在一个Django视图中合并两种形式 [英] Combining two forms in one Django view
问题描述
我正在努力为官方Django教程中制作的民意调查应用程序添加更多功能。我正在做的一件事是使登录的用户可以创建民意测验/选择(而不是在管理屏幕中,该教程将留给我们)。
I am working on adding more functionality to the polls app that is made in the official Django tutorial. One of the things I am working on is making Polls/Choices creatable by logged in users (instead of in an admin screen, where the tutorial leaves us).
我是试图创建一个视图,用户可以在其中创建一个民意测验,然后还包括一些与该民意测验相关联的选择。 Django Admin自动执行此操作,我不确定如何在视图中写出来。
I am looking to create a view where a user can create the a Poll, and then as well include some Choices to associate to the Poll. The Django Admin automagically does it, and I am not sure how to go about writing this out in a view.
首先,这些是与我相关的文件:
To start with, these are my relevant files:
models.py
models.py
import datetime
from django.db import models
from django.utils import timezone
class Poll(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
class Choice(models.Model):
question = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __unicode__(self):
return self.choice_text
forms.py
from django import forms
from .models import Poll, Choice
from datetime import datetime
class PollForm(forms.ModelForm):
question_text = forms.CharField(max_length=200, help_text="Please enter the question.")
pub_date = forms.DateTimeField(widget=forms.HiddenInput(), initial = datetime.now())
class Meta:
model = Poll
fields = ("__all__")
class ChoiceForm(forms.ModelForm):
choice_text = forms.CharField(max_length=200, help_text="Please enter choices.")
votes = forms.IntegerField(widget=forms.HiddenInput(),initial=0)
exclude = ('poll',)
views.py
def add_poll(request):
# A HTTP POST?
if request.method == 'POST':
form = PollForm(request.POST)
# Have we been provided with a valid form?
if form.is_valid():
# Save the new category to the database.
form.save(commit=True)
# Now call the index() view.
# The user will be shown the homepage.
return render(request, 'polls/index.html', {})
else:
# The supplied form contained errors - just print them to the terminal.
print form.errors
else:
# If the request was not a POST, display the form to enter details.
form = PollForm()
# Bad form (or form details), no form supplied...
# Render the form with error messages (if any).
return render(request, 'polls/add_poll.html', {'form': form})
当前,我的视图允许用户添加投票。我只是不确定如何修改它,以将输入的文本作为Poll模型的question_text传递给Choice模型,然后传递给ChoiceForm。
Currently, my view allows me a user to add a poll. I am just not sure how to go about adapting it to pass the entered text as the Poll model's question_text, to the Choice model, and in turn, the ChoiceForm.
任何
干杯,
Paul
Cheers, Paul
推荐答案
表单集是在Django中实现此目的的方法。
Formsets are the way to do it in django.
首先为 Poll.pub_date
字段添加默认值
值:
class Poll(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published', default=timezone.now)
然后制作表格稍微简单一点:
Then make forms a bit simpler:
class PollForm(forms.ModelForm):
class Meta:
model = Poll
fields = ('question_text', )
class ChoiceForm(forms.ModelForm):
class Meta:
model = Choice
fields = ('choice_text',)
向您的视图添加表单集支持:
Add formset support to your view:
from django.forms.formsets import formset_factory
def add_poll(request):
ChoiceFormSet = formset_factory(ChoiceForm, extra=3,
min_num=2, validate_min=True)
if request.method == 'POST':
form = PollForm(request.POST)
formset = ChoiceFormSet(request.POST)
if all([form.is_valid(), formset.is_valid()]):
poll = form.save()
for inline_form in formset:
if inline_form.cleaned_data:
choice = inline_form.save(commit=False)
choice.question = poll
choice.save()
return render(request, 'polls/index.html', {})
else:
form = PollForm()
formset = ChoiceFormSet()
return render(request, 'polls/add_poll.html', {'form': form,
'formset': formset})
最后是您的模板:
<form method="post">
{% csrf_token %}
<table>
{{ form }}
{{ formset }}
</table>
<button>Add</button>
</form>
这篇关于在一个Django视图中合并两种形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!