POST form with init value

Hi,

I’ve a form with init value. The rendering is good. But when I submit the post request, is_valid() return false with the following error.

The rendering:

<ul class="errorlist"><li>locality<ul class="errorlist"><li>This field is required.</li></ul></li></ul>

In the html, the locality field has a choice selected. I dont understand.

The form :

class CivicAddressForm(forms.ModelForm):
    class Meta:
        model = CivicAdresse

        fields = [
            'civic_number',
            'route',
            'locality',
            'administrative_area_level_3',
            'administrative_area_level_2',
            'administrative_area_level_1',
            'country',
            'postal_code',
            
        ]
        ## LABELS WIDGET HELP_TEXT ##
        labels = {
            'civic_number': 'No. Porte',
            'route': 'Nom de rue',
            'locality': 'Municipalité',
            'administrative_area_level_3':'MRC',
            'administrative_area_level_2':'Région administrative',
            'administrative_area_level_1':'Province',
            'country': 'Pays',
            'postal_code': 'Code postale'
            
             

        }

    def __init__(self,loggedin_user, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        super(CivicAddressForm, self).__init__(*args, **kwargs)  
        self.fields['locality'].queryset = Ville.objects.filter(pk = loggedin_user.ville.id)
        self.fields['locality'].initial = Ville.objects.get(pk = loggedin_user.ville.id)
        # self.fields['locality'].empty_label = None
        self.fields['locality'].widget.attrs['disabled'] = 'true'

        self.fields['administrative_area_level_3'].initial = loggedin_user.ville.service_adresse.administrative_area_level_3
        # self.fields['administrative_area_level_3'].widget = HiddenInput()
        self.fields['administrative_area_level_2'].initial = loggedin_user.ville.service_adresse.administrative_area_level_2
        # self.fields['administrative_area_level_2'].widget = HiddenInput()
        self.fields['administrative_area_level_1'].initial = loggedin_user.ville.service_adresse.administrative_area_level_1
        # self.fields['administrative_area_level_1'].widget = HiddenInput()

        self.fields['country'].initial = loggedin_user.ville.service_adresse.country
        # self.fields['country'].widget = HiddenInput()

the models:

class Adresse(models.Model):
    civic_number = models.CharField(max_length=8, blank=False) #Numero de porte
    route = models.CharField(max_length=45, blank=False)  #Rue
    sublocality_level_1 = models.CharField(max_length=45, blank=True)
    # locality = models.ForeignKey(Ville, on_delete=models.CASCADE)
    administrative_area_level_3 = models.CharField(max_length=75, blank=False)
    administrative_area_level_2 = models.CharField(max_length=75, blank=False)
    administrative_area_level_1 = models.CharField(max_length=75, blank=False)
    country = models.IntegerField(default=CountryChoice.CANADA, choices=CountryChoice)
    postal_code = models.CharField(max_length=7)

    def __str__(self):
        return str(self.civic_number) + " "+ self.route + ", " + self.postal_code +", "+ self.administrative_area_level_1

Sub-model :

class CivicAdresse(Adresse):
    locality = models.ForeignKey(Ville, on_delete=models.CASCADE)


    def __str__(self):
        return str(self.civic_number) + " "+ self.route + ", " + self.locality.name +", "+ self.administrative_area_level_1

Can anyone help me, I can publish additional code if required.

UPDATE 1:

It pointed out the problem come from :

self.fields['locality'].widget.attrs['disabled'] = 'true'

Anyone know why ?

Update 2:
from stackoverflow : Django modelform field how to make disabled and prevent tampering? - Stack Overflow

Quoting from the docs at: HTML attribute: disabled - HTML: HyperText Markup Language | MDN

The Boolean disabled attribute, when present, makes the element not mutable, focusable, or even submitted with the form.

(Emphasis added.)

The data for that field does not get submitted back with the form.

Hi Ken,

Thank you for your fast-tracking. There is no way to make it grayed but submitted ?

Not in the way that I think you want it to be.

But it doesn’t need to be submitted if it can’t be changed. Make it an optional field in the form.

If you’re updating an existing model, you want to use the same model when binding the data on the submit. So if that value already exists, it will still be there. (And, defining a queryset on a disabled field doesn’t make any sense either, because nothing will ever be submitted.)

Great Idea,

thank you!