[英]Django - Filter queryset by CharField value length
鉴于我有一个基于CharField
或CharField
的模型字段的遗留模型,如:
class MyModel(models.Model):
name = models.CharField(max_length=1024, ...)
...
我需要进行迁移才能使其max_length
为max。 255.首先,我正在编写一个数据datamigration
以使任何超过255个字符的值适应即将到来的模式schemamigration
以修复列的最大长度,我将在此工作后立即执行此操作。
问题是我有一个非常大的数据集,我知道并不是所有的行都包含超过255个字符的MyModel.name
,我想考虑我的迁移只有那些人。
是否有任何方法(使用)django ORM仅过滤满足此条件的对象? 就像是:
MyModel.objects.filter(name__len__gte=255)
会很棒,但我相信这是不可能的,或者至少它不是那么简单。
有人知道完成此查询的任何方法吗?
谢谢!
'最近'的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
老答案:
我想你必须选择:
在查询集上使用'extra':
MyModel.objects.extra(where=["CHAR_LENGTH(text) > 254"])
或者滥用正则表达式查找,我假设这会慢一些:
MyModel.objects.filter(text__regex = r'^.{254}.*')
如果你发现你使用了很多额外的正则表达式,按照@ 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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.