动态填充表单集中的字段

时间:2009-06-20 00:43:03

标签: django django-forms inline-formset

我有两个看起来像这样的模型:

class RouteBase(models.Model):
    base        =   models.ForeignKey("Base")
    route       =   models.ForeignKey("Route")
    sequence    =   models.IntegerField()

class Route(models.Model):
    bases       =   models.ManyToManyField("Base", through="RouteBase", blank=True)
    description =   models.TextField(blank=True)
    #and a few other attributes omitted for brevity

...然后是一个看起来像这样的模型:

class RouteBaseForm(ModelForm):
    base = forms.ModelChoiceField(queryset=Base.objects.all(), widget=forms.TextInput)
    sequence = forms.IntegerField(widget=forms.HiddenInput)

    class Meta:
        model = RouteBase

正如您所看到的,序列窗口小部件是隐藏的,因为我希望这个字段由django自动处理。我希望用户只需通过文本框输入Base。序列由文本框的顺序推断。

我创建了一个带有此表单的formset,用于创建/编辑路径中的所有基础:

RouteBaseFormset = inlineformset_factory(Route, RouteBase, form=RouteBaseForm, extra=5, )

创建此formset时,序列字段为空。在保存formset之前我需要用值填充它(否则它将不会验证)。我可以想到四种方法来实现这个目标

  1. 在我将表单集发送到模板之前,我运行此代码:
  2.     i=1
        for form in formset.forms:
            form.fields["sequence"].initial = i
            i += 1
    

    除了一个问题外,这个工作正常。当formset被提交回视图以进行保存时,所有 5使用formset创建的额外字段将填入序列值。当用户只想向路线添加2或3个碱基时,这会导致问题。弹出验证错误,因为该表单的必填字段“base”为空。我在可以运行一些代码后,在表单集已经POST,检查是否存在一个库,如果没有,删除序列,但如果我要这样做,我可能会良好...

    1. 在表单集POSTed时运行一些代码,检查是否已输入Base,如果是,则添加序列,如果没有,则将该字段留空。这样,当您尝试.save() formset时,空值确保不将特定表单放入数据库。唯一的问题是我不能对表单做任何事情,直到我运行.save(commit=False)这是我无法做到的,因为formset没有验证。但我可以......

    2. 通过复制request.POST变量并手动设置序列来添加序列值,但这看起来非常糟糕。

    3. 我也可以从我的blank=True个字段中删除RouteBase,但我真的不想这样做。

    4. 那我该怎么办?

2 个答案:

答案 0 :(得分:5)

如果您从未打算让用户编辑序列字段并计划始终在后端计算它的值,您可以exclude it from the form,而不是隐藏它。

然后你可以使用commit = False并根据需要处理你的序列字段的计算。

答案 1 :(得分:-2)

newPOST = request.POST.copy()
i=1
for index in range(0, int(request.POST["routebase_set-TOTAL_FORMS"])-1):
    if request.POST["routebase_set-" + str(index) + "-base"]:
        newPOST["routebase_set-" + str(index) + "-sequence"] = i
        i += 1
    else:
        newPOST["routebase_set-" + str(index) + "-sequence"] = ""

老实说,这似乎比任何搞乱表单验证更好。它并不像我想象的那样hacky ......