Как сохранить Django Form и Formset одновременно

У меня есть страница, на которой я использую форму и набор форм одновременно. Форма предназначена для информации о диссертации, а набор форм - для автора.

Вот код в моем models.py `

class thesisDB(Model):
    thesis_id = models.AutoField(primary_key=True, blank=True, null=False)
    title = models.CharField(max_length=200, blank=True, null=True, unique=True)
    published_date = models.DateField(blank=True, null=True)
    pdf = models.FileField(upload_to='pdf/', blank=True, null=True ,validators=[FileExtensionValidator(['pdf'])],)
    course = models.ForeignKey(ColCourse, default=None, on_delete=models.CASCADE, verbose_name='Course')
    tags = TaggableManager()
    date_created = models.DateField(auto_now_add=True, blank=True, null=True )
    uploaded_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=None)
    published_status = models.CharField(max_length=10, choices= THESIS_DECISION, default='Pending')
    abstract = models.TextField(blank=True, null=True)
    hit_count_generic = GenericRelation(HitCount, object_id_field='object_pk', related_query_name='hit_count_generic_relation')
    reason = models.TextField(blank=True, null=True)
    slug = models.SlugField(max_length = 250, null = True, blank = True) 

    def save(self, *args, **kwargs):
        self.title = self.title.title()
        #self.author = self.author.title()
        self.slug = slugify(self.title + "-" + self.author + "-" + str(self.published_date))
        super().save(*args, **kwargs)

    class Meta:
        db_table = 'thesis_storage'
initial_validator = RegexValidator('[A-Z]+.', 'Initial must contain period')

class Authors(Model):
    thesis = models.ForeignKey(thesisDB, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=200, blank=True, null=True)
    last_name = models.CharField(max_length=200, blank=True, null=True)
    middle_initial = models.CharField(max_length=2, blank=True, null=True, validators=[initial_validator])
        

`

Вот код в моем файле forms.py `

class AuthorForm(forms.ModelForm):
    class Meta: 
        model = Authors
        exclude = ()

        widgets = {
            'first_name': forms.TextInput(attrs=
                {'placeholder': 'First Name', 'class':'form-control', 'required': 'required'}),
            'last_name': forms.TextInput(attrs=
                {'placeholder': 'Last Name', 'class':'form-control', 'required': 'required'}),
            'middle_initial': forms.TextInput(attrs=
                {'placeholder': 'M.I.', 'class':'form-control', 'required': 'required'}),
        }

AuthorFormSet = inlineformset_factory(thesisDB, Authors, form=AuthorForm, 
        fields=['first_name', 'last_name', 'middle_initial'], extra=3, can_delete=False)

class thesisForm(forms.ModelForm):

    class Meta:
        model = thesisDB
        fields = ('title', 'published_date', 'course','tags', 'abstract', 'pdf',)
        readonly_fields = ['date_created']
        course = forms.ModelChoiceField(queryset=ColCourse.objects.all().order_by('-course_name'))
#        abstract = forms.CharField(widget=CKEditorWidget())
#        problem = forms.CharField(widget=CKEditorWidget())
        widgets = {
            'title': forms.TextInput(attrs=
                {'placeholder': 'Title', 'class':'form-control', 'required': 'required'}),
            'published_date': forms.DateInput(attrs=
                {'class':'form-control', 'required': 'required', 'type':'date'}),
            'abstract': forms.Textarea(attrs=
                {'placeholder': 'Abstract', 'class':'form-control',}),
            'course': forms.Select(attrs=
                {'placeholder': 'Short Description', 'class':'regDropDown', 'required': 'required'}),
        }


    def __init__(self, *args, **kwargs):
        super(thesisForm, self).__init__(*args, **kwargs)
        # Making location required
        self.fields['pdf'].required = True
        self.fields['abstract'].required = True
        self.fields['tags'].required = True

`

А это мой views.py для отправки формы. `

@login_required
@for_students
def submission(request):
    formset = AuthorFormSet()
    if request.method == "POST":
        form = thesisForm(request.POST, request.FILES)
        if form.is_valid() and formset.is_valid():
            form.instance.uploaded_by = request.user  # set the user
            post = form.save()  # save the form
            
            formset.instance.thesis = form.instance.thesis_id
            post = formset.save()

            message = "Your project entitled %s has been submitted successfully! We will notify you through email if it is once evaluated" % form.instance.title
            messages.success(request, message)
            return redirect('/profile/personal_repository/')
    else:
        form = thesisForm()
        formset = AuthorFormSet()

    return render(request,'StudentSubmitProject.html',{'form':form, 'formset':formset})

and my html file

<div class="container-fluid profilecontainer">
  <div class="row">
    <div class="col-lg-2"></div>
    <div class="col-lg-8 right_section">
      <h4 class="textmaroon">Submit A Project</h4>
      <p>The requirements for submitting a thesis follows:<p>
      <ul>
        <li>The softcopy of your thesis which is in PDF format.</li>
        <li>The pdf file should contain the approval form attesting the thesis has been approved by your department.</li>
        <li>The descriptions of thesis such as its Title, Author, Publication Date, Course, and Keywords.</li>
        <li>The abstract text of your thesis which should match in the pdf file.</li>
      </ul>
      <p>Below is the form for submitting a thesis project. Your project would be evaluated first by the Admin Account before it can be available to access in the system, so ensure that the given details are valid to avoid possible rejection.</p>
      <hr></hr>

      <form method="POST" class="mt-5 form-group profile_form" enctype="multipart/form-data">
        {{formset.management_data }}
        {% csrf_token %}

        <h4 class="textmaroon">Add author</h4>
        <p>Enter the author/s of the thesis project</p>
        <hr></hr>
        <div class="row">
          {% for form_s in formset %}
          <div class="col-md-5">
            {{form_s.first_name | as_crispy_field}}
          </div>
          <div class="col-md-5">
            {{form_s.last_name | as_crispy_field}}
          </div>
          <div class="col-md-2">
            {{form_s.middle_initial | as_crispy_field}}
          </div>
          {% endfor %}
        </div>

        <h4 class="textmaroon mt-5">Describe the thesis</h4>
        <p>Define the thesis project</p>
        <hr></hr>
        <div class="row">
          <div class="col-md-12">
            {{form | crispy}}
          </div>
        </div>

         <div class="row">
          <div class="col-md-12">
            <button type="submit" class="btn btn-danger mt-3 float-end">Submit</button>
            <button type="reset" class="btn btn-secondary mt-3 me-2 float-end">Reset</button>
          </div>
        </div>
      </form>
    </div>
    <div class="col-lg-2"></div>
  </div>
</div>

`

Моя проблема в том, что введенные данные в форме сохраняются, но не сохраняются в наборе форм

Потому что вы не добавили request.POST в ваш набор форм, поэтому никакие данные не были переданы в набор форм:

if request.method == "POST":
     formset = AuthorFormSet(request.POST) #need request.POST
     form = thesisForm(request.POST, request.FILES)
     if form.is_valid() and formset.is_valid():

если в наборе форм также есть файл, добавьте request.FILES в качестве второго аргумента

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