Цикл 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.

Вернуться на верх