Функция Cast в Django возвращает DataError: invalid input syntax for type integer: "Джон"
У меня есть следующие модели, которые позволяют мне динамически создавать и отслеживать данные для контакта:
class DataField(models.Model):
name = models.CharField()
class Contact(models.Model):
created_on = models.DateTimeField()
class ContactField(moddels.Model):
contact = models.ForeignKey(Contact)
data_field= models.ForeignKey(DataField)
value = models.CharField()
Например, у меня есть две модели DataField с полем имени, установленным как "First Name" и "Loan Amount". Чтобы создать данные для контакта, я создаю два ContactFields, первое я связываю с полем данных "First Name" и присваиваю ему значение "John", второе я связываю с полем данных "Loan Amount" и присваиваю ему значение 5000. например:
ContactField(1)
contact = Contact(1)
data_field = DataField(First Name)
value = "John"
ContactField(2)
contact = Contact(1)
data_field = DataField(Loan Amount)
value = "5000"
Теперь я хочу запросить базу данных, чтобы вернуть Контакты, у которых сумма кредита больше X. Первая проблема заключается в том, что поле value должно быть целым полем, чтобы выполнить запрос greater than, но оно является CharField. Я не могу изменить его на целочисленное поле, потому что оно должно хранить как целые числа, так и строки (например, оно также хранит значение "John" для имени).
В результате я пытаюсь использовать функции annotate и cast из django для создания нового столбца "value_int" для запроса, чтобы я мог выполнять запросы типа "больше, чем":
# get all "Loan Amount" contact fields that exist
queryset = ContactField.objects.filter(data_field__name="Loan Amount")
# add a value_int field
value_int_queryset = queryset.annotate("value_int": Cast("value", output_field=IntegerField()))
# filter based on value_int field, only returning ids that match query
ids_matching= value_int_queryset.filter(value_int__gt=X).values_list('id')
# return contacts that the contact fields belong to:
contacts = Contact.objects.filter(contact_field__in=ids_matching)
Выдает django.db.utils.DataError: invalid input syntax for type integer: "John". Таким образом, несмотря на то, что в начале я фильтрую поля "Сумма кредита", Django все равно пытается отбросить и имена. Я думаю, это связано с тем, что django querysets ленив, поэтому он приводит значение int до (или в то же самое время), когда отфильтровывает поле первого имени.
Я попробовал заставить queryset оценивать целочисленный столбец до его приведения с помощью len() (как указано в документации django https://docs.djangoproject.com/en/4.0/ref/models/querysets/), но я по-прежнему получаю ту же ошибку:
# get all "Loan Amount" contact fields that exist
queryset = ContactField.objects.filter(data_field__name="Loan Amount")
len(queryset)
# add a value_int field
value_int_queryset = queryset.annotate("value_int": Cast("value", output_field=IntegerField()))
Итак, я немного запутался в том, как я могу предотвратить включение поля First Name ContactField в команду Cast. Даже если я пройдусь итерацией по полям контактов, я увижу, что все поля значений являются целыми числами, а Джон не включен:
# get all "Loan Amount" contact fields that exist
queryset = ContactField.objects.filter(data_field__name="Loan Amount")
len(queryset)
for field in queryset:
print(field.value) # only prints number based strings e,g 5000. John never shows up here
# add a value_int field
value_int_queryset = queryset.annotate("value_int": Cast("value", output_field=IntegerField()))
Все еще получаем ту же ошибку, что и раньше