首页 > 解决方案 > 如何使用单个表单更新多个模型

问题描述

所以我一直在尝试更新三个模型,即

模型.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 模板中包含了所有三种形式

页面看起来像这样这

标签: pythondjangodjango-modelsdjango-forms

解决方案


它返回 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

推荐阅读