Попытка создать общий HTML-шаблон, который отображает набор вопросов в заголовках тем на основе контекста из views.py

У меня есть несколько областей, т.е. Лидерство, Операции и т.д., каждая из которых имеет набор тем и вопросов, связанных с ней. Например, "Лидерство" состоит из 3 тем, каждая из которых имеет свой набор и количество вопросов.

Я пытаюсь создать общий шаблон questions.html, в котором views.py может соответствовать конкретной области, темам, вопросам и т.д. для этой области. Я предоставляю темы, отдельные наборы вопросов для каждой темы через контекст при рендеринге страницы для этой области.

Я пытаюсь избежать жесткого кодирования каждой страницы, перебирая каждую тему и используя набор вопросов для этой темы.

Я протестировал код, жестко закодировав 1 набор вопросов и посмотрев, правильно ли отображается таблица, и это так, за исключением того, что вопросы повторяются в каждой теме.

Однако когда я задаю во внешнем цикле перебор тем с каждым уникальным вопросом, заданным с помощью переменных, ни один из вопросов не появляется. Страница просто отображает темы без ошибок.

Вот фрагмент кода, который работает, но повторно использует вопросы:

  <tbody>
{% for m in categories %}
    <td colspan="7">{{ m }}</td>
    
        {% for key, value in questions1.items %}
        <tr>
            <td class="question">{{ value }} </td>
                {% for n in nchoices %}
                    {% if n == 0 %} 
                    <td>
                    
                        <input name={{ key }} type="radio" value={{ n }}  id="{{ key }}_{{n}}"/> Not Sure
                
                    </td>
                    {% else %}
                    <td>
                    
                    <input name={{ key }} type="radio" value={{ n }}  id="{{ key }}_{{n}}"/>{{ n }}
            
                    </td>
                    {% endif%}
                {% endfor %}
        </tr>
        {% endfor %}
{% endfor %}
</table>

<h4>Enter any comments about your responses to the questions</h4>
<textarea name="{{ textname }}"></textarea>

<input type="submit">

фрагмент файлаviews.py (отредактирован для удаления несущественного кода):

def test(request):
        questions1 = {"L_Q1": "Conducts annual risk assessments and identifies key risks and mitigation actions"}
        
        questions2 =  {"L_Q4":"Provides the necessary resources for accomplishing business continuity objectives"}
        
        questions3 =  {"L_Q8": "Conduct annual test of business continuity plans"}
        
        nchoices = [0,1,2,3,4,5]

        categories = ["Risk Assessment and Planning", "Oversight", "Execution and Improvement"]
        
        questions = ["questions1","questions2","questions3"]

        textname= ["L_Text"]
        
        context = {
            "questions": questions,
            "questions1": questions1,
            "questions2": questions2,
            "questions3": questions3,
            "categories": categories,
            "nchoices": nchoices,
            "textname": textname
        }

        if request.method == "POST":
            return render(request, "leadershipresults.html", context)
        else:

            return render(request, "questions.html", context)

Я пробовал добавлять циклы внутри внешнего цикла для выбора каждого набора вопросов, но в этом случае вопросы не отображаются, например:

{% for m in categories %}
    <td colspan="7">{{ m }}</td>
    {% for x in questions %}
            {% for key, value in x.items %}
            <tr>
                <td class="question">{{ value }} </td>
                    {% for n in nchoices %}
                        {% if n == 0 %} 
                        <td>
                        
                            <input name={{ key }} type="radio" value={{ n }}  id="{{ key }}_{{n}}"/> Not Sure
                    
                        </td>
                        {% else %}
                        <td>
                        
                        <input name={{ key }} type="radio" value={{ n }}  id="{{ key }}_{{n}}"/>{{ n }}
                
                        </td>
                        {% endif%}
                    {% endfor %}
            </tr>
            {% endfor %}
        {% endfor %}
{% endfor %}

Возможно ли использовать переменную для определения того, какой список использовать для выбора правильного набора вопросов?

Я переименовал модели django, чтобы следовать руководствам PEP. Смотрите здесь

# type: ignore
from django.db import models


class Topic(models.Model):
    name = models.CharField(max_length=20)
   

    def __str__(self):
        return f"{self.name}"


class Question(models.Model):
    question = models.CharField(max_length=200)
    name = models.CharField(max_length=20)  # THis is probably useless

    topic = models.ForeignKey(
        Topic, on_delete=models.CASCADE
    )  # Django will store this as topic_id on database

    def __str__(self):
        return f"{self.name} is question {self.question}"


class Answer(models.Model):
    value = models.IntegerField()
    name = models.CharField(max_length=20)
    # q_id = models.CharField(max_length=10, default="XX")  # USed foreignkey instead
    question = models.ForeignKey(Question, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.question} value is {self.value}"


class Comment(models.Model):
    name = models.CharField(max_length=20)
    comments = models.CharField(max_length=1000, default="No comment")
    question = models.ForeignKey(
        Question, on_delete=models.CASCADE
    )  # Use One to one if a question has one answer

    def __str__(self):
        return f"{self.name} comments are {self.comments}"

Простой способ получить Questions и соответствующие темы -

questions = Question.objects.select_related('topic').all()
#Then create a dict
from collections import defaultdict
questions_by_topic = defaultdict(list)#If not topic in dict then it will create it with empty list as value
for question in questions:
    questions_by_topic[question.topic].append(question.question)

#You can then use the dict in html as so
for topic, questions in questions_by_topic.items():
    print(f"Topic: {topic.name}")
    for question in questions:
        print(f" - {question}")
Вернуться на верх