Opened 2 months ago

Closed 2 months ago

#35454 closed Uncategorized (invalid)

ArrayField with default throwing a ValidationError on full_clean

Reported by: hfroot Owned by: nobody
Component: Database layer (models, ORM) Version: 5.0
Severity: Normal Keywords: full_clean, ArrayField, ValidationError
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I am attempting to add an ArrayField of IntegerFields to my model with a default value of list. I would expect the field to be populated with an empty list when the object is created, but when I call full_clean a ValidationError is thrown.

`
my_array_field = ArrayField(base_field=models.IntegerField(), default=list)
...
obj = MyObject.objects.create()
obj.full_clean()
`

The error I'm seeing is that the field cannot be empty:

`
django.core.exceptions.ValidationError: {'my_array_field': Ce champ ne peut pas être vide.}
`

I saw this ticket : https://forum.djangoproject.com/t/fields-with-db-default-fail-on-full-clean/28153 so I attempted to use db_default=list() and db_default=[] alone and in conjunction with default but none of it seems to work.

Is this a bug? Am I just defining the default wrong?

I can't see an example of defining the default in the docs, although it does mention it : https://docs.djangoproject.com/en/5.0/ref/contrib/postgres/fields/#django.contrib.postgres.fields.ArrayField.base_field

I'm on Django 5.0.3

Change History (2)

comment:1 by hfroot, 2 months ago

I fixed the issue by adding blank=True to the ArrayField definition. I see now in the docs

For both string-based and non-string-based fields, you will also need to set blank=True if you wish to permit empty values in forms, as the null parameter only affects database storage (see blank).

https://docs.djangoproject.com/en/5.0/ref/models/fields/#null

Maybe the docs for blank and the mention of setting default=list in the ArrayField docs could be updated? Given that there is a use case for not wanting a nullable array field, but wanting an empty array for later uses such as assuming you can treat the value stored in the field as an iterator without extra code :

MyRelatedObject.objects.filter(my_field__in=my_object.my_array_field)

Last edited 2 months ago by hfroot (previous) (diff)

comment:2 by Jacob Walls, 2 months ago

Resolution: invalid
Status: newclosed

The docs on the additional fields from django.contrib.postgres.fields I think (rightly) assume more basic knowledge about null, blank, and default, so I'm reluctant to suggest we re-document those basics on ArrayField.

I fixed the issue by adding blank=True to the ArrayField definition.

Glad you found the answer.

Note: See TracTickets for help on using tickets.
Back to Top