POST请求不适用于Django表单和Django表单集

问题描述 投票:0回答:1

我有一个表单ApplyJobForm和一个表单集ApplyJobFormset。当我将表单和表单集传递到视图时,GET方法起作用,但是对于发布请求,表单和表单集is_valid()不起作用,单击提交后,它将返回到视图而不保存。我无法使用表单集保存表单,我不知道我在做什么错。这是我的代码。

models.py

class Applicants(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    job = models.ForeignKey(Job, on_delete=models.CASCADE, related_name='applicants')
    experience = models.IntegerField(blank=True, null=True)
    cv = models.FileField(upload_to=user_directory_path)
    degree = models.CharField(choices=DEGREE_TYPE, blank=True, max_length=10)
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f'{self.user.get_full_name()} Applied'


class Certification(models.Model):
    applicant = models.ForeignKey(Applicants, on_delete=models.CASCADE, related_name='applicant_certifications')
    name = models.CharField(max_length=50)
    certification = models.FileField(upload_to=user_directory_path, blank=True)

    def __str__(self):
        return f'{self.user.get_full_name()} certificate'

forms.py

class ApplyJobForm(forms.ModelForm):

    class Meta:
        model = Applicants
        fields = ('job', 'degree', 'experience', 'cv')
        exclude = ('job',)
        labels = {
            'degree': 'Degree',
            'experience': 'Experience',
            'cv': 'CV',
        }
        widgets = {
            'degree': forms.Select(attrs={
                'class': 'form-control',
            }
            ),
            'experience': forms.NumberInput(
                attrs={
                    'class': 'form-control',
                }
            ),
            'cv': forms.FileInput(
                attrs={
                    'class': 'form-control',
                }
            ),
        }


ApplyFormset = modelformset_factory(
    Certification,
    fields=('name', 'certification'),
    extra=1,
    widgets={
        'name': forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': 'Certification name'
            }
        ),
        'certification': forms.FileInput(
            attrs={
                'class': 'form-control',
                'placeholder': 'Upload certification'
            }
        )
    }
)

views.py

def job_apply(request, job_id=None):
    template_name = 'apply_form.html'
    applyform = ApplyJobForm(request.GET or None)
    job = get_object_or_404(Job, id=job_id)
    formset = ApplyFormset(queryset=Certification.objects.none())
    if request.method == 'GET':
        context = {'applyform': applyform, 'formset': formset}
        return render(request, template_name, context)
    elif request.method == 'POST':
        applyform = ApplyJobForm(request.POST)
        formset = ApplyFormset(request.POST)
        if applyform.is_valid() and formset.is_valid():
            apply = applyform.save(commit=False)
            applyform.job = job
            apply.save()
            for form in formset:
                # so that `apply` instance can be attached.
                certification = form.save(commit=False)
                certification.apply = apply
                certification.save()
            return redirect('successful-apply')
        else:
            return redirect('job-detail', id=job.id)

    return render(request, template_name, {'applyform': applyform, 'formset': formset})

尽管申请者不是必填字段,但申请人在申请工作时可以在其中添加任意多个申请字段。认证模型绑定到申请人模型。

。html

<form class="form" method="POST" action="" enctype="multipart/form-data" role="form" autocomplete="off">
.................
</form>
django post django-forms formset
1个回答
1
投票

首先,从不如果您的表单无效,则重定向。您想要使用无效的表单呈现模板,以便可以将错误display显示给用户。这也有助于调试,因为您会看到错误。

因此,在您看来,删除这两行:

        else:
            return redirect('job-detail', id=job.id)

以便无效的大小写在您的模板中呈现表单。

下一步,由于您要上传文件,因此需要使用request.FILES初始化需要文件的表单:

formset = ApplyFormset(request.POST, request.FILES)

(和applyform相同。

最后确保在模板中您还同时在每个字段({{ form.<field>.errors }})或全局({{ form.errors }})上显示所有错误。

© www.soinside.com 2019 - 2024. All rights reserved.