如何在 Django ModelForm 中显示 CHOICES
How to display CHOICES in Django ModelForm
- 我有一个包含 16 个类别的 policy_category 模型。
- 我有一个 Response 模型来记录调查答案。该模型包括一个字段,用于记录受访者对每个政策类别的 1-5 评级。 (policy_1_rank..policy_16_rank, 等等)
我不知道如何显示我为每个字段创建的 CHOICES:
Form Template
<div><b>How important are each of the following issues or policy areas to you, when you're selecting a candidate for president?</b></div>
<div><br></div>
<ul><div>{{ policy_category.object(pk=1) }}</div></ul>
# show POLICY_1_CHOICES below:
<div>{{ form.policy_1_rank }}</div>
<div><br></div>
<ul><div>{{ policy_category.object(pk=2) }}</div></ul>
# show POLICY_2_CHOICES below:
<div>{{ form.policy_2_rank }}</div>
...
Responses Model:
# Temp Survey Response
class Temporaryresponse(models.Model):
# Healthcare
POLICY_1_CHOICES = [
(1, '1: Extremely supportive of a healthcare system with ONLY private insurance'),
(2, '2: Somewhat supportive of a healthcare system with ONLY private insurance'),
(3, '3: Somewhat supportive of a healthcare system with BOTH private insurance and a public insurance option'),
(4, '4: Extremely supportive of a healthcare system with BOTH private insurance and a public insurance option'),
(5, '5: Somewhat supportive of a healthcare system with ONLY public insurance (commonly referred to as "universal healthcare")'),
(6, '6: Extremely supportive of a healthcare system with ONLY public insurance (commonly referred to as "universal healthcare")'),
]
...
# Healthcare
policy_1_rank = models.IntegerField(blank=True, default=0, choices=POLICY_1_CHOICES)
Forms.py
class NextresponseForm(ModelForm):
policy_1_rank = forms.IntegerField()
policy_2_rank = forms.IntegerField()
...
class Meta:
model = Temporaryresponse
fields = ['policy_1_rank', 'policy_2_rank',...]
编辑:也许下面的答案不起作用,因为我的观点有问题。我正在尝试从第一个表单页面 "tr.html" 导航,保存数据,然后将响应的 pk 发送到 "nr.html" 以进行调查的第二部分。这是工作。但是我对"nr.html"的看法不正确吗?
views.py
# Create temporary response view - this saves and goes to nr perfectly. pk produced from saving the response shows in nr link in web browser (myapp/nr/pk# shows here perfectly.)
def tr(request):
if request.method == "POST":
form = TemporaryresponseForm(request.POST)
if form.is_valid():
tempresponse = form.save()
tempresponse.save()
return redirect('nr', pk=tempresponse.pk)
else:
form = TemporaryresponseForm()
return render(request, 'politicalexperimentpollapp/tr.html', {'form': form})
def nr(request, pk):
tempresponse = get_object_or_404(Temporaryresponse, pk=pk)
instance = Temporaryresponse.objects.get(pk=pk)
if request.method == "POST":
form = NextresponseForm(request.POST, instance=instance)
if form.is_valid():
nextresponse = form.save()
nextresponse.save()
return redirect('fr', pk=nextresponse.pk)
else:
form = NextresponseForm(instance=instance)
return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse}, {'form': form})
您可以覆盖 __init__
中的表单字段以包含 forms.ChoiceField
:
class NextresponseForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['policy_1_rank'] = forms.ChoiceField(
choices=self._meta.model.POLICY_1_CHOICES)
class Meta:
model = Temporaryresponse
fields = ['policy_1_rank', 'policy_2_rank',...]
更新
在 Django 中呈现表单对象的最简单方法是将其作为视图中的上下文传递:
def some_view(request):
form = NextresponseForm(request.POST or None)
context = {'form':form}
return render(request, 'some_template.html', context)
然后您可以通过在模板中调用 form.as_ul
来访问表单:
<ul>
{{ form.as_ul }}
</ul>
更新 2
您观点中的最后一行不正确:
return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse}, {'form': form})
这应该是:
return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse, 'form': form})
context
是一个 字典 。如果需要将多个项目传递给模板,则需要在上下文字典中包含多个键,而不是多个参数。
最后,我建议 始终 使用 request.POST or None
初始化表单,以避免使您的表单无效:
form = TemporaryresponseForm(request.POST or None)
这是对一个常见问题的教科书式回答 "Why is form.is_valid()
always invalid?".
- 我有一个包含 16 个类别的 policy_category 模型。
- 我有一个 Response 模型来记录调查答案。该模型包括一个字段,用于记录受访者对每个政策类别的 1-5 评级。 (policy_1_rank..policy_16_rank, 等等)
我不知道如何显示我为每个字段创建的 CHOICES:
Form Template
<div><b>How important are each of the following issues or policy areas to you, when you're selecting a candidate for president?</b></div>
<div><br></div>
<ul><div>{{ policy_category.object(pk=1) }}</div></ul>
# show POLICY_1_CHOICES below:
<div>{{ form.policy_1_rank }}</div>
<div><br></div>
<ul><div>{{ policy_category.object(pk=2) }}</div></ul>
# show POLICY_2_CHOICES below:
<div>{{ form.policy_2_rank }}</div>
...
Responses Model:
# Temp Survey Response
class Temporaryresponse(models.Model):
# Healthcare
POLICY_1_CHOICES = [
(1, '1: Extremely supportive of a healthcare system with ONLY private insurance'),
(2, '2: Somewhat supportive of a healthcare system with ONLY private insurance'),
(3, '3: Somewhat supportive of a healthcare system with BOTH private insurance and a public insurance option'),
(4, '4: Extremely supportive of a healthcare system with BOTH private insurance and a public insurance option'),
(5, '5: Somewhat supportive of a healthcare system with ONLY public insurance (commonly referred to as "universal healthcare")'),
(6, '6: Extremely supportive of a healthcare system with ONLY public insurance (commonly referred to as "universal healthcare")'),
]
...
# Healthcare
policy_1_rank = models.IntegerField(blank=True, default=0, choices=POLICY_1_CHOICES)
Forms.py
class NextresponseForm(ModelForm):
policy_1_rank = forms.IntegerField()
policy_2_rank = forms.IntegerField()
...
class Meta:
model = Temporaryresponse
fields = ['policy_1_rank', 'policy_2_rank',...]
编辑:也许下面的答案不起作用,因为我的观点有问题。我正在尝试从第一个表单页面 "tr.html" 导航,保存数据,然后将响应的 pk 发送到 "nr.html" 以进行调查的第二部分。这是工作。但是我对"nr.html"的看法不正确吗?
views.py
# Create temporary response view - this saves and goes to nr perfectly. pk produced from saving the response shows in nr link in web browser (myapp/nr/pk# shows here perfectly.)
def tr(request):
if request.method == "POST":
form = TemporaryresponseForm(request.POST)
if form.is_valid():
tempresponse = form.save()
tempresponse.save()
return redirect('nr', pk=tempresponse.pk)
else:
form = TemporaryresponseForm()
return render(request, 'politicalexperimentpollapp/tr.html', {'form': form})
def nr(request, pk):
tempresponse = get_object_or_404(Temporaryresponse, pk=pk)
instance = Temporaryresponse.objects.get(pk=pk)
if request.method == "POST":
form = NextresponseForm(request.POST, instance=instance)
if form.is_valid():
nextresponse = form.save()
nextresponse.save()
return redirect('fr', pk=nextresponse.pk)
else:
form = NextresponseForm(instance=instance)
return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse}, {'form': form})
您可以覆盖 __init__
中的表单字段以包含 forms.ChoiceField
:
class NextresponseForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['policy_1_rank'] = forms.ChoiceField(
choices=self._meta.model.POLICY_1_CHOICES)
class Meta:
model = Temporaryresponse
fields = ['policy_1_rank', 'policy_2_rank',...]
更新
在 Django 中呈现表单对象的最简单方法是将其作为视图中的上下文传递:
def some_view(request):
form = NextresponseForm(request.POST or None)
context = {'form':form}
return render(request, 'some_template.html', context)
然后您可以通过在模板中调用 form.as_ul
来访问表单:
<ul>
{{ form.as_ul }}
</ul>
更新 2
您观点中的最后一行不正确:
return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse}, {'form': form})
这应该是:
return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse, 'form': form})
context
是一个 字典 。如果需要将多个项目传递给模板,则需要在上下文字典中包含多个键,而不是多个参数。
最后,我建议 始终 使用 request.POST or None
初始化表单,以避免使您的表单无效:
form = TemporaryresponseForm(request.POST or None)
这是对一个常见问题的教科书式回答 "Why is form.is_valid()
always invalid?".