Django Model formset is partially working
I have normally just a simple question but I can't get it working. I have a view where customers can add, delete or edit their addresses.
view.py:
customer_addresses = CustomerAddresses.objects.filter(CustomerID=customer)
AddressFormSet = modelformset_factory(CustomerAddresses, form=CustomerAddressesForm, extra=0)
formset = AddressFormSet(queryset=customer_addresses, form_kwargs={'user': User.ID})
if request.method == 'POST':
if 'add_address' in request.POST:
add_address_form = CustomerAddressesForm(User.ID, request.POST)
if add_address_form.is_valid():
add_address_form.save()
if 'edit_address' in request.POST:
address_id = request.POST.get('id_Address')
address_data = CustomerAddresses.objects.get(pk=address_id)
edit_address_form = AddressFormSet(request.POST, queryset=customer_addresses, form_kwargs={'user': User.ID})
print('ERROR', edit_address_form.errors)
messages.error(request, 'ERROR')
if edit_address_form.is_valid():
instances = edit_address_form.save(commit=False)
for instance in instances:
instance.save()
return redirect('addresses')
if 'delete_customer_address_id' in request.POST:
delete_customer_address_id = request.POST.get('delete_customer_address_id')
request.session['delete_customer_address_id'] = delete_customer_address_id
return redirect('delete-customer-address')
if 'register_customer' in request.POST:
register_form = CustomerAddressesForm(user=user_id)
if register_form.is_valid():
customer = register_form.save(commit=False)
customer.UserID = user_id
customer.save()
# You can redirect to a success page or login the user directly
redirect(request.META.get('HTTP_REFERER'))
else:
add_address_form = CustomerAddressesForm(user=User.ID)
and my form:
class CustomerAddressesForm(forms.ModelForm):
Title = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control mb-3', 'autofocus': True}),
required=False)
Address_Firstname = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}))
Address_Lastname = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}))
Zip = forms.IntegerField(
widget=forms.TextInput(attrs={'class': 'form-control', 'maxlength': '5', 'data-toggle': 'maxlength'}),
label='Postnummer')
City = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}))
Address_Company = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}),
required=False)
Street = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}), required=False)
Country = forms.ModelChoiceField(widget=forms.Select(attrs={'class': 'form-select'}),
queryset=CountryList.objects.values_list('countryname', flat=True).order_by(
'code'), initial='Denmark', to_field_name='countryname')
Is_Default_Shipping_address = forms.BooleanField(
widget=forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': 'customSwitch4'}), initial=False,
required=False)
Is_Default_Billing_address = forms.BooleanField(
widget=forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': 'customSwitch3'}), initial=False,
required=False)
class Meta:
model = CustomerAddresses
fields = ['Title', 'Address_Firstname', 'Address_Lastname', 'Zip', 'City', 'Address_Company', 'Country',
'Is_Default_Shipping_address', 'Is_Default_Billing_address', 'Address_CustomerSalutation',
'CustomerID', 'Street']
def __init__(self, user, *args, **kwargs):
super(CustomerAddressesForm, self).__init__(*args, **kwargs)
self.fields['Address_CustomerSalutation'] = forms.ModelChoiceField(
widget=forms.Select(attrs={'class': 'form-select mb-3'}),
queryset=Salutation.objects.filter(UserID_id=user), empty_label=None)
so the forms are generating, and I can open the edit_customer_form, the values are filled in because query set. But if I click on save, the form is posting, its hopping in the right loop: if 'edit_address' in request.POST: but I got the output from: print('ERROR', edit_address_form.errors)
that all fields are required and there are no inputs given. That is strange.
The HTML forms looks like:
<input type="text" name="form-0-Address_Firstname" value="Christopher" class="form-control" autofocus="" id="id_form-0-Address_Firstname">
The error says:
ERROR [{'CustomerID': ['Dette felt er påkrævet.'], 'ID': ['Dette felt er påkrævet.']}, {'Address_Firstname': ['Dette felt er påkrævet.'],
In my eyes the field name is different to the value given by the prefix, which is necessary. But how can I save the form and give the values to the form.
regards Christopher.
I found the the problem, it was a misunderstand, I created for every instance a own <form>
tag, this was not working because
{{ formset.management_form }}
have to be in the form for all formsets.
I tried also
{{ form.instance.management_form }}
and
{{ form.management_form }}
in the {% for form in formset %}
loop, but it was not working. I also excluded the CustomerID field because it will not be changed by the customer or the admin.