【问题标题】:Show objects properly as choices in django forms choicefield将对象正确显示为 django 表单中的选项
【发布时间】:2015-12-19 18:47:10
【问题描述】:

我正在开发某种测试应用程序。我有两个模型用于测试和用户回答:

class TestModel(AbstractDatetimeModel):
    number = models.IntegerField(unique=True)
    answer_1 = models.CharField(max_length=255)
    answer_2 = models.CharField(max_length=255)

class AnswerModel(AbstractDatetimeModel):
    ANSWERS = (
        ('1', 'A'),
        ('2', 'B')
    )
    candidate = models.ForeignKey(User)
    question = models.ForeignKey(TestModel)
    answer = models.CharField(max_length=1, choices=ANSWERS)

我有一个表格,候选人(用户)可以在其中回答每个问题。为了实现这一点,我使用了一个视图 formset_factory:

def communicative_test(request):
    questions = TestModel.objects.all()
    question_formset = formset_factory(form=TestForm, extra=questions.count())
    question_formset = question_formset(initial=[{'candidate': request.user, 'question': x.number,
                                                  'answer_1': x.answer_1, 'answer_2': x.answer_2} for x in questions])
    return render(request, 'testing/communicative.html', locals())

在我需要显示 ChoiceField 的表单上,选择应该是来自字段 answer_1 和 answer_2 的数据。这是这个表格:

class TestForm(forms.ModelForm):
    answer_1 = forms.CharField()
    answer_2 = forms.CharField()
    VARIANTS = (
        ('answer_1', answer_1),
        ('answer_2', answer_2)
    )
    variants = forms.ChoiceField(choices=VARIANTS, widget=forms.RadioSelect())

    class Meta:
        model = TestAnswer
        fields = '__all__'

问题是这些答案在页面上显示为带有以下标签的单选按钮:

<django.forms.fields.CharField object at 0x7f36248ef5d0>
<django.forms.fields.CharField object at 0x7f36248ef650>

我需要正确显示它。

【问题讨论】:

  • 您在此处尝试执行的操作 ('answer_1', answer_1) 无法正常工作。为什么表格中有answer_1answer_2?它们看起来像多项选择题,所以您不只是想收集用户的选择(例如 A/B/C/D)而不是描述性答案值吗?你需要更清楚地思考你要做什么
  • 没有多项选择,因为它们在 ChoiceField 中用作选择。我同意你的观点,用 A 或 B 显示 ChoiceFiled 会容易得多。但对于用户来说,这还不够。用户需要查看每个变体的文本。这些文本来自 TestModels answer_1 和 answer_2 字段。
  • 您混淆了向用户显示的内容(答案文本)和应提交给表单的值(例如 A/B/C/D 或仅 0/1/2/3 )
  • 不,我没有混淆。我只需要表明,我在问题和描述中解释过。提交表格是另一回事。但首先,我需要解决当前的问题。
  • 我的意思是,你试图通过尝试做一些不正确的事情来解决你为自己制造的问题

标签: django django-forms formset choicefield


【解决方案1】:

嗯,正如@Anentropic 所提到的,我没有走对路。 他是对的,因为我只需要提交答案 A 或 B。但是对于表单上的用户,我需要显示来自测试模型的这些答案的文本。所以我为此写了两个模板标签。 类TestForm(forms.ModelForm):

    class Meta:
        model = TestAnswer
        fields = '__all__'

def communicative_test(request):
    questions = TestModel.objects.all()
    QuestionFormSet = formset_factory(form=TestForm, max_num=questions.count())
    formset = QuestionFormSet(initial=[{'candidate': request.user, 'question': x.number} for x in questions])
    return render(request, 'testing/communicative.html', locals())

每个答案有两个自定义模板标签 (A/B):

@register.filter(name='get_answer1')
def get_answer1(question):
    try:
        question = TestModel.objects.get(number=question)
        answer = question.answer_1
    except ObjectDoesNotExist:
        answer = ''
    return answer


@register.filter(name='get_answer2')
def get_answer2(question):
    try:
        question = TestModel.objects.get(number=question)
        answer = question.answer_2
    except ObjectDoesNotExist:
        answer = ''
    return answer

模板是:

{% load test_tags %}
<form id="communicative-test-form" method="post">
     {% csrf_token %}
     {{ question_formset.management_form }}
     {% for form in question_formset.forms %}
        {% crispy form %}
        {{ form.id }}
        <p>{{ form.question.value }}</p>
        <p><label>
           <input type=radio name="form-{{ form.question.value|add:"-1" }}-answer" id='id_form-{{ form.question.value|add:"-1" }}-answer' value="1">
                        {{ form.question.value|get_answer1 }}
           </label></p>
           <p><label>
              <input type=radio name="form-{{ form.question.value|add:"-1" }}-answer" id='id_form-{{ form.question.value|add:"-1" }}-answer' value="2">
                        {{ form.question.value|get_answer2 }}
              </label></p>
      {% endfor %}
      <div style="text-align: right;" class="col-md-12">
          <button type="submit">Save</button>
      </div>
</form>

【讨论】:

  • 如果它解决了您的问题,您应该接受您的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 2014-08-24
  • 2020-07-09
  • 2016-01-28
  • 2011-01-11
  • 2018-08-03
  • 2015-05-25
相关资源
最近更新 更多