我想根据this和this文档从多个对象的'blog/'
字段中删除slug
子字符串:
>>> import re
>>> from django.db.models import F
>>> p = re.compile('blog/')
>>> Blog.objects.update(slug=p.sub('', F('slug')))
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: expected string or buffer
我尝试将str()
添加到最后一个字符串,并且它没有错误地传递:
>>> Blog.objects.update(slug=p.sub('', str(F('slug'))))
但它会将(DEFAULT: )
插入所有对象的slug
字段中。
有什么建议吗?
答案 0 :(得分:2)
你做不到。更新完全在数据库中完成,因此它必须是可以转换为SQL的东西,而代码则不是。您需要迭代并更新:
for blog in Blog.objects.filter(slug__startswith='blog/'):
blog.slug = blog.slug.replace('blog/', '')
blog.save()
答案 1 :(得分:2)
有些晚,但对于今天需要解决方案的人 注意:Django 2.1的新功能。
替换类
Documentation中的用法示例:
>>> from django.db.models import Value
>>> from django.db.models.functions import Replace
>>> Author.objects.create(name='Margaret Johnson')
>>> Author.objects.create(name='Margaret Smith')
>>> Author.objects.update(name=Replace('name', Value('Margaret'), Value('Margareth')))
2
>>> Author.objects.values('name')
<QuerySet [{'name': 'Margareth Johnson'}, {'name': 'Margareth Smith'}]>
答案 2 :(得分:2)
要在 Django 中使用正则表达式在查询集上一次更新多个对象,您可以使用 Func expression 访问数据库中的正则表达式函数:
django.db.models import F, Func, Value
pattern = Value(r'blog(/?)') # the regex
replacement = Value(r'new-blog-slug\1') # replacement string
flags = Value('g') # regex flags
Blog.objects.update(
slug=Func(
models.F('slug'),
pattern, replacement, flags,
function='REGEXP_REPLACE',
output_field=models.TextField(),
)
)
有关详细信息和特定功能支持,请查看您的数据库供应商文档。
在 r''
和 pattern
中使用原始字符串 replacement
以避免转义反斜杠。
使用 replacement
和 \n
从 1 到 9 引用 n
中匹配的子字符串。
您可以使用 F
表达式从每个实例的字段中提供 pattern
、replacement
和 flags
:
pattern = F('pattern_field')
replacement = F('replacement_field')
flags = F('flags_field')
您还可以使用 Func
表达式进行注释。
目前有一个 open pull request 用于在 Django 中添加正则表达式数据库功能。合并后,您可能会在 RegexpReplace
下使用 RegexpStrIndex
、RegexpSubstr
和 django.db.models.functions
函数表达式,以使您的代码更加简洁,并在数据库供应商之间使用统一的单一 API。>