Несколько разных форм в одном представлении Django

Я хотел узнать, есть ли способ иметь несколько различных форм в одном представлении и нажать одну кнопку отправки для сохранения информации. У меня есть следующие формы, первая - это общая форма, которая должна быть создана первой:

class GeneralForm(forms.ModelForm):
    name = forms.CharField(max_length=50)

    TYPE_CHOICES = (
        ("C","C"),
        ("E","E")
    )

    STATUS_CHOICES = (
        ("A", "A"),
        ("F", "F"),
    )
    type=forms.ChoiceField(choices=STATUS_CHOICES)
    number=forms.CharField(max_length=50)
    TURN_CHOICES = (
        ("1", "1"),
        ("2", "2"),
        ("3", "3")
    )
    turn = forms.ChoiceField(choices=TURN_CHOICES)

   

    class Meta:
        model = models.General
        fields=["name","type","number","turn"]

Второму нужен экземпляр первого, и третьему тоже:

class TypeOneForm(forms.ModelForm):
    num_chairs=forms.IntegerField()
    num_instalations = forms.IntegerField()
    total = forms.IntegerField()
    num_programs = forms.IntegerField()


    class Meta:
        model = models.TypeOne
        fields=["num_chairs","num_instalations","total","billetes_cien"]



class TypeTwoForm(forms.ModelForm):
    
    num_available_seats=forms.IntegerField()
    num_available_instalations = forms.IntegerField()
    total = forms.IntegerField()
    num_new_programs = forms.IntegerField()


    class Meta:
        model = models.TypeTwo
        fields=["num_available_seats", "num_available_instalations","total","num_programs" ]

Вот мои модели:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse


# Create your models here.
class General(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
    name = models.CharField(max_length=100)
    TYPE_CHOICES = {
        "C": "C",
        "E": "E",
    }
    type = models.CharField(max_length=10, choices=TYPE_CHOICES)
    STATUS_CHOICES = {
        "A": "A",
        "F": "F",
    }
    status = models.CharField(max_length=10, choices=STATUS_CHOICES)
    number = models.CharField(max_length=100)
    TURN_CHOICES = {
        "1": "1",
        "2": "2",
        "3": "3",
    }
    turn = models.CharField(max_length=10, choices=TURN_CHOICES)

    def __str__(self):
        return self.name


class One(models.Model):
    one = models.OneToOneField(General, on_delete=models.CASCADE, primary_key=True)
    num_chairs = models.IntegerField(default=0)
    num_installations = models.IntegerField(default=0)
    total = models.IntegerField(default=0)
    num_programs = models.IntegerField(default=0)


class Two(models.Model):
    two = models.OneToOneField(General, on_delete=models.CASCADE, primary_key=True)
    num_available_seats = models.IntegerField(default=0)
    num_available_installations = models.IntegerField(default=0)
    total = models.IntegerField(default=0)
    num_new_programs = models.IntegerField(default=0)

Вот мои представления, но я также не уверен, как написать представление создания и представление обновления для этого конкретного случая.

from django.shortcuts import render, get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.views.generic import (
    ListView,
    DetailView,
    CreateView,
    UpdateView,
)
from .models import General, One,Two
# Create your views here.

class GeneralListView(ListView):
    model = General
    template_name = "testing/user_testing.html"
    context_object_name = 'generals'

class GeneralDetailView(DetailView):
    model = General

class GeneralCreateView(LoginRequiredMixin, CreateView):
    model = General
    fields = '__all__'

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)
class GeneralUpdateView(LoginRequiredMixin, UpdateView):
    pass

Я читал, что могу использовать наборы форм, но не уверен, могу ли я использовать разные формы вместо нескольких экземпляров одной формы.

Инструмент, который вы здесь ищете, - это префиксный аргумент классов форм. Вам придется переопределить некоторые методы представлений, такие как get_form и, возможно, get_form_class, поскольку представления, основанные на классах, по умолчанию не рассчитаны на прием более одного типа форм. Вам также может понадобиться переопределить метод post в представлениях, чтобы загрузить данные из почтового запроса в формы.

Аргумент prefix означает, что данные формы, отправляемые в ваше приложение django, будут «namespaced», поэтому класс формы будет загружать из запроса только те данные post, которые ему нужны.

В зависимости от того, как вы отображаете свои формы, вам может понадобиться убедиться, что префикс также отображается в атрибуте name HTML-ввода.

По моему опыту, переопределить весь код представления, основанного на модели, будет сложнее: возможно, вы воспользуетесь более общим классом FormView, но вам придется повторить большую часть логики CreateView и UpdateView для обработки и сохранения (например, вызов form.save() в методе form_valid в FormView)

Мне всегда нравилось CCBV для распутывания порядка вызова методов представления, основанного на классах.

Еще одно замечание: вы всегда можете вывести на страницу более одной формы, но сделать так, чтобы отправленные данные попадали в разные представления. Если формы зависят друг от друга, возможно, будет проще написать одну форму, которая будет обрабатывать очищенные данные в экземпляры модели и сохранять их. Иными словами, в зависимости от сценария использования и опыта, который вы хотите получить от пользователей, вам нужно будет принять решение о том, как обрабатывать форму.

Обязательная ссылка на документацию

Вернуться на верх