Reputation: 25
I'm new in python and Django also I was searching for answer but can't find it :( I have 3 classes in my app. First one class in my app is Exam, Question, Answer.
models.py
class Egzam(models.Model):
name = models.CharField(max_length=200, default='kolokwium ')
date = models.DateField('date publish')
code = models.CharField(max_length=200)
def __str__(self):
return str("%s %s" % (self.date, self.name))
class Question(models.Model):
egzam = models.ForeignKey(Egzam, on_delete=models.CASCADE)
name = models.CharField(max_length=200) # nazwa pytania
def __str__(self):
return self.name
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer_text = models.CharField(max_length=200) #treść odpowiedzi
correct = models.BooleanField(default=False)
def __str__(self):
return self.answer_text
So Egzam class can handle few Question and Question class can handle few Answers. What I want to do is list all exam's on index page and after I clicked on one of them, my app should open new page where I see all Question and Answers to this specific Exam. And I don't know how to return all Question and Answer's from specific Exam to one html. Here is rest of my code.
urls.py
app_name = 'kolos'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.EgzamView.as_view(), name='view'),
]
views.py
class IndexView(generic.ListView):
template_name = 'kolos/index.html'
context_object_name = 'egzam_list'
def get_queryset(self):
return Egzam.objects.all()
class EgzamView(generic.DetailView):
model = Egzam
template_name = 'kolos/egzam.html'
def get_queryset(self):
return Answer.obects.filter()
Upvotes: 2
Views: 2461
Reputation: 52028
You can try like this:
in template kolos/egzam.html
{% for question in object.question_set.all %}
{{ question.name }}
{% for answer in question.answer_set.all %}
{{ answer.answer_text }}
{{ answer.correct }}
{% endfor %}
{% endfor %}
And remove get_queryset
method from EgzamView
.
Please see the Many to one query section regarding how reverse query works(with _set
).
Upvotes: 2
Reputation: 5049
Although there is nothing wrong with ruddra's answer I would suggest a similar approach. I would set the related_name
on the foreign key relations. I find it useful and cleaner if I plan to often access bidiractional relationships. Like this:
class Question(models.Model):
egzam = models.ForeignKey(Egzam, on_delete=models.CASCADE, related_name='questions')
name = models.CharField(max_length=200) # nazwa pytania
def __str__(self):
return self.name
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='answers')
answer_text = models.CharField(max_length=200) #treść odpowiedzi
correct = models.BooleanField(default=False)
This way you can access the questions using the Egzam
like this:
{% for question in object.questions.all %}
{{ question.name }}
{% for answer in question.answers.all %}
{{ answer.answer_text }}
{{ answer.correct }}
{% endfor %}
{% endfor %}
Also, not going into to much reasons, currently it is preferable to use .format()
instead of %
for strings. Like this
def __str__(self):
return str("{} {}".format(self.date, self.name))
Upvotes: 1