thedboydguy thedboydguy - 1 year ago 165
Python Question

How can I access the elements of a foreign set for a model in Django's get_context_data method?

I have a generic

in Django 1.9.7, which uses my model
to show a super-time-saving no-hassle view (thank you Django). However, I'm struggling to access a related foreign key set on my
object (a set of
objects). My model is as follows:

class QuizQuestion(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
question_index = models.IntegerField()
user_answer_text = models.CharField(max_length=1000)
date_answered = models.DateTimeField(null=True)
user_is_correct = models.NullBooleanField()

def __str__(self):
return self.user_answer_text

Here's my view:

class QuizDetail(generic.DetailView):
model = Quiz

def get_context_data(self, **kwargs):
context = super(QuizDetail, self).get_context_data(**kwargs)

# Pass/fail chart
passed_questions = self.model.quizquestion_set.objects.filter(user_is_correct=True)

# ...

return context

This gives me 'ReverseManyToOneDescriptor' object has no attribute 'objects'.

I'm not sure if trying to get the related objects using the
is preferable to scooting around the long way and asking for
, but I'm operating on the basis that it is. Please correct me if I'm mistaken :)

gives: ''ReverseManyToOneDescriptor' object has no attribute 'filter''

passed_questions = self.model.quizquestion_set.all()
gives 'ReverseManyToOneDescriptor' object has no attribute 'all'

P.S. I find it quite obvious that I am relatively new to Django - apologies for any silly mistakes.

Answer Source

You are referring to the model, you need to refer to the instance (the object for which the view is showing the details) as relations are for instances and not models. You can get the instance with self.get_object():

def get_context_data(self, **kwargs):
    context = super(QuizDetail, self).get_context_data(**kwargs)
    obj = self.get_object()
    passed_questions = obj.quizquestion_set.filter(...)
    return context