我可以使用带有字符串连接的 Django F() 对象吗?

问题描述 投票:0回答:3

我想通过 ORM 运行 django 更新,如下所示:

MyModel.objects.filter(**kwargs).update(my_field=F('my_other_field')+'a string')

这会导致 MySQL 抛出异常。有没有办法在不编写原始 SQL 的情况下完成此操作?

python mysql django
3个回答
163
投票

我也有类似的问题;基本上我想连接两个字段来获取用户的全名。我用这种方法解决了这个问题(但必须说我使用的是 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('...')
将其参数作为查询进行评估,因此您可以查询模型本身的字段,或者像在过滤器/获取中那样跨越模型,而
Value('...')
按字面意思评估其参数(在我的情况下,我需要在
first_name
last_name
之间放置一个空格),并且
output_field=...
指定注释字段的类型(我想成为
CharField
)。 有关更多信息,您可以阅读有关 Concat 的 Django 文档


46
投票

发生的情况是 Django 将“+”传递给 SQL - 但 SQL 不允许使用“+”进行连接,因此它尝试进行数字相加。如果您使用整数代替“字符串”,它确实可以将

my_other_field
的整数值添加到您的变量中。

这是否是一个错误还有争议。查找查询中F()

对象
文档指出:

Django 支持对

F()
对象使用加法、减法、乘法、除法和模运算

因此可能有人认为您不应该尝试使用它来更新字符串。但这肯定没有记录,并且错误消息“不正确的 DOUBLE 值”并不是很有帮助。我去开票。


43
投票

您可以使用Concat函数https://docs.djangoproject.com/en/stable/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'))
© www.soinside.com 2019 - 2024. All rights reserved.