# Type validation on not required field

**URL:** <https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969>\
**Category:** The Admin\
**Created:** [September 19, 2023, 7:39am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969 "2023-09-19T07:39:51Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 7:39am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/1 "2023-09-19T07:39:51Z")

</div>

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?

Thank you for your help.

Here is the model:

```auto
class Condition(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    code = models.CharField()
    common_name_en = models.CharField()
    ordering = models.IntegerField(blank=True, null=True)
    common_name_cs = models.CharField()
    eval_time_frame = models.ForeignKey('ConditionEvalTime', models.DO_NOTHING, db_column='eval_time_frame')
    unit = models.CharField(blank=True, null=True)
    metric_extreme_low = models.FloatField(blank=True, null=True)
    metric_extreme_high = models.FloatField(blank=True, null=True)
    metric_scale = models.FloatField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'planner"."condition'

    def __str__ (self) -> str:
        return self.common_name_en

```

Here is my admin file:

```auto
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"]

```

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 8:20am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/2 "2023-09-19T08:20:20Z")

</div>

> [@danjirovec](#):
>
> ```auto
> ordering = models.IntegerField(blank=True, null=True)
> 
> ```

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.

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 8:35am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/3 "2023-09-19T08:35:52Z")

</div>

If I remove `blank=True` the field becomes required and that is not what I want.

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 9:41am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/4 "2023-09-19T09:41:03Z")

</div>

Okay, in that case see [Validators | Django documentation | Django](https://docs.djangoproject.com/en/4.2/ref/validators) this from official docs.

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 9:52am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/5 "2023-09-19T09:52:32Z")

</div>

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:

```auto
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.")

```

And the model again:

```auto
class Condition(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    code = models.CharField()
    common_name_en = models.CharField()
    ordering = models.IntegerField(blank=True, null=True, validators=[validate_integer])
    common_name_cs = models.CharField()
    eval_time_frame = models.ForeignKey('ConditionEvalTime', models.DO_NOTHING, db_column='eval_time_frame')
    unit = models.CharField(blank=True, null=True)
    metric_extreme_low = models.FloatField(blank=True, null=True)
    metric_extreme_high = models.FloatField(blank=True, null=True)
    metric_scale = models.FloatField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'planner"."condition'

    def __str__ (self) -> str:
        return self.common_name_en

```

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 10:03am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/6 "2023-09-19T10:03:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 10:17am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/7 "2023-09-19T10:17:59Z")

</div>

I am using the admin panel and it does accept string characters though:

 ![Screenshot 2023-09-19 at 12.16.58](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/6/4/6456de0404e5f39c6a5c50f7ef3665714d380725.png)

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 10:24am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/8 "2023-09-19T10:24:14Z")

</div>

There might be some other issue as I’ve seen in my current projects I’ve these two fields

```auto
    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

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 10:25am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/9 "2023-09-19T10:25:54Z")

</div>

I have rerun migrations couple times already, no change. 😕

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 10:29am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/10 "2023-09-19T10:29:04Z")

</div>

> [@danjirovec](#):
>
> ```auto
> metric_extreme_low = models.FloatField(blank=True, null=True)
> metric_extreme_high = models.FloatField(blank=True, null=True)
> metric_scale = models.FloatField(blank=True, null=True)
> 
> ```

This fields also accepting any characters or just number.

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 10:30am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/11 "2023-09-19T10:30:42Z")

</div>

Those fields also accept any character, just as the integer field and validation doesn’t work for those fields either.

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 10:41am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/12 "2023-09-19T10:41:13Z")

</div>

There might be some other issue, can you share your working environment like OS, Browser, etc

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 11:15am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/13 "2023-09-19T11:15:10Z")

</div>

MacOS Ventura 13.5.2 , currently in Firefox 117.0.1, Django 4.2.3 with PostgreSQL on the backend

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 11:25am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/14 "2023-09-19T11:25:37Z")

</div>

After trying it in Firefox it seems it is indeed accepting any characters so I’ve searched and found this [1466793 - Firefox allows you to write letters inside input type="number"](https://bugzilla.mozilla.org/show_bug.cgi?id=1466793) and [css - Input type="number" with pattern="[0-9]\*" allows letters in firefox - Stack Overflow](https://stackoverflow.com/questions/49923588/input-type-number-with-pattern-0-9-allows-letters-in-firefox#:~:text=Seems%20that%20Firefox%20doesn%27t%20restrict%20you%20from%20entering%20alphabetic%20characters%20into%20a%20number%20input%2C%20however%20it%20still%20will%20validate%20the%20input%20upon%20submitting%20your%20form%20as%20seen%20below.%20Note%20that%20both%20e%20and%20E%20are%20valid%20in%20numeric%20inputs).  
Try to use it in another browser, as stated in stackoverflow it still will validate the input upon submitting your form.

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 11:28am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/15 "2023-09-19T11:28:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 11:39am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/16 "2023-09-19T11:39:58Z")

</div>

It does indeed not let me input string chars in Chrome. Still don’t get why the validation doesn’t work though.

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 11:44am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/17 "2023-09-19T11:44:57Z")

</div>

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)`.

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 11:51am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/18 "2023-09-19T11:51:55Z")

</div>

Yes, the print does work when I enter a number. So I guess there is no way to show a validation error for a not required field then, right?

---

<div class="post-metadata">

**Author:** ![addwebsolution](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/addwebsolution/32/23762_2.png) [@addwebsolution](https://forum.djangoproject.com/u/addwebsolution)\
**Post date:** [September 19, 2023, 11:56am UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/19 "2023-09-19T11:56:23Z")

</div>

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](https://docs.djangoproject.com/en/4.2/ref/contrib/admin/#:~:text=The%20admin%E2%80%99s%20recommended%20use%20is%20limited%20to%20an%20organization%E2%80%99s%20internal%20management%20tool.%20It%E2%80%99s%20not%20intended%20for%20building%20your%20entire%20front%20end%20around).

---

<div class="post-metadata">

**Author:** ![danjirovec](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/danjirovec/32/16011_2.png) [@danjirovec](https://forum.djangoproject.com/u/danjirovec)\
**Post date:** [September 19, 2023, 12:02pm UTC](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969/20 "2023-09-19T12:02:36Z")

</div>

I know but it’s a requirement of my work ticket, that’s why I’m trying to figure it out. Thanks for your help though, appreciete it.

[Next page](https://forum.djangoproject.com/t/type-validation-on-not-required-field/23969.md?page=2)
