0

I'm making a study app that involves flashcards. It is divided into subjects. Each subject (biology, physics) has a set of decks (unitone, unittwo). Each deck has a set of cards (terms and definitions). I want my URLs to look like localhost:8000/biology/unitone/ but I have trouble putting two URL parameters in one URL.

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

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
    slug_field = "deck"
    template_name = 'card/deck.html'

urls.py

# localhost:8000/subjects/1 (biology)
url(r'^subjects/(?P<pk>[0-9]+)/$', views.SubjectView.as_view(), name='subject')


# localhost:8000/subjects/1/1 (biology/unitone)
url(r'^subjects/(?P<pk>[0-9]+)/(?P<pk>[0-9]+)/$', views.DeckView.as_view(), name='deck'),

The second URL in urls.py is what I'm having trouble with. It's not a valid URL.

3
  • What did you try, and which part didn't work as expected? Commented Sep 13, 2016 at 14:50
  • Edited my post! Commented Sep 13, 2016 at 14:52
  • You define "pk" twice, that is probably the problem Commented Sep 13, 2016 at 15:00

2 Answers 2

2

You can't have multiple parameters with the same name. You have to give each parameter a unique name, e.g.:

url(r'^subjects/(?P<pk>[0-9]+)/(?P<deck>[0-9]+)/$', views.DeckView.as_view(), name='deck'),

In the DeckView you can then access them as self.kwargs['pk'] and self.kwargs['deck'].

Sign up to request clarification or add additional context in comments.

2 Comments

How would I access them in templates? deck.id isn't working
It should be url(r'^subjects/(?P<subject>[0-9]+)/(?P<pk>[0-9]+)/$', views.DeckView.as_view(), name='deck'), because DetailView gets the object by pk key, so when someone calls subjects/2/3 it would return object with pk 2 and not pk 3 as expected
1

there's a way by rewriting the DetailViews

urls.py

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

views.py

class DeckView(DetailView):
    model = Deck
    # slug_field = "deck" # you don't need it 
    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)

then access localhost:8000/subjects/biology/unitone/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.