如何创建一个发布请求以使ModelForm有效(为您提供用户需要填写的所有内容),然后更改模型(为用户提供不必提供的所有内容,例如用户名/个人资料,日期时间,其他可计算变量等...]),然后在视图中验证表单/表单集?
示例代码:
views.py
def view(request):
# Create the formset, specifying the form and formset we want to use.
LowerFormSet = formset_factory(LowerForm, formset=BaseLowerFormSet, extra=0)
# If they are posting data
if request.method == 'POST':
# Grab the data they submitted
formData = request.POST
# highestForm = MealForm(formData, meal=meal, prefix='recipe')
lower_formset = LowerFormSet(formData, prefix='lower_formset')
lower_form in lower_formset:
lower_form.instance.a = A.objects.create(…)
# HERE
# Each form isn't valid, because it is missing its associated higher object, despite not including the field in the ModelForm
lower_form.save()
# But if we create a foreign key/higher object and add it here, we are circumventing the validation step, and creating objects when the validation might not be True
lower_form.instance.higher = Higher.objects.create(…)
lower_form.save()
# How do you separate these concerns, so you can create a valid Model Form, then add the necessary parts after the validation?
# Check for valid data
if all([otherForm.is_valid(),
lower_formset.is_valid(),
other_formset.is_valid(),
]):
# make the Higher here, and add it to each form
for form in lower_formset:
form.higher = higher
form.save()
return HttpResponseRedirect(reverse('recipe:success'))
else:
return response = render(request, 'template', {…})
else:
# …
models.py
class Lower(models.Model):
higher = models.ForeignKey(Higher, related_name="higher")
# Etiher A or B is required, depending on information from the foreign key of the Higher
a = models.ForeignKey(A, blank=True, null=True, related_name="switch_case")
b = models.ForeignKey(B, blank=True, null=True, related_name="switch_case")
createdAt = models.DateTimeField(auto_now_add=True)
def clean(self):
if self.higher.a:
if not self.a:
raise AssertionError("The higher wants a, but you did not provide a")
if self.b:
raise AssertionError("The higher wants a, but you provided b")
else:
if not self.a:
raise AssertionError("The higher wants b, but you provided a")
if self.b:
raise AssertionError("The higher wants b, but you did not provide b")
def save(self, *args, **kwargs):
self.clean()
super(Lower, self).save(*args, **kwargs)
答案 0 :(得分:2)
您会因考虑无效表格而感到困惑。在对表单进行任何操作之前,表单必须始终有效,但这并不意味着它必须表示模型的有效实例。您需要做的是排除您不想显示给用户的字段,然后在实例上设置这些字段。
class LowerForm(forms.ModelForm):
class Meta:
model = Lower
exclude = ['higher']
和视图:
lower_formset = LowerFormSet(formData, prefix='lower_formset')
if lower_formset.is_valid(): # perform validation
for lower_form in lower_formset:
lower = lower_form.save(commit=False) # create a Lower instance but don't save to db yet
lower.higher = Higher.objects.create(…)
lower.save()