Hol*_*lly 16 python django django-orm
我正在尝试更新和修改字符串字段Django的ORM.执行此操作的等效SQL是:
UPDATE example_table SET string_field = REPLACE(string_field, 'old text', 'new text');
Run Code Online (Sandbox Code Playgroud)
随着该查询,我希望old text和old text more text对被替换new text,并new text more text分别在所有条目string_field列.
批量更新()似乎很有希望,但不允许我只修改字段的一部分,而F()表达式只实现数字更改,而不是字符串替换.我还看了使用原始查询来运行上面的SQL,但这似乎是一个横向黑客(特别是因为F()存在以对数字执行相同的功能),我无法让它们实际执行.
我最终得到了这个,但是当我知道有一行SQL语句来执行所有额外的查询时,这似乎是一种耻辱.
for entry in ExampleModel.objects.all():
entry.string_field = entry.string_field.replace('old text', 'new text', 1)
entry.save()
Run Code Online (Sandbox Code Playgroud)
这个功能在Django的ORM中不存在用于字符串吗?我在文档中忽略了什么吗?
相关的SO问题:
Tri*_*Nhu 23
用django 1.9测试
from django.db.models import F, Func, Value
ExampleModel.objects.filter(<condition>).update(
string_field=Func(
F('string_field'),
Value('old text'), Value('new text'),
function='replace',
)
)
Run Code Online (Sandbox Code Playgroud)
您可以创建自己F的对象来表示SQL中的字符串替换.这是一个概念证明:
from django.db.models.expressions import ExpressionNode
class StringReplaceF(ExpressionNode):
def __init__(self, field, replace_from, replace_to):
self.field = field
self.replace_from = replace_from
self.replace_to = replace_to
super(StringReplaceF, self).__init__()
def evaluate(self, evaluator, qn, connection):
return (
"REPLACE({}, %s, %s)".format(self.field),
(self.replace_from, self.replace_to)
)
>>> f = StringReplaceF('string_field', 'old text', 'new text')
>>> ExampleModel.objects.update(string_field=f)
Run Code Online (Sandbox Code Playgroud)
如果你需要它与其他F对象表现得很好,你需要对该类做更多的工作,但是再一次,现有的F对象似乎无法使用字符串.