Django - 按 CharField 值长度过滤查询集
Posted
技术标签:
【中文标题】Django - 按 CharField 值长度过滤查询集【英文标题】:Django - Filter queryset by CharField value length 【发布时间】:2014-06-14 14:17:21 【问题描述】:鉴于我有一个带有基于 CharField
或 CharField
的模型字段的旧模型,例如:
class MyModel(models.Model):
name = models.CharField(max_length=1024, ...)
...
我需要进行迁移以使其具有最大的max_length
。 255. 首先,我正在编写一个datamigration
以使任何超过 255 个字符的值适应即将到来的 schemamigration
以修复列的最大长度,我将在此工作之后立即执行此操作。
问题是我有一个非常非常大的数据集,我知道并非所有行都包含超过 255 个字符的 MyModel.name
值,我想考虑迁移只有那些这样做的人。
django ORM 有什么方法可以只过滤满足这个条件的对象吗?比如:
MyModel.objects.filter(name__len__gte=255)
会很棒,但我相信这是不可能的,或者至少不是这么简单。
有人知道完成这个查询的方法吗?
谢谢!
【问题讨论】:
django filter on the basis of text length 的可能重复项 【参考方案1】:'Recent' Django 版本有内置的django.db.models.functions.Length
查找/转换,所以你可以这样做:
MyModel.objects.annotate(length=Length('text')).filter(length__gt=254)
见https://docs.djangoproject.com/en/1.11/ref/models/database-functions/#length
旧答案:
我认为你必须选择:
在查询集上使用“额外”:
MyModel.objects.extra(where=["CHAR_LENGTH(text) > 254"])
或者滥用正则表达式查找,我假设这会更慢:
MyModel.objects.filter(text__regex = r'^.254.*')
【讨论】:
我正在使用 PostgreSQL,发现正则表达式可以挽救生命。 更新:使用 Django 1.7 custom lookups and transforms 很容易实现。因此,您可以实现完全符合test__length__gt=254
的转换,其中length
是您的自定义转换。
注意:在使用 extra 之前阅读此处的警告:docs.djangoproject.com/en/1.11/ref/models/querysets/#extra【参考方案2】:
如果您发现自己使用了很多额外的和正则表达式,按照@BBT 的建议,我继续执行转换,如下所示:
# utils.db
from django.db.models import Transform
from django.db.models import CharField
class CharacterLength(Transform):
lookup_name = 'len'
def as_sql(self, compiler, connection):
lhs, params = compiler.compile(self.lhs)
return "LENGTH(%s)" % lhs, params
CharField.register_lookup(CharacterLength)
此后,我可以对“mycolname”进行级联查找,如下所示:
from utils.db import *
queryset.filter(mycolname__len__gte=10)
【讨论】:
以上是关于Django - 按 CharField 值长度过滤查询集的主要内容,如果未能解决你的问题,请参考以下文章
如何按字母顺序对多对多 django-admin 框中的值进行排序?