Могу ли я использовать объекты Django F() с конкатенацией строк?
Я хочу запустить обновление django через ORM, который выглядит примерно так:
MyModel.objects.filter(**kwargs).update(my_field=F('my_other_field')+'a string')
Это заставляет MySQL вызывать исключение. Есть ли способ сделать это без написания исходного SQL?
Ответы
Ответ 1
Что происходит в том, что Django передает "+" через SQL, но SQL не позволяет использовать "+" для конкатенации, поэтому он пытается добавить численно. Если вы используете целое число вместо "строки", оно работает в том смысле, что оно добавляет целочисленное значение my_other_field
к вашей переменной.
это Это спорно ли ошибка. Документация для объектов F()
в запросах поиска утверждает:
Django поддерживает использование сложения, вычитания, умножения, деления и по модулю арифметики с объектами F()
поэтому можно утверждать, что вы не должны пытаться использовать его для обновления со строками. Но это, безусловно, не задокументировано, и сообщение об ошибке "Неверное значение DOUBLE" не очень полезно. Я открою билет.
Ответ 2
У меня была аналогичная проблема; в основном я хотел объединить два поля, чтобы получить полное имя пользователя. Я решил его решить (но должен сказать, что использовал Postgres):
from django.db.models.functions import Concat
from django.db.models import F, Value, CharField
AnyModel.objects.filter(**kwargs).annotate(full_name=Concat(F('model__user_first_name'), Value(' '), F('model__user_last_name'), output_field=CharField()))
где F ('...') оценивает свой аргумент как запрос, поэтому вы можете запросить поле самой модели или разброс по всем моделям, как это было бы в файле filter/get, а Value ('...) оценивает свой аргумент буквально (в моем случае мне нужно пространство, которое должно быть помещено между first_name и last_name), а output_field =... определяет тип аннотированного поля (я хотел быть CharField).
Для получения дополнительной информации вы можете прочитать Django docs about Concat
Надеюсь, что это будет полезно для кого-то там. Приветствия
Ответ 3
Вы можете использовать функцию Concat https://docs.djangoproject.com/en/1.9/ref/models/database-functions/#concat
from django.db.models.functions import Concat
from django.db.models import Value
MyModel.objects.filter(**kwargs).update(my_field=Concat('my_other_field', Value('a string'))