我有以下 Django 结构。我使用最新的 Django 版本
5.1
。我也检查了版本4.2.15
问题仍然存在。
我的目标是让
Formset
使用基于类的视图。不管怎样,无论我尝试什么,我的表单集都永远无效。我可以在 request.POST
中看到原始数据,但它无法验证,is_valid
始终是 False
。我错过了什么?
低于我的 MCVE:
class Folder(models.Model):
reference = models.CharField(max_length=64, null=False, unique=True,)
class Revenue(models.Model):
folder = models.ForeignKey(Folder, null=False, on_delete=models.RESTRICT,)
amount = models.DecimalField(max_digits=10, decimal_places=2, null=False,)
class FolderForm(forms.ModelForm):
class Meta:
model = models.Folder
fields = ['reference']
class RevenueForm(forms.ModelForm):
class Meta:
model = models.Revenue
fields = ["amount"]
RevenueFormset = inlineformset_factory(
models.Folder, models.Revenue, RevenueForm,
extra=1, can_delete=True
)
class FolderTestView(LoginRequiredMixin, UpdateView):
template_name = "core/folder_test.html"
model = models.Folder
form_class = forms.FolderForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["revenue_formset"] = forms.RevenueFormset(instance=self.get_object())
return context
def post(self, request, *args, **kwargs):
print(request.POST) # Contains whole form raw data
formset = forms.RevenueFormset(request.POST, instance=self.get_object())
print(formset.is_valid()) # Always set as False
print(formset.errors) # No errors: []
return super().post(request, *args, **kwargs)
def form_valid(self, form):
print(form.cleaned_data)
return super().form_valid(form)
def get_success_url(self):
return reverse("core:folder-test", kwargs={"pk": self.kwargs["pk"]})
urlpatterns = [
path('folder/<int:pk>/test/', views.FolderTestView.as_view(), name='folder-test'),
]
<form action="{% url 'core:folder-test' object.id %}" method="POST">
{% csrf_token %}
{{ form|crispy }}
{{ formset.management_form }}
{% for revenue_form in revenue_formset %}
{{ revenue_form|crispy }}
{% endfor %}
<input type="submit" value="Submit" class="btn btn-primary">
</form>
原始数据存在,未验证且不返回错误:
<QueryDict: {'csrfmiddlewaretoken': ['secret'], 'reference': ['Test'], 'revenue_set-0-amount': ['1245.54'], 'revenue_set-1-amount': ['']}>
False
[]
我也尝试过
prefix
它并没有改变问题。
问题很简单,就是缺少管理表格。替换为:
<form action="{% url 'core:folder-test' object.id %}" method="POST">
{% csrf_token %}
{{ form|crispy }}
{{ revenue_formset.management_form }}
{% for revenue_form in revenue_formset %}
{{ revenue_form|crispy }}
{% endfor %}
<input type="submit" value="Submit" class="btn btn-primary">
</form>
问题解决了!