Django formset показывает необработанные данные в POST, но никогда не становится валидным
У меня следующая структура Django. Я использую последнюю версию Django 5.1
.
Я пытаюсь заставить Formset
работать в первый раз. В любом случае, что бы я ни пробовал, мой набор форм никогда не является валидным. Я вижу исходные данные в request.POST
, но они не проверяются, поэтому я никогда не получаю разобранные данные в cleaned_data
. Что
Model.py
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,)
Form.py
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,
validate_min=True, extra=1, can_delete=True
)
View.py
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=context["object"])
return context
def post(self, request, *args, **kwargs):
print(request.POST) # Contains whole form raw data
formset = forms.RevenueFormset(request.POST)
print(formset.is_valid()) # Always set as False
return super().post(request, *args, **kwargs)
def form_valid(self, form):
print(form.cleaned_data) # Never gets the formset data
return super().form_valid(form)
def get_success_url(self):
return reverse("core:folder-test", kwargs={"pk": self.kwargs["pk"]})
url.py
urlpatterns = [
path('folder/<int:pk>/test/', views.FolderTestView.as_view(), name='folder-test'),
]
folder_test.html
<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>
Проблема была проста - отсутствовала форма управления. Замена на:
<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>
Решили проблему!