I have an IntegerChoices
Genre
:
from django.db import models
# ...
class Genre(models.IntegerChoices):
fantasy = 0,
scifi = 1,
real = 2,
#...
and a book
model that uses an ArrayField
of PositiveSmallIntegerField
with Genre
as choices:
from django.contrib.postgre.fields import ArrayField
#...
class Book(models.Model):
#...
genres = ArrayField(models.PositiveSmallIntegerField(choices=Genre.choices), null=True, blank=True))
#...
When I try to filter by the genres
field using values from the Genre
choices I get an error that Django (or psycopg2) cannot cast an integer to a smallint:
# traceback
psycopg2.errors.CannotCoerce: cannot cast type integer to smallint[]
LINE 1: ..."book" WHERE "book"."genres" @> 1::smallint...
^
The above exception was the direct cause of the following exception:
# traceback
django.db.utils.ProgrammingError: cannot cast type integer to smallint[]
LINE 1: ..."book" WHERE "book"."genres" @> 1::smallint...
^
All of these attempts to filter trigger the above error:
genre = Genre.scifi
print(genre) # >>> 1
Book.objects.filter(genres__contains=genre) # error
Book.objects.filter(genres=genre) # error
However if I try to create a book
instance with the genre everything works.
book = Book.objects.create(
#...
genres=[genre]
) # no error
print(book.genres) # >>> [1]
Is the problem the PositiveSmallIntegerField
? I couldn't find any "SmallIntegerChoices" as a replacement for the IntegerChoices
.
Or is it the way the filtering is/should be done? I haven't had this issue before and by searching I haven't found anything that looks the same (some errors with migrations or other type casting, but nothing quite like this).
It does feel like a simple problem, but I can't find my way around it.
When you are querying the ArrayField, you need to provide an array of value(s), you can not simply pass the value itself, so in this case, the variable 'genre' you are passing should be an array of value like, [1] or [1, 2, 3] for multiple values. It should fix your problem.
Documentation of Querying in ArrayField for reference.