我有一个表单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>
首先,从不如果您的表单无效,则重定向。您想要使用无效的表单呈现模板,以便可以将错误display显示给用户。这也有助于调试,因为您会看到错误。
因此,在您看来,删除这两行:
else:
return redirect('job-detail', id=job.id)
以便无效的大小写在您的模板中呈现表单。
下一步,由于您要上传文件,因此需要使用request.FILES
初始化需要文件的表单:
formset = ApplyFormset(request.POST, request.FILES)
(和applyform
相同。
最后确保在模板中您还同时在每个字段({{ form.<field>.errors }}
)或全局({{ form.errors }}
)上显示所有错误。