You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django中使用普通表单向多个关联模型传递数据可行吗?

用普通表单处理多关联模型数据提交方案

核心思路

不用写JS,直接创建一个包含所有所需字段的普通表单,在视图里手动处理数据,依次创建Customer、Order、OrderItem实例,完成多表关联数据的提交。


1. 定义表单类

创建一个包含三个模型所有需要字段的表单,外键关联的Product用ModelChoiceField直接选择:

from django import forms
from .models import Product

class OrderCreateForm(forms.Form):
    # 客户信息字段
    first_name = forms.CharField(max_length=50)
    last_name = forms.CharField(max_length=50)
    phone = forms.CharField(max_length=15, required=False)
    email = forms.EmailField()
    address_line_1 = forms.CharField(max_length=250)
    address_line_2 = forms.CharField(max_length=60, required=False)
    postal_code = forms.CharField(max_length=20)
    city = forms.CharField(max_length=100)
    state = forms.CharField(max_length=100, required=False)
    country = forms.CharField(max_length=100, initial="Mexico")
    
    # 订单信息字段
    paid = forms.BooleanField(required=False, initial=False)
    
    # 订单项信息字段
    product = forms.ModelChoiceField(queryset=Product.objects.all())
    quantity = forms.IntegerField(min_value=1, initial=1)

2. 编写视图处理逻辑

在视图里接收表单提交,验证通过后按关联顺序创建模型实例:

from django.shortcuts import render, redirect
from .forms import OrderCreateForm
from .models import Customer, Order, OrderItem

def order_create(request):
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            # 先创建客户
            customer = Customer.objects.create(
                first_name=form.cleaned_data['first_name'],
                last_name=form.cleaned_data['last_name'],
                phone=form.cleaned_data['phone'],
                email=form.cleaned_data['email'],
                address_line_1=form.cleaned_data['address_line_1'],
                address_line_2=form.cleaned_data['address_line_2'],
                postal_code=form.cleaned_data['postal_code'],
                city=form.cleaned_data['city'],
                state=form.cleaned_data['state'],
                country=form.cleaned_data['country']
            )
            # 再创建订单,关联刚创建的客户
            order = Order.objects.create(
                customer=customer,
                paid=form.cleaned_data['paid']
            )
            # 最后创建订单项,关联订单和选中的商品
            OrderItem.objects.create(
                order=order,
                product=form.cleaned_data['product'],
                quantity=form.cleaned_data['quantity']
            )
            # 提交完成后跳转到订单详情页
            return redirect('sales:order-update', pk=order.pk)
    else:
        form = OrderCreateForm()
    return render(request, 'sales/order_create.html', {'form': form})

3. 编写提交模板

直接渲染表单所有字段,普通POST提交即可:

<!-- sales/order_create.html -->
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">创建订单</button>
</form>

扩展说明

  • 如果需要支持多个订单项(一次买多个商品),可以用Django原生的FormSet,不用写JS,只需要定义订单项的表单集,在视图里循环处理每个表单实例即可。
  • 表单验证逻辑可以在OrderCreateForm里自定义,比如添加邮箱格式、手机号格式检查等,和普通表单操作一致。
  • 之前尝试的方案无效,大概率是因为只依赖ModelForm的外键关联,没有手动处理关联实例的创建,这个方案逻辑直白,完全手动控制数据流向,更适合新手理解。

内容的提问来源于stack exchange,提问作者Aris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:01:17