在 Django 中处理动态生成的表单的更好方法

Posted

技术标签:

【中文标题】在 Django 中处理动态生成的表单的更好方法【英文标题】:Better ways to handle dynamically generated forms in Django 【发布时间】:2015-08-08 03:42:29 【问题描述】:

我有一个表单,允许用户记录他们的活动。为简单起见,假设我只有两个希望用户填写的字段。

时间 动作

一天中,用户可以填写多个时间+操作对。我在前端使用了 javascript,以允许用户根据需要添加这些对。

因此,我不知道事先会有多少对。因此,我无法为其创建预定义的 ModelForm。

为了处理这个问题,我用一个唯一的名称标记了每个时间和操作字段。所以当我收到一个 POST 请求时,我会在 request.POST 字典中得到一个这样的列表:

time_1: 9:50 action_1:唤醒 time_2: 11:00 aciton_2:锻炼 ...

然后,我从字典中减去每一对,并将它们放入 ModelForm 中进行验证并保存到数据库中。

class TimeActionModel(Model):
    time = DateField()
    action = CharField(max_length=100)

class TimeActionForm(ModelForm):
    class Meta:
        model = TimeActionModel

class TimeActionView(View):
    def post(self, request, *args, **kwargs):
        self._subtract_and_save(request)

    def _subtract_and_save(request):
        #loop through the request.POST dictionary
            #pull out each pair
            #stuff each one into a ModelForm object
            if form.is_valid():
                form.save()

这是我的问题:

您觉得这种方法合适吗? 处理这种情况的“Django 方式”是什么?

谢谢!

【问题讨论】:

【参考方案1】:

Django中有一个概念叫formset:

表单集是一个抽象层,用于在同一页面上处理多个表单。最好将其与数据网格进行比较。

Django 方法是使用Model formsets:

与常规表单集一样,Django 提供了一些增强的表单集类,可以轻松使用 Django 模型。

因此,您可以为您的 TimeActionModel 创建一个模型表单集,如下所示:

from django.forms.models import modelformset_factory

TimeActionFormset = modelformset_factory(TimeActionModel)

您可以在文档中阅读更多相关信息。它有广泛的用例和示例来涵盖您的案例。

更新:formset 的extras 参数不是很重要。您可以轻松地操作表单集with a bit of javascript 中额外表单的数量。还有一些 contrib 包,例如 django-dynamic-formset。

UPDATE2:字段的名称也取决于使用的prefix,如果单个页面中有许多不同的表单/表单集,我建议使用它,但是您可以通过查看 Django 呈现的默认表单轻松推断它.

另外请不要忘记在您的模板中包含 my_formset.management_form my_formsets_form.id

【讨论】:

感谢您指出这一点。在阅读表单集文档时,它声明了formset_factory(ArticleForm, extra=2),这意味着您必须定义将在渲染页面上显示多少个集合。但是对于我的情况,不知道会有多少个 TimeAction 对。因此,我不知道应该将其设置为多少。 谢谢。我明白你的意思了。每次添加新表单时,我似乎都需要使用 javascript 来增加隐藏的“form-TOTAL_FORMS”。此外,对于新添加的表单,我需要确保每个输入字段都有一个“form-set_number-field_name”格式的名称。我说的对吗? 欢迎您!再次更新答案并添加链接***.com/a/8097617/940098

以上是关于在 Django 中处理动态生成的表单的更好方法的主要内容,如果未能解决你的问题,请参考以下文章

Django:在按钮按下时提供动态生成的数据作为附件

使用 Django,有没有更好的方法在 urls.py 中动态导入视图?

Django 中的动态表单要求

请教朋友们,django如何动态改变ImageField,FileField的upload_to?...

Django 动态表单保存

Django 动态名称属性并在views.py 中获取值