首页 > 解决方案 > Django ModelFormset:使用两种独立的模型,一种用于呈现调查问题,一种用于保存回复

问题描述

我是 Django 的新手,并且被卡住了。我正在使用两种模型创建调查:一种用于描述调查问题,另一种用于存储响应(由 QUESTION_ANSWER_CHOICES 定义的答案选择,或文本字段):

class PassengerRequirement (models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ...
    question_number = models.CharField(max_length=12, default=0, unique=False)
    is_yes_no_question = models.BooleanField(default=False, verbose_name='Is this a Yes/No Question?')
    question_text = models.TextField(max_length=256, null=True, blank=True, help_text="Put the question in this field.")
    ...

class PassengerRequirementMeasurement (models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    survey_question = models.ForeignKey('PassengerRequirement',
                                        related_name='passenger_requirement_answer',
                                        on_delete=models.CASCADE)

    survey_instance = models.ForeignKey('SurveyInstance',
                                        related_name='passenger_requirement_measurements',
                                        on_delete=models.CASCADE,
                                        null=True)

    answer_choice = models.CharField(max_length=1,
                                       choices=QUESTION_ANSWER_CHOICES,
                                       default=YES)

    answer_text = models.TextField(max_length=256,
                                   null=True,
                                   blank=True,
                                   help_text="Add Details")

然后在forms.py中使用modelformset_factory一个formset:

prFormSet = modelformset_factory(PassengerRequirementMeasurement,
                                 fields=('answer_choice', 'answer_text'),
                                 extra=0
                                 )

而我的观点:

def passenger_requirements_pretravel(request):

    surveyquestions = PassengerRequirement.objects.filter(...)

    if request.method == 'POST':
        formset = prFormSet(queryset=PassengerRequirement.objects.filter(...),
                        data=request.POST)

        if formset.is_valid():
            print('no problem')
        else:
            print(formset.errors)

        ...

    else:
        formset = prFormSet(queryset=PassengerRequirement.objects.filter(...)
        return render(request, 'surveys/passenger_requirements_pretravel.html',
            {'formset': formset, 'surveyquestions': surveyquestions})

我正在遍历调查问题和表单集以显示问题和表单字段:

            <form action="{% url 'pr_pretravel' %}" method="post" class="mt-5">
                {% csrf_token %}
                {{ formset.management_form }}

                {% for question in surveyquestions %}
                    {% with cntr=forloop.counter0 %}
                    <div class="q_{{ question.question_number|length }} form-group">
                    <h5 class="font-weight-bold">{{ question.question_number }}:  {{ question.question_text }}</h5>
                        {% if question.is_yes_no_question == True %}
                            {% for form in formset %}
                                {% if cntr == forloop.counter0 %}
                                    {{ form.answer_choice }}
                                {% endif %}
                            {% endfor %}
                        {% else %}
                            {% for form in formset %}
                                {% if cntr == forloop.counter0 %}
                                    {{ form.answer_text }}
                                {% endif %}
                            {% endfor %}
                        {% endif %}
                    </div>
                    {% endwith %}
                {% endfor %}

                <input type="submit" value="Submit"/>
            </form>

我知道这很尴尬,但我能弄清楚如何同时使用表单集和调查问题的唯一方法。

问题是,我无法通过 is_valid() 方法;它总是返回一个列表:

[{'id': ['This field is required.']}, {'answer_choice': ['This field is required.'],...

对于列表中的每个问题。

我尝试了一种仿照这个问题的方法,但仍然得到类似的结果:

<ul class="errorlist"><li>answer_choice<ul class="errorlist"><li>This field is required.</li></ul></li></ul>

有什么建议么?谢谢!

标签: django

解决方案


推荐阅读