python - 如何使用单个表单更新多个模型
问题描述
所以我一直在尝试更新三个模型,即
模型.py:
from django.db import models
from postlog.models import FlightNum
class pnr(models.Model):
pnr=models.CharField(max_length=9,primary_key=True)
def __str__(self):
return self.pnr
class name(models.Model):
pnr=models.OneToOneField(pnr,on_delete=models.CASCADE,related_name='p1')
name=models.CharField(max_length=10)
def __str__(self):
return self.name
class passenger(models.Model):
pnr=models.OneToOneField(pnr,on_delete=models.CASCADE,primary_key=True,related_name='p2')
name=models.ForeignKey(name,on_delete=models.CASCADE)
dob=models.CharField(max_length=10)
passport_no= models.CharField(max_length=10,blank=True)
fl_no=models.ForeignKey (FlightNum,on_delete=models.SET_NULL,null=True,unique=False)
所以我想做的是创建一个表单,我可以从用户那里获取 pnr、name、dob、passport_no 的输入,并同时更新所有三个模型
我创建了 3 个模型表单,如下所示:
表格.py:
from Django.forms import ModelForm
from postlog.models import FlightNum
from passenger.models import pnr,name,passenger
class pnrForm(ModelForm):
class Meta:
model = pnr
fields = '__all__'
labels = {
'pnr' : ('PNR')
}
class nameForm(ModelForm):
class Meta:
model = name
fields = ('name',)
labels = {
'name' : ('Name')
}
class passenForm(ModelForm):
class Meta:
model = passenger
fields = ('dob', 'passport_no', 'fl_no')
labels = {
'dob' : ('Date Of Birth'),
'passport_no' : ('Passport Number'),
'fl_no' : ('Flight Number'),
}
我的意见.py:
from django.shortcuts import render,redirect
from passenger.forms import passenForm, pnrForm, nameForm
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
def passengerAdd(request):
if request.method =="POST":
formA = pnrForm(request.POST, prefix= 'pnr')
formB = nameForm(request.POST, prefix= 'name')
formC = passenForm(request.POST, prefix= 'pass')
if formA.is_valid() and formB.is_valid() and formC.is_valid():
fa = formA.save()
fb = formB.save(commit=False)
fb.pnr = fa
fb.save()
fc = formC.save(commit=False)
fc.pnr = fa
fc.name = fb
fc.save()
return redirect(reverse('passenger_list'))
else:
formA = pnrForm(prefix = 'pnr')
formB = nameForm(prefix = 'name')
formC = passenForm(prefix = 'pass')
args = {'formA' : formA, 'formB' : formB, 'formC' : formC}
return render(request, 'passenger_add.html', args)
我已经在 html 模板中包含了所有三种形式
页面看起来像这样
解决方案
它返回 None 因为您的表单似乎无效,并且当您的表单无效时您没有返回任何内容,所以,这就是它从“passengerAdd”函数返回 None 的原因
注意:- 当您不从函数返回任何内容时,Python 将返回 None 您可以通过将实例传递给表单的 save 方法来保存多个表单。例子:-
视图.py
from django.shortcuts import render, redirect
from .forms import passenForm, pnrForm, nameForm
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
def passengerAdd(request):
if request.method == "POST":
formA = pnrForm(request.POST, prefix='pnr')
formB = nameForm(request.POST, prefix='name')
formC = passenForm(request.POST, prefix='pass')
if formA.is_valid() and formB.is_valid() and formC.is_valid():
a = formA.save()
b = formB.save(a)
c = formC.save(a, b)
return render(request, 'passenger/passenger_home.html')
else:
formA = pnrForm(prefix='pnr')
formB = nameForm(prefix='name')
formC = passenForm(prefix='pass')
args = {'formA': formA, 'formB': formB, 'formC': formC}
return render(request, 'passenger_add.html', args)
表格.py
from django.forms import ModelForm
from .models import pnr, name, passenger
class pnrForm(ModelForm):
class Meta:
model = pnr
fields = '__all__'
labels = {
'pnr': ('PNR')
}
class nameForm(ModelForm):
class Meta:
model = name
fields = ('name',)
labels = {
'name': ('Name')
}
def save(self, b, commit=True):
instance = super(nameForm, self).save(commit=False)
if not self.instance.pk:
# create
if commit:
instance.pnr = b
instance.save()
return instance
class passenForm(ModelForm):
class Meta:
model = passenger
fields = ('dob', 'passport_no')
labels = {
'dob': ('Date Of Birth'),
'passport_no': ('Passport Number'),
}
def save(self, a, b, commit=True):
instance = super(passenForm, self).save(commit=False)
if not self.instance.pk:
# create
if commit:
instance.pnr = a
instance.name = b
instance.save()
return instance
推荐阅读
- c# - 实体框架从非抽象类继承表结构,但创建所有字段
- javascript - 在 Chrome 和 Safari 上运行的 jQuery,不在 Firefox、Edge 和 Brave 上运行
- html - 搜索、输入、按钮边距和填充
- cs50 - 程序继续打印多行然后用户输入的内容
- c++ - Windows下所有类别的过滤器和硬件设备列表
- networking - Ansible 持久连接
- r - 如何从R中的数据框行中删除特定字符
- ios - 安全地展开可选值并将其添加到 Alamofire 参数
- android - 后台服务 Android Studio - 与服务断开连接
- postgresql - uWSGI (PythonAnywhere)、Flask、SQLAlchemy 和 PostgreSQL:SSL 错误:解密失败或坏记录 mac