1

I am building a form which has a nested model formset for holding multiple addresses for a subscriber. I want to specify dropdown for region and city fields. So I added widgets property to the formset definition.

AddressFormSet = modelformset_factory(
    Address,
    fields = (
        'country', 
        'region', 
        'city', 
        'locality'
    ),
    widgets = {
       'region': Select(), 
       'city': Select()
    },
    extra=0
)

This is working fine and am able to select the value in the dropdown and save it to the database. When I come to the subscriber_edit page again, I see that the fields region and city are empty.

This is the Address model.

class Address(models.Model):
    subscriber = models.ForeignKey(SubscriberProfile, on_delete=models.CASCADE, related_name='address')
    locality = models.CharField(max_length=100, blank=True, verbose_name="Locality")
    city = models.CharField(max_length=40, verbose_name="City")
    region = models.CharField(max_length=40, verbose_name="State")
    country = models.CharField(max_length=200, verbose_name="Country")

This is the subscriber_edit view.

def subscriber_edit(request, slug):
    _subscriber = get_object_or_404(SubscriberProfile, slug=slug)
    _address = Address.objects.filter(subscriber=_subscriber).all()

    if request.method == 'POST':
        subscriber_form = SubscriberForm(data=request.POST, instance=_subscriber, prefix='s')
        addr_fmset = AddressFormSet(data=request.POST, prefix='addr')

        if all([subscriber_form.is_valid(), addr_fmset.is_valid()]):
            subscriber_form.save()

            for form in addr_fmset:
                addr = form.save(commit=False)
                addr.subscriber = sub
                addr.save()

            return redirect('subscriber_preview', slug=_subscriber.slug)

    else:
        subscriber_form = SubscriberForm(instance=_subscriber, prefix='s')
        addr_fmset = AddressFormSet(prefix='addr', queryset=_address)

    return render(request, 'main/subscriber_edit.html', {
        'sub_fm': subscriber_form,
        'addr_fmset': addr_fmset
    })

When I print(addr_fmset) in the view, I see that the values for region and city are empty.

<input type="hidden" name="addr-TOTAL_FORMS" value="1" id="id_addr-TOTAL_FORMS" /><input type="hidden" name="addr-INITIAL_FORMS" value="1" id="id_addr-INITIAL_FORMS" /><input type="hidden" name="addr-MIN_NUM_FORMS" value="0" id="id_addr-MIN_NUM_FORMS" /><input type="hidden" name="addr-MAX_NUM_FORMS" value="1000" id="id_addr-MAX_NUM_FORMS" />
<tr><th><label for="id_addr-0-country">Country:</label></th><td><input type="text" name="addr-0-country" value="India" maxlength="200" id="id_addr-0-country" /></td></tr>
<tr><th><label for="id_addr-0-region">State:</label></th><td><select name="addr-0-region" maxlength="40" id="id_addr-0-region"></select></td></tr>
<tr><th><label for="id_addr-0-city">City:</label></th><td><select name="addr-0-city" maxlength="40" id="id_addr-0-city"></select></td></tr>
<tr><th><label for="id_addr-0-locality">Locality:</label></th><td><input type="text" name="addr-0-locality" value="Madhapur" maxlength="100" id="id_addr-0-locality" /></td></tr>

So how do I specify the select widget for a field in a formset?

Animesh
  • 4,926
  • 14
  • 68
  • 110

0 Answers0