我可以将Django F()对象与字符串连接一起使用吗?

76 投票
3 回答
35667 浏览
提问于 2025-04-16 01:38

我想通过ORM在Django中执行一个更新操作,代码大概是这样的:

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

但是这样会导致MySQL出现错误。有办法不写原始SQL语句就做到这一点吗?

3 个回答

43

你可以使用 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'))
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('...')的意思是把它里面的内容当作查询来处理,所以你可以查询模型本身的字段,或者像在filter/get中那样跨模型查询。而Value('...')则是把里面的内容当作字面意思来处理(在我的例子中,我需要在first_namelast_name之间加一个空格),output_field=...则是指定这个合并后字段的类型(我希望它是一个CharField)。想了解更多,可以看看Django文档关于Concat的内容

46

发生的事情是,Django把'+'符号直接传给了SQL,但SQL不允许用'+'来连接字符串,所以它就尝试进行数字相加。如果你用一个整数代替字符串,那么它就能正常工作,因为它会把my_other_field的整数值加到你的变量上。

这是否算是一个bug还有争议。关于查找查询中F()对象的文档中提到:

Django支持使用F()对象进行加法、减法、乘法、除法和取模运算

所以可以说,你不应该用它来更新字符串。不过,这一点在文档中并没有说明,而且错误信息'Incorrect DOUBLE value'也不是很有帮助。我会去提交一个问题。

撰写回答