Django:使用实例初始化自定义表单的表单集
鉴于以下模型:Django:使用实例初始化自定义表单的表单集,django,forms,instance,formset,Django,Forms,Instance,Formset,鉴于以下模型: class Graph(models.Model): owner = models.ForeignKey(User) def __unicode__(self): return u'%d' % self.id class Point(models.Model): graph = models.ForeignKey(Graph) date = models.DateField(primary_key = True) a
class Graph(models.Model):
owner = models.ForeignKey(User)
def __unicode__(self):
return u'%d' % self.id
class Point(models.Model):
graph = models.ForeignKey(Graph)
date = models.DateField(primary_key = True)
abs = models.FloatField(null = True)
avg = models.FloatField(null = True)
def __unicode__(self):
return u'%s' % self.date
我正在尝试创建一个用于编辑点列表的表单。
HTML输入标记需要设置其他属性,因此我使用以下自定义表单:
class PointForm(forms.ModelForm):
graph = forms.ModelChoiceField(queryset = Graph.objects.all(),
widget = forms.HiddenInput())
date = forms.DateField(widget = forms.HiddenInput(), label = 'date')
abs = forms.FloatField(widget = forms.TextInput(
attrs = {'class': 'abs-field'}),
required = False)
class Meta:
model = Point
fields = ('graph', 'date', 'abs') # Other fields are not edited.
def pretty_date(self):
return self.data.strftime('%B')
此时,我不知道如何将point类的实例传递给FormSet:
def edit(request):
PointFormSet = forms.formsets.formset_factory(PointForm, extra = 0)
if request.method == 'POST':
return
# Receive 3 points to edit from the database.
graph, res = Graph.objects.get_or_create(id = 1)
one_day = datetime.timedelta(days = 1)
today = datetime.date.today()
do_edit = []
for date in [today - (x * one_day) for x in range(3)]:
point, res = Point.objects.get_or_create(graph = graph, date = date)
do_edit.append(point)
formset = PointFormSet(????) # How is this initialized with the points?
我发现了一个有点奏效的黑客,但它会在稍后尝试处理生成的POST数据时导致错误:
do_edit = []
for date in [today - (x * one_day) for x in range(3)]:
point, res = Point.objects.get_or_create(graph = graph, date = date)
data = point.__dict__.copy()
data['graph'] = graph
do_edit.append(data)
formset = PointFormSet(initial = do_edit)
如何正确地做到这一点
作为参考,我的模板如下所示:
<form action="" method="post">
{{ formset.management_form }}
<table>
<tbody>
{% for form in formset.forms %}
<tr>
<td>{{ form.graph }} {{ form.date }} {{ form.pretty_date }}:</td>
<td width="100%">{{ form.abs }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
{{formset.management_form}
{formset.forms%%中表单的%
{{form.graph}{{form.date}{{form.pretty_date}}}:
{{form.abs}
{%endfor%}
诀窍是使用“ModelFormset”而不仅仅是formset,因为它们允许使用queryset进行初始化。这些文档是,您要做的是在创建模型表单集时提供一个form=*,在实例化表单集时提供queryset=*。form=*参数没有很好的文档化(必须在代码中仔细研究一下,以确保它确实存在)
因此代码很容易通过。如果请求是GET,那么实例化的表单将返回给用户。如果请求是一个POST,并且表单是not.is\u valid()
,则错误“fall-through”并在同一模板中返回。如果请求是POST且数据有效,则保存表单集
希望有帮助
-Will如果您只想设置一个可能的值,或者可能是一个闭合的值,则可以在用户使用
commit=False将数据发布到服务器后设置它们
请考虑以下代码:
class UserReferralView(View):
ReferralFormSet = modelformset_factory(ReferralCode,
form=ReferralTokenForm, extra=1)
def get(self, request):
pass
def post(self, request):
referral_formset = UserUpdateView.ReferralFormSet(request.POST)
if referral_formset.is_valid():
instances = referral_formset.save(commit=False)
for instance in instances:
instance.user = request.user
instance.save()
return redirect(reverse('referrals.success_view'))
else:
return redirect(reverse('referrals.failure_view'))
啊,太谢谢你了,真是太棒了。次要更正:验证POST数据时,初始化如下所示:“PointFormset(request.POST,queryset=qset)”。否则您将得到此错误:“具有此日期的点已存在”。doh。。。抢手货我忘了,当使用model_表单集并提供数据时,您也需要提供查询集。。。我从未真正使用过这个用例。
class UserReferralView(View):
ReferralFormSet = modelformset_factory(ReferralCode,
form=ReferralTokenForm, extra=1)
def get(self, request):
pass
def post(self, request):
referral_formset = UserUpdateView.ReferralFormSet(request.POST)
if referral_formset.is_valid():
instances = referral_formset.save(commit=False)
for instance in instances:
instance.user = request.user
instance.save()
return redirect(reverse('referrals.success_view'))
else:
return redirect(reverse('referrals.failure_view'))