Django Forms - How can I update a form with a disabled required field?

I have a Django Model with one required field (shpid). I want to set this field to disabled when updating the form. Although the value of this field is shown and disabled when the template is first displayed I get a crispy-forms error saying 'this field is required' with the field showing empty when I try and update.

I'm using crispy-forms and FormHelper to style the page.

The relevant part of forms.py is:

class UpdateShpForm(ModelForm):

    class Meta:
        model = Shipment
        fields = '__all__'
        widgets = {
            "shpid": TextInput(attrs={'disabled':False,'style':'max-width:120px'}),  <=== Note diabled attribute
            "costs": TextInput(attrs={'style':'max-width:200px'}),
            "coldate": DateInput(attrs={'type': 'date','style':'max-width:180px'}),
            "deldate": DateInput(attrs={'type': 'date','style':'max-width:180px'}),
            "sts_date": DateInput(attrs={'type': 'date','style':'max-width:180px'}),

        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['shpid'].label = "Shipment ID"
        self.fields['awb'].label = "AWB"
        self.fields['pod'].label = "POD"
        self.fields['coldate'].label = "Collection Date"
        self.fields['deldate'].label = "Delivery Date"
        self.fields['recipient'].label = "Recipient"
        self.fields['status'].label = "Status"
        self.fields['sts_date'].label = "Status Date"
        self.fields['costs'].label = "Costs"

        self.helper = FormHelper()
        self.helper.layout = Layout(
            Row (
                Column('shpid',css_class='form-group col-md-3 mb-0 pe-4'),
                Column('status',css_class='form-group col-md-3 mb-0 ps-2 pe-2'),
                Column('sts_date', css_class='form-group col-md-3 mb-0 ps-4'),
            ),
            Row(
                Column('awb',css_class='form-group col-md-6 mb-0 pe-4'),
                Column('pod',css_class='form-group col-md-6 mb-0 pe-4'),
            ),
            Row(
                Column('coldate', css_class='form-group col-md-3 mb-0 pe-4'),
                Column('deldate', css_class='form-group col-md-3 mb-0 ps-2 pe-2'),
                Column('recipient', css_class='form-group col-md-3 mb-0'),
            ),
            Field('costs'),
           ButtonHolder(
                Submit('submit', 'Update Shipment', css_class='ms-5 px-3 fw-bold'),

               css_class='center'
            )
        )
        self.helper.form_class = 'form-horizontal'

The relevant part of views.py is:

def update_shipment(request,shpid,orderid):

    if shpid == 'None':
        ###  When called from a list this will be either 'None' or an existing shpid
        add_shipment(request,orderid)
        return render(request,'tracker/add_shipment.html', {'form':AddShpForm()})
    else:
        instance = Shipment.objects.get(shpid=shpid)
        shp_form = UpdateShpForm(request.POST or None, instance=instance)
        print('##########  Checking for Validity  ############')
        if shp_form.is_valid():
            print('========  Form is valid  ===============')
            shp_form.save()
            orders = Order.objects.all()
            messages.success(request,f'Shipment no: {shpid} has been updated')
            return render(request,'tracker/list_orders.html',{'orders':orders})
        else:
            return render(request,'tracker/update_shipment.html', {'form':shp_form, 'shpid':instance})

Currently I disable the shpid field with a (shpid) widget which works fine when the form is first displayed but gives an error when the form is saved, as crispy-forms has decided that it is empty.

How can I make a required field disabled without it causing a problem when trying to save the form styled with crispy-forms?

You can't disable a form input element (or "widget" here). I mean, you can but if you do it, it's value will be completely ignored. Instead, use readonly=True. This way, the value will actually be sent when you submit the form.

See the readonly attribute's page on MDN.

Вернуться на верх