如何使用单个窗体更新多个模型

2024-05-15 07:42:05 发布

您现在位置: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\u 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模板中包含了所有这三个表单

页面看起来像这样this


Tags: djangononamefromimportprefixmodelsrequest
1条回答
网友
1楼 · 发布于 2024-05-15 07:42:05
It returns None because your forms seems like invalid and you have not returned anything when your forms are invalid, so, that's why it is returning None from the "passengerAdd" function

Note:- Python will return None when you don't return anything from the function


You can save multiple forms by passing an instances to your form's save method.

    Example:-

    views.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)




        forms.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

相关问题 更多 >