回答
这将是更好的和更快,如果你只是增加一列,预先计算(memoizes)的长度文本的 。
例如
class MyModel(models.Model):
text = models.TextField()
text_len = models.PositiveIntegerField()
def save(self, *args, **kwargs):
self.text_len = len(self.text)
return super(MyModel, self).save(*args, **kwargs)
MyModel.objects.filter(text_len__gt = 10) # Here text_len is pre-calculated by us on `save`
是因为文本字段没有编入索引并且每次计算文本长度查询到达数据库的时间。 lain建议的解决方案也是这样做的,不是吗(尽管这个解决方案对我来说并不合适)。 – ashish
@ashish 1)是的,它是预先计算的。 2)没有拉宁不这样做。 – rantanplan
1)所以如果长度是预先计算,那么为什么我需要另一列2)如果字符发生大于n,lain的解决方案不检查每个表达式? – ashish
您可以使用正则表达式过滤器来搜索特定长度的文本:
MyModel.objects.filter(text__regex = r'.{10}.*')
警告:为MySQL,最大长度为255,否则会抛出异常:
DatabaseError: (1139, "Got error 'invalid repetition count(s)' from regexp")
作为[文档](https://docs.djangoproject.com/en/dev/ref/models/querysets/#regex)说:'使用原始字符串(例如,r'foo'而不是'foo')来传递在正则表达式语法是建议。“# –
@goliney谢谢你,你是正确的。我编辑了我的答案。 –
我在执行代码 **后发现此异常** OperationalError:(1139,“从regexp得到错误'无效重复计数”)** 这是因为大括号。 – ashish
另一种方法是:
MyModel.objects.extra(where=["CHAR_LENGTH(text) > 300"])
这可以用在文本lenght过超过255个字符。
如果你有sqlite,它是'LENGTH(..)'。 –
Django的> = 1.8可以使用Length function,这是@ Pratyush的CHAR_LENGTH()
引擎盖为MySQL下,或LENGTH()
其他一些数据库:
from django.db.models.functions import Length
qs = MyModel.objects.annotate(text_len=Length('text_field_name')).filter(
text_len__gt=10)
假设我不想过滤查询集,而是首先返回对象'text_len__gt = 10'('order_by')。任何提示? – vabada
@dabad,你可以像使用任何其他数据库*字段*一样使用'text_len' *注解*,所以它可以在'order_by'或'Sum'或其他任何内容中使用。按照递减的文本长度顺序排序结果并返回长度值:'MyModel.objects.annotate(text_len = Length('text_field_name'))。order_by(' - text_len')。values_list('text_len',flat = True) '。 – hobs
@guettli一个被接受的答案的问题是,原始的海报已经在2015年9月上次被看到,并且您令人钦佩的利他主义是唯一的可能性:-)我必须先编辑这个答案,然后才可以上传。我添加了一个类似的[Django> = 1.9](https://stackoverflow.com/a/45260608/448474),它不需要注释,而是一个全局注册的“Length”变换。 – hynekcer
为Django的一个不错的解决办法> = 1.9可以通过注册内置函数Length
作为转换查找CharField
。 (见文档为Length as a transform完全相同的例子)
from django.db.models import CharField
from django.db.models.functions import Length
CharField.register_lookup(Length, 'length')
result = MyModel.objects.filter(text__length__gt=10)
它可以正确处理所有的后端,通过LENGTH()
大多数后端编译和CHAR_LENGTH()
为MySQL。然后它自动注册CharField的所有子类,例如为EmailField。 TextField
必须单独注册。注册名称“长度”是安全的,因为变换名称永远不会被同名的字段名称或相关字段名称遮蔽或遮蔽。
唯一的缺点可能是可读性难题:“长度”从哪里来? (查找是全球性的,但同样可以幸运地安全地在多个模块反复注册,如果可读性是有用的,而不会在查询运行任何可能的开销。)
其他类似的有价值的解决方案是hobs的上面是短如果注册计数并且不重复使用类似的查询。
我会解决您的应用程序服务器上的问题,而不是税收您的数据库。你可以这样做:
models_less_than_ten = []
mymodel = MyModel.objects.all()
for m in mymodel:
if len(m.text) > 10:
models_less_than_ten.append(m)
这对MyModel中的很多行不会很好地扩展。如果你有100,000行,那么对数据库执行strlen并决定不发送一行数据的话,会比向应用程序服务器发送大量数据以过滤掉更少。在db上完成这项工作几乎总是比较好的,如果它太慢或征税,查询可以优化。 – nevelis
- 1. Django的过滤器 - 根据过滤器
- 2. Django的过滤器
- 3. Django的过滤器
- 4. 过滤的过滤器在Django管理
- 5. 过滤器Django Queryset:ValueError
- 6. 过滤器通过在Django
- 7. django过滤器:可以过滤元组?
- 8. Django过滤器不按user_id过滤
- 9. Django的意见/过滤器
- 10. Django的过滤器对象
- 11. Django的:使用过滤器
- 12. Django的模板过滤器
- 13. Django的查询过滤器
- 14. Django的:从过滤器
- 15. Django的带过滤器
- 16. django过滤器的帮助
- 17. Django的过滤器“或”
- 18. django ManyToManyField的Queryset过滤器?
- 19. Django的:过滤器外键
- 20. Django过滤器循环或
- 21. Django objects.filter多个过滤器
- 22. Django:后续OR过滤器
- 23. Django过滤器查询
- 24. Django - 过滤器模型
- 25. django过滤器和更新
- 26. Django管理员过滤器
- 27. Django过滤器vs排除
- 28. Django过滤器推演ManyToMany
- 29. django queryset过滤器问题
- 30. Django“评估”过滤器?
使用https://docs.djangoproject.com/en/dev/ref/models/database-functions/#django.db.models.functions.Length功能。 – guettli