我可以将Django F()对象与字符串连接一起使用吗?
我想通过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_name
和last_name
之间加一个空格),output_field=...
则是指定这个合并后字段的类型(我希望它是一个CharField
)。想了解更多,可以看看Django文档关于Concat的内容
46
发生的事情是,Django把'+'符号直接传给了SQL,但SQL不允许用'+'来连接字符串,所以它就尝试进行数字相加。如果你用一个整数代替字符串,那么它就能正常工作,因为它会把my_other_field
的整数值加到你的变量上。
这是否算是一个bug还有争议。关于查找查询中F()
对象的文档中提到:
Django支持使用
F()
对象进行加法、减法、乘法、除法和取模运算
所以可以说,你不应该用它来更新字符串。不过,这一点在文档中并没有说明,而且错误信息'Incorrect DOUBLE value'也不是很有帮助。我会去提交一个问题。