在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
相关产品推荐
相关产品推荐

