Цикл For в шаблоне Django
Я работаю над проектом Django. В нем есть два приложения, одно для объяснения темы, которое имеет свою собственную модель и представления, а второе приложение - это викторина, которая имеет свою собственную модель и представление, которое будет проверять способности / обучение студентов по каждой теме.
Основная идея заключается в том, что по каждой теме каждой книги будет проведен тест для проверки способностей учащихся.
Моя модель объяснения книги выглядит следующим образом:
class book_explination(models.Model):
title = models.CharField (max_length = 255)
slug = models.SlugField(max_length= 250, null = True, blank = True, unique= True)
lesson_no = models.CharField (max_length = 255)
book_text = models.TextField (blank=False, null=False)
book_text_explination = models.TextField (blank=False, null=False)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE, null= True, blank=True)
timestamp = models.DateField(auto_now=False, auto_now_add=True)
def __str__(self):
return self.title
Мое представление для модели курса следующее:
def maths_topics(request):
content_list = book_explination.objects.filter(title = "maths")
return render(request, 'blog/maths_topics.html', {'content_list': content_list})
Мой url в файле url.py выглядит следующим образом:
path('nahwa_meer_topics/', maths_topics, name = 'maths_topics'),
Моя модель викторины выглядит следующим образом:
class Quiz(models.Model):
title = models.CharField(max_length=255)
book_name = models.CharField(max_length=255)
slug = models.SlugField(blank = True)
topic = models.CharField(max_length=255)
number_of_questions = models.IntegerField()
class Meta:
verbose_name_plural = 'Quizes'
def __str__(self):
return self.title
Мое мнение о приложении для викторины следующее:
def maths_quiz(request):
maths_quiz = Quiz.objects.filter(book__name = "maths")
return render(request, 'blog/maths_topics.html', {'maths_quiz': maths_quiz})
Мой HTML шаблон django выглядит следующим образом:
{% for c in content_list %}
<ul class="list-group list-group-horizontal">
{% if c.title == "maths" %}
<li> <a href= "{{ c.slug }}" class="list-group-item"> {{ c.title }}</a></li>
<li> <a href= "{{ c.slug }}" class="list-group-item"> {{ c.lesson_no }}</a></li>
<li> <a href= "{{ c.slug }}" class="list-group-item"> {{ c.book_text }}</a></li>
{% endif %}
</ul>
{%endfor%}
{% for c in maths_quiz %}
<ul class="list-group list-group-horizontal">
{% if c.name == "maths" %}
<li> <a href= "{{ c.slug }}" class="list-group-item"> {{ c.topic }}</a></li>
<li> <a href= "{{ c.slug }}" class="list-group-item"> {{ c.title }}</a></li>
{% endif %}
</ul>
{% endfor %}
Шаблон HTML отражает объяснение учебника математики, но не показывает часть данных викторины.
Моя цель - показать темы книги на html странице, и перед каждой темой должен быть тест, связанный с этой темой, учитывая, что каждая тема будет иметь свой отдельный тест.
Спасибо за вашу поддержку и помощь. С нетерпением жду положительного ответа с вашей стороны.
Приветствует
Если я правильно понимаю, переменная maths_quiz
содержит кверисет экземпляров Quiz
. В логике вашего шаблона вы отображаете элемент списка, если атрибут name
экземпляра равен "maths"
. Однако в вашей модели Quiz
вообще нет поля name
. Может быть, вы хотели проверить атрибут book_name
вместо этого?
{% for c in maths_quiz %}
<ul class="list-group list-group-horizontal">
{% if c.book_name == "maths" %}
...
{% endif %}
</ul>
{% endfor %}
Кроме того, я думаю, что вы допустили ошибку в своем запросе, начав с:
...
maths_quiz = Quiz.objects.filter(book__name = "maths")
В book__name
есть два подчеркивания, но в вашем поле только одно:
class Quiz(models.Model):
...
book_name = models.CharField(max_length=255)
Более того, я только что заметил, что все ваше условие if
в шаблоне кажется излишним, поскольку вы выполняете именно такую фильтрацию в запросе в функции представления перед передачей результатов в шаблон. Поэтому нет необходимости проверять book_name
снова в шаблоне. Каждый экземпляр в этом наборе запросов будет иметь book_name == "maths"
.
То же самое относится и к представлению maths_topics
.
Наконец, я предполагаю, что либо HTML на самом деле представляет собой два отдельных шаблона, либо, если нет, то вы знаете, что только один из двух разделов будет отображаться в зависимости от вызываемого представления, maths_topics
или maths_quiz
, а не оба.
В качестве побочного замечания: я бы предложил использовать более описательные имена переменных, если это возможно. Поскольку вы работаете с несколькими экземплярами Quiz
, я бы назвал переменную как maths_quizzes
, а для итерации использовал бы имя quiz
вместо c
:
def maths_quiz(request):
maths_quizzes = Quiz.objects.filter(book__name = "maths")
return render(request, 'blog/maths_topics.html', {'maths_quizzes': maths_quizzes})
{% for quiz in maths_quizzes %}
...
{% endfor %}
EDIT
OK, теперь, когда вы объяснили немного больше, кажется, что вы do думаете, что оба кверисета должны как-то отображаться. У вас есть два отдельных представления. Они отображают отдельные ответы. Если вы хотите, чтобы оба кверисета передавались в данные вашего шаблона, то вы должны сделать это в одном представлении:
def maths_view(request):
content_list = book_explination.objects.filter(title = "maths")
maths_quiz = Quiz.objects.filter(book_name = "maths")
return render(
request,
'blog/maths_topics.html',
{'content_list': content_list, 'maths_quiz': maths_quiz}
)
Тогда, очевидно, вам нужно настроить URL-маршрут так, чтобы он указывал на это представление, что-то вроде этого (например):
path('yoururlpath/', maths_view, name = 'maths_view')
Кроме того, мне кажется, что если две ваши модели так тесно связаны, то вам стоит подумать о создании неких отношений между ними. А именно, если тест всегда связан ровно с одной книгой, это, по-видимому, требует отношения внешнего ключа от теста к книге.
Я имею в виду что-то вроде этого:
class Quiz(models.Model):
book = ForeignKey(to=book_explination, ...)
...
Это позволит вам получить все связанные объекты в одном запросе.
Вы можете прочитать об отношениях в документации Django.