Функция 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()))

Все еще получаем ту же ошибку, что и раньше

Вернуться на верх