[编辑]
由于我已经删除了 new_method = ... 和 syspar.method.add() 行(这是由 method.save() 处理的),我最初丢弃的解决方案已经变成了 DRY,所以它是完全可以接受的。
我仍然认为设置 self.fields[].initial (根据 pyriku 的回答)仅在 extra > 0 时才有效,因为在“添加表单”按钮之前不希望显示表单的简单用例是单击后,必须有 extra=0 并且应该可以为新添加的表单设置初始值。
[ /编辑]
免责声明:我查看了许多相关问题的答案,但我只找到了一种可行的解决方案,但对我来说似乎很笨拙,而且不是很干燥(4378667)/免责声明
我有一个modelformset,我将extra设置为0,因为我只想在用户按下“add_method”时显示一个新表单。一切正常,除了新添加的表单是空的(期望的行为:它们包含我在方法表中设置的名称的默认值)
在模型.py 中:
class System(models.Model):
method = models.ManyToManyField(Method)
...
class Method(models.Model):
name = models.CharField()
...
在 view.py 中:
syspar = System.objects.get(id=sys_id)
MethodFormSet = modelformset_factory(Method, form=MethodForm, extra=0)
if request.POST:
if 'add_method' in request.POST:
new_method = Method.objects.create(name='whatever')
syspar.method.add(new_method)
post = request.POST.copy()
post['method-TOTAL_FORMS'] = repr(int(post['method-TOTAL_FORMS'])+ 1)
post['method-2-name'] = 'whatever' # code needed here to get actual value of -2-
methodformset = MethodFormSet(data=post, prefix='method',
queryset=Method.objects.filter(id__in=syspar.method.all()))
我的行有问题: post['method-2-name']='' 这很糟糕,因为:
- 我已经在 db 表中设置了值
- 我需要额外的 cruft 来确定每个案例的“2”值
我尝试了这种方法,也尝试了设置初始值(如对其他一些相关问题的回答中所建议的那样),但都没有奏效,而且都导致了非 DRY 代码。
必须有更好的方法来做到这一点......