In Django admin interface, when submitting a form which has an optional integer field named “ordering”, I want to show a validation error message when user enters an incorrect type (string). However when user enters a string into this field and submits the form, Django recognizes it as an incorrect type and changes the value to None and successfully validates the form. Therefore there is no way to find out if the field was left blank or if the user entered incorrect type. Even when I tried to get clean data from custom form (clean_<field_name>) it always returns None. I also tried to do custom validator but no success with that either.
Is there a way to show a validation error for an optional field? Or can I somehow get the value that was actually entered into the field?
class ConditionForm(forms.ModelForm):
class Meta:
model = Condition
exclude = []
@admin.register(Condition)
class ConditionAdmin(admin.ModelAdmin):
def get_related_models(self, obj):
"""
Return all models that have 'one-to-many' relation to Condition model
"""
related_models = []
related_fields = obj._meta.get_fields()
for field in related_fields:
if field.is_relation and field.one_to_many:
related_model = field.related_model
related_models.append(related_model._meta.object_name.lower())
return related_models
def has_delete_permission(self, request, obj=None):
"""
Overwrite delete permission if object has relations
"""
if obj:
for related_model in self.get_related_models(obj):
if getattr(obj, f"{related_model}_set").exists():
messages.warning(request, f"Can't delete: {obj.common_name_en} - {obj.id}")
return False
return super().has_delete_permission(request, obj)
form = ConditionForm
fields = [field.name for field in Condition._meta.fields]
readonly_fields = ["id"]
This field is the one I can see as IntegerField and it has blank=True, null=True attributes which will save your data without giving you validation and sets None if given different type to this field. You can remove blank=True and then try to create new instance.
As I stated in the initial issue overview, I tried to do custom validation but with no success. The function which validates the input doesn’t run for some reason.
Here is my validator:
def validate_integer(value):
print("Inside validator ", value)
if not isinstance(value, int):
print("Inside validator condition ", value)
raise ValidationError("This field must be an integer.")
One thing I don’t understand is that, if you are using Django’s admin panel than the IntegerField i.e ordering will not accept any characters expect number as it’s input type will be number by default in admin panel. If you are not using Django’s admin panel than you can give your validation within form or view.
There might be some other issue as I’ve seen in my current projects I’ve these two fields
float = models.FloatField()
int = models.IntegerField()
and in admin I’m not able to enter any character in both fields except number values.
Is ordering field always a IntegerField or you have changed it to IntegerField, if so re-run the makemigrations and migrate commands
Also if this fields did not have blank=True, null=True you would have got the error This field is required as submitting the form will send the null values to the respective fields.
Because None value is sent to field and blank=True, null=True is set to field so it will not go to validator i.e validate_integer. Try to give number and you will see your print statement will be executed print("Inside validator", value).
Well there might be, if someone knows it better but on the other side why do you really want to build that much logic to Django admin site as official docs itself states The admin’s recommended use is limited to an organization’s internal management tool. It’s not intended for building your entire front end around.The Django admin site | Django documentation | Django.