在 Django 中使用一个创建视图的多个表单

Multiple forms with one single create view in Django

我有 5 个表格:MyForm、EducationForm、ExperienceForm、RecommendationForm、OtherDocumentsForm 我想在一个表单模板中显示它们。我不能用 CreateView 来做,因为它只接受一种形式 class。如何为多个表单创建单一视图?

class MyForm(forms.ModelForm):
    class Meta:
        model = UserForm_uz
        fields = 'all'

class EducationForm(forms.ModelForm):
    class Meta:
        model = Education_uz
        fields = 'all'

class ExperienceForm(forms.ModelForm):
    class Meta:
        model = Experience_uz
        fields = 'all'

class RecommendationForm(forms.ModelForm):
    class Meta:
        model = Recommendation_uz
        fields = 'all'

class OtherDocumentsForm(forms.ModelForm):
    class Meta:
        model = OtherDocuments
        fields = 'all'

我希望在一个请求和一个按钮中提交所有表单。它们与外键相互关联 EducationForm、ExperienceForm、RecommendationForm、OtherDocumentsForm 使用外键

连接到 MyForm

我的模特:

from django.db import models
language_choices = [('1', 'Билмайман'),
                    ('2', 'Ёмон'),
                    ('3', 'Лугат ёрдамида'),
                    ('4', 'Ўртача'),
                    ('5', 'Яхши'),
                    ('6', 'Жуда яхши'), ]
approve_choices = [('Yes', 'Ха'),
                    ('No', 'Йўк')]
agreement_choices = [('Yes', 'Ха'),
                    ('No', 'Йўк')]
class UserForm_uz(models.Model):
    rasm = models.ImageField(upload_to='rasmlar',null=True,blank=True)
    lastName = models.CharField(max_length=200)
    firstName = models.CharField(max_length=200)
    middleName = models.CharField(max_length=200)
    birthData = models.DateField()
    nation = models.CharField(max_length=50)
    birthPlace = models.CharField(max_length=250)
    marriage_status = models.CharField(max_length=20)
    children = models.CharField(max_length=20)
    militaryResp = models.CharField(max_length=150)
    language_uzbek = models.CharField(choices=language_choices,max_length=150)
    language_russian = models.CharField(choices=language_choices,max_length=150)
    language_english = models.CharField(choices=language_choices,max_length=150)
    language_boshqa = models.CharField(max_length=50)
    computer_literacy = models.CharField(max_length=15)
    functional_resp = models.CharField(max_length=250)
    work_experience = models.CharField(max_length=200)
    yutuqlar = models.CharField(max_length=200)
    leaving_work_reason = models.CharField(max_length=200)
    main_skills = models.CharField(max_length=300)
    expected_salary = models.CharField(max_length=100)
    reasontoWork = models.CharField(max_length=300)
    relatives_company = models.CharField(max_length=300)
    criminal_history = models.CharField(max_length=250)
    homeNumber = models.CharField(max_length=15)
    phoneNumber = models.CharField(max_length=15)
    email = models.EmailField()
    additional_info = models.CharField(max_length=300)
    approve_info = models.CharField(choices=approve_choices,max_length=20)
    agreement = models.CharField(choices=agreement_choices,max_length=20)

    passport_file = models.FileField(upload_to='fayllar')
    diplom_file = models.FileField(upload_to='fayllar')
    trudovoyKnishka = models.FileField(upload_to='fayllar')
    fullName = models.CharField(max_length=100)

class Education_uz(models.Model):
    form = models.ForeignKey(
        UserForm_uz,
        on_delete=models.CASCADE,
    )
    startingDate = models.DateField()
    endingDate = models.DateField()
    name = models.CharField(max_length=200)
    degree = models.CharField(max_length=50)
    speciality = models.CharField(max_length=150)
    diplomSeriya = models.CharField(max_length=50)


class Experience_uz(models.Model):
    form = models.ForeignKey(
        UserForm_uz,
        on_delete=models.CASCADE,
    )
    startWorkDate = models.DateField()
    endWorkDate = models.DateField()
    name = models.CharField(max_length=100)
    lavozim = models.CharField(max_length=100)
    address = models.CharField(max_length=100)

class Recommendation_uz(models.Model):
    form = models.ForeignKey(
        UserForm_uz,
        on_delete=models.CASCADE,
    )
    fullName = models.CharField(max_length=150)
    workPlace = models.CharField(max_length=150)
    phoneAndEmail = models.CharField(max_length=100)

class OtherDocuments(models.Model):
    form = models.ForeignKey(
        UserForm_uz,
        on_delete=models.CASCADE,
    )
    file = models.FileField(upload_to='fayllar')
    comment = models.CharField(max_length=100)

由于 MyForm 将与其他表单同时提交,因此您需要从所有其他模型中排除 UserForm_uz 的 ForeignKey 字段,相关对象尚不存在,因此你不能 select 它

class EducationForm(forms.ModelForm):
    class Meta:
        model = Education_uz
        # Repeated for all four forms
        exclude = ['form']  # Whatever the ForeignKey to UserForm_uz is named

这是一个使用三种形式的示例视图(我漏掉了两种以节省输入)。给每个表单一个前缀,这样可以降低表单字段名称冲突的风险。一次验证它们,如果任何形式无效,则视图不应继续。先保存 MyForm 并使用输出作为外键值传递给其他窗体

def my_view(request):
    if request.method == 'POST':
        my_form = MyForm(request.POST, request.FILES, prefix='user')
        education_form = EducationForm(request.POST, request.FILES, prefix='education')
        experience_form = ExperienceForm(request.POST, request.FILES, prefix='experience')
        if all([my_form.is_valid(), education_form.is_valid(), experience_form.is_valid()]):
            form = my_form.save()
            education = education_form.save(commit=False)
            education.form = form
            education.save()
            experience = experience_form.save(commit=False)
            experience.form = form
            experience.save()
            return redirect('some-view')
    else:
        my_form = MyForm(prefix='user')
        education_form = EducationForm(prefix='education')
        experience_form = ExperienceForm(prefix='experience')
    return render(request, 'template.html', {'my_form': my_form, 'education_form': education_form, 'experience_form': experience_form})

在您的模板 (template.html) 中,您需要以相同的表单标记呈现所有表单

<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ my_form }}
    {{ education_form }}
    {{ experience_form }}
    <input type="submit" />
</form>