Понимание ленивых кверисетов Django и их работы с заимствованием функций и приведением столбцов к целым числам
Я создал функцию, которую использую для применения фильтров, отправленных из фронтенда, для запроса к базе данных django. Я включаю ее в метод get_queryset различных ViewSet'ов.
Основная проблема возникает, когда я пытаюсь привести одно из полей моей модели к значению int, чтобы я мог применять к нему __gt-запросы. Поле может содержать обычные символьные строки и строковые представления целых чисел, но я могу легко фильтровать нецелые строки на основе другого поля. Я думал, что это позволит мне приводить каждый элемент в наборе запросов без получения ошибки "не является допустимым целым числом" при приведении поля. Но это не так, и я полагаю, что причина связана с ленивыми правилами заимствования функций queryset/queryset.
Пример набора представлений
def get_queryset(self):
queryset = MyModel.objects.all()
# ...
# ... other queries
# ...
filter_model = self.request.query_params.get('filter')
if filter_model:
queryset = apply_filter(queryset, filter_model)
return queryset
apply_filter
def apply_filter(queryset, filter_model):
for _filter in filter_model:
# filter models to ensure only instances with valid integer strings are in the queryset
field_qs = RelatedChildModel.objects.filter(data_field__name=_filter['name'])
# cast integer field
field_qs = field_qs.annotate("value_int"=Cast("value", output_field=IntegerField()))
# solely to double check that every instance in the queryset has cast an int successfully
for x in field_queryset:
print(isinstance(x.value_int, int)) # This is always True!
# apply __gt query to new cast column, return id's of parent models that match the query
field_qs = field_qs.filter(Q(**{"value_int__gt":_filter['value']})).values_list('my_model')
# Everything works as expected up until here.
# If i return from the function there is no error.
# However if I try to filter the original queryset with field_qs I get an error
queryset = queryset.filter(id__in=field_qs)
# throws error django.db.utils.DataError: invalid input syntax for type integer: "John Smith"
Это не имеет никакого смысла для меня. Я получаю ошибку, потому что по какой-то причине, если я пытаюсь изменить исходный кверисет с помощью кастомного кверисета, он действует так, как будто я написал строку:
field_qs = RelatedChildModel.objects.all()
вместо
field_qs = RelatedChildModel.objects.filter(data_field__name=_filter['name'])
Значит, он не отфильтровывает нецелые значения и пытается приводить экземпляры RelatedChildModel, где в поле value находится 'John Smith', а не действительное целое число.
Почему это может произойти? Переменная queryset является набором экземпляров MyModel. Переменная field_qs в итоге содержит только id экземпляров MyModel. Почему при попытке объединить два кверисета поля пытаются преобразовать в целые числа?
Я не могу найти способ заставить это работать