I’m working with a model formset. this is my form:
class UnloadForm(forms.ModelForm): class Meta: model = Unload fields = '__all__' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['fieldContract'].queryset = FieldContract.objects.filter(applicativeContract__contract__is_active=True).order_by('applicativeContract__contract__internal_code', 'applicativeContract__internal_code', 'internal_code') self.fields['product'].queryset = Product.objects.all().order_by('name')
class BaseUnloadFormset(BaseModelFormSet): def clean(self): super().clean() for form in self.forms: cd = form.cleaned_data whouse = cd['whouse'] company = cd['company'] product = cd['product'] quantity = cd['quantity'] movement_date = cd['movement_date'] helper = StockHelper(product, whouse, company, movement_date) if quantity > helper.stock: raise ValidationError(f'Attenzione quantità massima disponibile di {product}: {helper.stock}') return cd
UnloadFormSet = modelformset_factory( model = Unload, fields = '__all__', extra = 5, form = UnloadForm, formset=BaseUnloadFormset )
class UnloadFormSetHelper(FormHelper): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_tag = False self.layout = Layout( Row( 'whouse', 'fieldContract', 'company', 'product', 'quantity', 'movement_date', ) ) self.render_required_fields = True
the problem occurs, when I’ve added the clean method in the BaseUnloadFormset.
Since all fields in the model are required, for example not stating the movement_date would prompt a front-end validation.
Unfortunately, although the source code of the web page shows that the field is actually required, forgetting the movement_date would send the form to the back-end and eventually the system would crash since there is no movement_date in the cleaned_data dictonary, thus raising a KeyError.
I tried to follow the Docs for overrinding the clean method:
https://docs.djangoproject.com/en/3.2/topics/forms/modelforms/#overriding-clean-on-a-modelformset
Removing the clean method in the form, would restore the correct behavior.
just in case it could be help full, this is my view:
def unload(request): helper = UnloadFormSetHelper() context = { 'helper': helper, 'title': 'Nuovo SCarico', } if request.method == 'GET': formset = UnloadFormSet(queryset=Unload.objects.none()) load_user_companies_in_formset(request, formset) context['formset'] = formset elif request.method == 'POST': formset = UnloadFormSet(request.POST) context['formset'] = formset load_user_companies_in_formset(request, formset) if formset.is_valid(): formset.save() messages.success(request, 'Scarico salvato correttamente', fail_silently=True) return HttpResponseRedirect(reverse('warehouse:dashboard')) else: return render(request, 'warehouse/unload.html', context) return render(request, 'warehouse/unload.html', context)
I looked for help on other forums but I got no replies. Although it’s a minor thing, since the users know about this already, still it’s not how it is supposed to work and I would like to correct it.
Thank you very much for any tip.