user298519
user298519

Reputation: 1190

Django: Trouble with named URLs instead of ids

So I'm making a study app that involves flash cards. A user can make subjects and put decks containing cards in them. So for example, in the Biology subject, there would be a Deck called "unit one" and in that deck would be full of cards. The URL for a deck would ideally look like

localhost:8000/subjects/Biology/unit-one/

Here is my code

views.py

class IndexView(generic.ListView):
  template_name = 'card/index.html'
  context_object_name = 'subjects'

  def get_queryset(self):
      return Subject.objects.all()

class SubjectView(DetailView):
  model = Subject
  slug_field = "subject"
  template_name = 'card/subject.html'

class DeckView(DetailView):
  model = Deck
  template_name = 'card/deck.html'

  def get_object(self, subjects, deck):
      subject_obj = Subject.objects.filter(subject_name=subjects).first()
      obj = Deck.objects.filter(subject=subject_obj, deck_name=deck).first()
      return obj

  def get(self, request, subjects, deck):
      self.object = self.get_object(subjects, deck)
      context = self.get_context_data(object=self.object)
      return self.render_to_response(context)

models.py

class Subject(models.Model):
  subject_name = models.CharField(max_length=100)
  description = models.TextField()

  def __str__(self):
      return self.subject_name

  def get_absolute_url(self):
      return reverse('card:index')

class Deck(models.Model):
  deck_name = models.CharField(max_length=100)
  subject = models.ForeignKey(Subject, on_delete=models.CASCADE)

  def __str__(self):
      return self.deck_name

class Card(models.Model):
  term = models.CharField(max_length=100)
  definition = models.TextField()
  deck = models.ForeignKey(Deck, on_delete=models.CASCADE)

  def __str__(self):
      return self.term

urls.py

url(r'^subjects/(?P<subject>[\w ]+)/$', views.SubjectView.as_view(), name='subject'),
url(r'^subjects/(?P<subject>[\w ]+)/(?P<deck>[\w ]+)/$', views.DeckView.as_view(), name='deck'),

index.html

<li><a href="{% url 'card:subject' subject.subject_name %}">

subject.html

<ul>
  {% for deck in subject.deck_set.all %}
  <li><a href="{% url 'card:deck' deck.deck_name %}">{{deck.deck_name}}</a></li>
  {% endfor %}
</ul>

However, I am getting this error.

Generic detail view SubjectView must be called with either an object pk or a slug.

The index page is showing properly, but when I click on a subject, I get that error. How do I fix this?

Upvotes: 1

Views: 38

Answers (2)

itzMEonTV
itzMEonTV

Reputation: 20339

Just an assumption. Try by change Char to Slug

class Subject(models.Model):
  subject_name = models.SlugField(max_length=100)
  description = models.TextField()

Also

slug_field = "subject_name"

Upvotes: 1

pnovotnak
pnovotnak

Reputation: 4581

Have you tried setting SubjectView.slug_url_kwarg?

Upvotes: 0

Related Questions