Search code examples
djangofilterprimary-keydetailview

How to reference pk in DetailView


Hi i'm sure this had a simple solution but i cant find it! It must be required ALL the time!

To learn django i am writing simple app for me to log my learning points. So i have two models:

class Topic(models.Model):
    title = models.CharField(max_length=40)

    def __unicode__(self):
        return self.title

    class Meta():
        ordering = ['title']


class Fact(models.Model):
    note = models.CharField(max_length=255)
    topic = models.ForeignKey('Topic')

    def __unicode__(self):
        return self.note

    class Meta():
        ordering = ['note']

I have template and url that will list ALL the topics.

When i see that list i want to be able to click on it [which i can do] and have that topic and all the facts linked to it (thourgh the foreign key appear) [would that technicaly be described as filtered query set of child objects?] I am using detailview.

url

 url(r'^(?P<pk>\d+)/$', TopicDetailView.as_view(), name='facts'),

Here is the code of the detail view. Know i knows it knows the pk as it shows the right page when i take out the extracontext filter (and just take .all()). But i cant ref it no matter how many ways i try. I'd like something like this...

class TopicDetailView(DetailView):
    model = Topic
    template_name = 'study/topic_facts.html'

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(TopicDetailView, self).get_context_data(**kwargs)
        # Add in a QuerySet of all the books

        context['fact_list'] = Fact.objects.filter(topic='pk')
        return context

I can do this if i put some logic and a filter in the template but that doesn't seem very proper to me and i feel i must be able to do this easily by adding the right extra context.

Help some poor newbie out! Many Thanks.


Solution

  • 'pk' is just a string. You mean self.kwargs['pk'].

    But actually you don't want to do this at all. The super class already adds the Topic object to the context: and you have a relationship between Topic and Fact. You can traverse this relationship in the template:

    {% for fact in topic.fact_set.all %}
        ...
    {% endfor %}
    

    so you don't need to override get_context_data.