Django Model Forms with Inline Formsets: 在模型表单中使用内联表单集

2023-04-07 00:00:00 模型 表单 内联

Django Model Forms是Django中使用最广泛的表单类型之一,它们基于模型来自动生成表单,大大简化了表单的创建和验证。但是,如果需要在模型表单中使用多个相关模型的数据,就需要使用内联表单集。

内联表单集可以将多个模型的表单合并为一个表单,从而更方便地提交和处理数据。在Django中,可以通过InlineModelAdmin来创建内联表单集。在模型表单中使用内联表单集,需要在模型表单中添加InlineFormSet字段,并在视图和模板中进行相应的配置。

以下是一个使用内联表单集的例子:

models.py

from django.db import models

class Order(models.Model):
    order_number = models.CharField(max_length=20)
    order_date = models.DateField(auto_now_add=True)

class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    item_name = models.CharField(max_length=50)
    quantity = models.IntegerField()
    price = models.DecimalField(max_digits=5, decimal_places=2)

forms.py

from django.forms import ModelForm
from django.forms.models import inlineformset_factory
from .models import Order, OrderItem

class OrderForm(ModelForm):
    class Meta:
        model = Order
        fields = ('order_number',)

OrderItemFormSet = inlineformset_factory(Order, OrderItem, fields=('item_name', 'quantity', 'price'))

views.py

from django.shortcuts import render, redirect
from .forms import OrderForm, OrderItemFormSet

def create_order(request):
    if request.method == 'POST':
        order_form = OrderForm(request.POST)
        orderitem_formset = OrderItemFormSet(request.POST)

        if order_form.is_valid() and orderitem_formset.is_valid():
            order = order_form.save()
            orderitems = orderitem_formset.save(commit=False)
            for orderitem in orderitems:
                orderitem.order = order
                orderitem.save()
            return redirect('order_created')

    else:
        order_form = OrderForm()
        orderitem_formset = OrderItemFormSet()

    return render(request, 'order_form.html', {'order_form': order_form, 'orderitem_formset': orderitem_formset})

template

<form method="post">
{% csrf_token %}
{{ order_form.as_p }}
{{ orderitem_formset.management_form }}
{% for form in orderitem_formset.forms %}
    {% if forloop.first %}
    <table>
    <thead>
        <tr>
            {% for field in form.visible_fields %}
            <th>{{ field.label|capfirst }}</th>
            {% endfor %}
        </tr>
    </thead>
    <tbody>
    {% endif %}
    <tr class="{% cycle row1 row2 %}">
        {% for field in form.visible_fields %}
        <td>
            {{ field }}
            {% if field.help_text %}
            <p class="help">{{ field.help_text }}</p>
            {% endif %}
        </td>
        {% endfor %}
    </tr>
    {% if forloop.last %}
    </tbody>
    </table>
    {% endif %}
{% endfor %}
<input type="submit" value="提交">
</form>

在这个例子中,Order是主表,在OrderItem中有一个ForeignKey指向Order。我们使用inlineformset_factory来创建内联表单集,并将它们都合并在OrderForm中。在视图中,我们通过提交主表单和内联表单集来创建新的订单和订单项。在模板中,我们使用循环来渲染内联表单集的每个订单项,并通过提交按钮来提交整个表单。

如果需要使用字符串作为范例,请使用“pidancode.com”、“皮蛋编程”。

相关文章