基于文本长度的django过滤器

4c8rllxm  于 2023-04-13  发布在  Go
关注(0)|答案(6)|浏览(176)

我想根据文本的长度来过滤我的模型

MyModel.objects.filter(len(text) > 10)

其中text是MyModel模型中的字符或文本字段

wribegjk

wribegjk1#

对于现代Django(〉=1.9)@hynecker的answer is better
对于Django〉= 1.8,你可以使用 annotation 和Length函数:

from django.db.models.functions import Length
qs = MyModel.objects.annotate(text_len=Length('text_field_name')).filter(
    text_len__gt=10)

Django使用的是@Pratyush建议的CHAR_LENGTH() MariaDB(MySQL)函数。但是Django Length函数将适用于任何Django兼容的数据库,只需将LENGTH()用于Postgres和其他数据库。

cetgtptt

cetgtptt2#

另一种方式是:

MyModel.objects.extra(where=["CHAR_LENGTH(text) > 300"])

这也可以用于文本长度超过255个字符的情况。

ac1kyiln

ac1kyiln3#

Django〉= 1.9的一个很好的解决方案是将内置函数Length注册为CharField查找的Transform
在项目中注册一次转换。(最好的地方可能是models.py。)

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”是安全的,因为转换名称永远不会被同名字段名称或相关字段名称遮蔽。
唯一的缺点可能是可读性问题:“length”从何而来?(查找是全局的,但幸运的是,如果对可读性有用,可以在更多模块中安全地重复注册,而不会在查询运行时产生任何开销。
另一个类似的有价值的解决方案是上面的hobs,如果注册计数并且不重复使用类似的查询,则该解决方案更短。

piok6c0g

piok6c0g4#

您可以使用正则表达式过滤器来搜索特定长度的文本:

MyModel.objects.filter(text__regex = r'.{10}.*')

注意:对于MySQL,最大长度值为255。否则会抛出异常:

DatabaseError: (1139, "Got error 'invalid repetition count(s)' from regexp")
83qze16e

83qze16e5#

我会在你的应用服务器上解决这个问题,而不是对你的数据库征税。你可以通过以下方式做到这一点:

models_less_than_ten = []
mymodel = MyModel.objects.all()
for m in mymodel:
    if len(m.text) > 10:
          models_less_than_ten.append(m)
0sgqnhkj

0sgqnhkj6#

如果你只是添加一个预先计算(记忆)文本长度的列,那会更好,更快。
例如

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`

相关问题