Djangofilter的基础上的文字长度
我想根据文本的长度来过滤我的模型
MyModel.objects.filter(len(text) > 10)
其中text是MyModel模型中的Char或Text字段
提前致谢
如果您只是添加一个预先计算(记忆)文本长度的列,那将会更好更快。
例如
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`
对于Django> = 1.8,您可以使用Length函数 ,即MySQL的引擎下的@ Pratyush的CHAR_LENGTH()
,或者其他一些数据库的LENGTH()
:
from django.db.models.functions import Length qs = MyModel.objects.annotate(text_len=Length('text_field_name')).filter( text_len__gt=10)
另一种方法是:
MyModel.objects.extra(where=["CHAR_LENGTH(text) > 300"])
这可以用于文本长度超过255个字符的地方。
您可以使用正则expression式filter来search特定长度的文本:
MyModel.objects.filter(text__regex = r'.{10}.*')
注意:对于MySQL,最大长度值是255.否则会引发exception:
DatabaseError: (1139, "Got error 'invalid repetition count(s)' from regexp")
Django> = 1.9的一个很好的解决scheme是通过注册内置函数Length
作为CharField
查找的转换 。 (请参阅长度文档中与转换相同的示例)
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()
编译,MySQL的CHAR_LENGTH()
编译。 然后自动注册CharField的所有子类,例如EmailField。 TextField
必须单独注册。 注册名称“length”是安全的,因为变换名称永远不会被同名的字段名称或相关的字段名称遮蔽或被阴影化。
唯一的缺点是可读性难题:“长度”从哪里来? (查找是全局的,但是如果在可读性方面有用,在查询运行时没有任何可能的开销,那么同样可以在更多模块中反复安全地注册。
其他类似的有价值的解决scheme是滚刀的上面,如果登记计数和如果一个类似的查询不重复使用, 则更短。
我会解决您的应用程序服务器上的问题,而不是税收你的数据库。 你可以这样做:
models_less_than_ten = [] mymodel = MyModel.objects.all() for m in mymodel: if len(m.text) > 10: models_less_than_ten.append(m)