2

我想根据这个这个文档'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所有对象的字段中。

有什么建议么?

4

3 回答 3

3

要在 Django 中使用查询集上的正则表达式一次更新多个对象,您可以使用Func 表达式来访问数据库中的正则表达式函数:

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''patternand中使用原始字符串replacement以避免必须转义反斜杠。

replacement使用\nn1 到 9引用匹配的子字符串。

您可以使用F表达式来提供pattern,replacementflagsfrom 每个实例的字段:

pattern = F('pattern_field')
replacement = F('replacement_field')
flags = F('flags_field')

您还可以使用Func表达式进行注释。

目前有一个在 Django 中添加正则表达式数据库函数的开放拉取请求。合并后,您可能会拥有RegexpReplace,RegexpStrIndexRegexpSubstr函数表达式,django.db.models.functions以使您的代码更简洁,并拥有跨数据库供应商统一的单一 API。

于 2021-07-16T00:00:45.840 回答
2

你不能那样做。更新完全在数据库中完成,因此它必须是可转换为 SQL 的东西,而您的代码不能。您需要遍历和更新:

for blog in Blog.objects.filter(slug__startswith='blog/'):
    blog.slug = blog.slug.replace('blog/', '')
    blog.save()
于 2012-09-11T14:17:20.627 回答
1

有点晚了,但对于那些今天需要解决方案的人 注意:Django 2.1 中的新功能。

类替换

文档中的用法示例:

>>> 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'}]>
于 2020-04-06T01:27:23.940 回答