When the field is readonly, it is excluded from Model.full_clean and so from Model.validate_constraints.
So the validation doesn’t occur django side, and it crash at DB side with IntegrityError.
The Form cannot validate any field which is not part of it, thus you need to find a way to add the field to the form and yet to prevent users from editing it, this may be achieved by a custom field which displays the value and adds an hidden input for it.
In the custom form this can be done by checking if the pseudo-readonly field is in form.changed_data, which means that someone is trying to tamper that value. This should raise a validation error.
Quite true - but if you’re already creating a custom form, you’re still better off not including that value at all. (Why create even the opportunity for mischief?)
Thanks for all your responses.
I’ve finally opted to override Model.full_clean so it enforce that fields from constraints can only be excluded altogether, or not excluded at all.