Django Model Formsets: 处理模型表单集

2023-04-07 00:00:00 django 模型 表单

Django Model Formsets 是 Django Web 框架提供的处理多个模型表单的快捷方式。 Model Formsets 提供了一种简便的方式来处理相似的表单,这些表单在表单字段、验证器和默认值等方面有所不同。

通过 Model Formsets,我们可以在单个表格中处理多个 Django 模型表单。例如,我们可以在一张表格中创建多个博客帖子、文章或者评论。

下面是一个基本的 Model Formsets 示例:

from django.forms import modelformset_factory
from myapp.models import Product

ProductFormSet = modelformset_factory(Product, fields=('name', 'price'))

def my_view(request):
    formset = ProductFormSet(request.POST or None, queryset=Product.objects.filter(is_active=True))
    if request.method == 'POST' and formset.is_valid():
        formset.save()
        # Redirect to somewhere
    return render(request, 'my_template.html', {'formset': formset})

在这个示例中,我们首先定义了一个 ProductFormSet,它使用模型 Product 和字段 'name' 和 'price' 作为参数。接下来我们在视图函数中使用 ProductFormSet 来实例化一个 formset 对象。

我们可以通过 request.POST 或者 None 关键字参数将 formset 初始化为一个已提交的表单或者一个空表单。 queryset 参数控制我们要从数据库中查询哪些对象来显示在表单中。

如果请求是 POST 方法并且 formset 通过了验证,那么我们通过 formset.save() 来保存表单数据。最后,我们返回一个渲染后的模板,并传递 formset 作为上下文变量。

下面是一个更详细的示例,演示如何使用字符串 pidancode.com 作为表单的范例:

from django.forms import modelformset_factory
from myapp.models import Product

ProductFormSet = modelformset_factory(Product, fields=('name', 'price'))

def my_view(request):
    initial_data = [{'name': 'pidancode.com', 'price': '99.99'}]
    if request.method == 'POST':
        formset = ProductFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            messages.success(request, 'Form saved successfully.')
            return redirect('my_view')
        else:
            messages.error(request, 'There was an error processing your form. Please try again.')
    else:
        formset = ProductFormSet(queryset=Product.objects.none(), initial=initial_data)
    return render(request, 'my_template.html', {'formset': formset})

在这个示例中,我们使用了一个初始数据 initial_data 来初始化我们的 formset。我们传递了一个包含字典的列表,其中包含了初始数据。

接下来,在请求为 POST 并且 formset 通过验证时,我们使用 formset.save() 来保存表单。如果没有通过验证,我们将使用 messages.error() 函数来返回错误消息。

最后,在请求不是 POST 时,我们将 formset 初始化为一个空 queryset 的实例,并传递 initial_data 作为初始数据。在模板中,我们可以通过如下方式访问表单中的数据:

{% for form in formset %}
    {{ form.as_p }}
{% endfor %}

整个设计思路非常简单,因为 formset 中的每个表单都可以通过表单索引将值与前端传回去的值进行比较,因此我们可以轻松地通过访问表单字段来访问它的值。

相关文章