thedboydguy thedboydguy - 5 months ago 77
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

DetailView
in Django 1.9.7, which uses my model
Quiz
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
Quiz
object (a set of
QuizQuestion
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
_set
is preferable to scooting around the long way and asking for
QuizQuestion.objects.filter(...)
, but I'm operating on the basis that it is. Please correct me if I'm mistaken :)

self.model.quizquestion_set.filter(user_is_correct=True)
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

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