django基于文本长度过滤

ash*_*ish 62 django

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

MyModel.objects.filter(len(text) > 10)
Run Code Online (Sandbox Code Playgroud)

其中text是MyModel模型中的Char或Text字段

hob*_*obs 159

对于Django> = 1.8,您可以使用Length函数,这是@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)
Run Code Online (Sandbox Code Playgroud)

  • @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) `. (3认同)

Pra*_*ush 56

另一种方式是:

MyModel.objects.extra(where=["CHAR_LENGTH(text) > 300"])
Run Code Online (Sandbox Code Playgroud)

这可以在文本长度超过255个字符的地方使用.

  • 如果你有sqlite,那就是`LENGTH(..)`. (4认同)

Iai*_*ton 27

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

MyModel.objects.filter(text__regex = r'.{10}.*')
Run Code Online (Sandbox Code Playgroud)

警告:对于MySQL,最大长度值为255.否则抛出异常:

DatabaseError: (1139, "Got error 'invalid repetition count(s)' from regexp")
Run Code Online (Sandbox Code Playgroud)

  • 正如[文档](https://docs.djangoproject.com/en/dev/ref/models/querysets/#regex)所说:`使用原始字符串(例如,r'foo'而不是'foo')传入建议使用正则表达式语法 (2认同)
  • @ emil-stenstrom实际上是255 (2认同)

hyn*_*cer 21

为一个很好的解决方案的Django> = 1.9通过是可能的注册的内建函数Length作为变换CharField查找.(在文档中查看与作为转换的长度完全相同的示例)

from django.db.models import CharField
from django.db.models.functions import Length

CharField.register_lookup(Length, 'length')
Run Code Online (Sandbox Code Playgroud)

它适用于所有后端,由LENGTH()大多数后端和CHAR_LENGTH()MySQL 编译.然后,它会自动为CharField的所有子类注册,例如,用于EmailField.将TextField必须单独注册.注册名称"length"是安全的,因为变换名称永远不会被同名的字段名称或相关字段名称着色或加阴影.

唯一的缺点可能是可读性难题:"长度"来自何处?(查找是全局的,但是如果在可读性方面有用,可以在更多模块中重复安全地重复注册,在查询运行时没有任何可能的开销.)

其他类似的有价值的解决方案是如果注册计数并且如果不重复使用类似的查询则上面的滚刀更短.


ran*_*lan -20

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

例如

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`
Run Code Online (Sandbox Code Playgroud)

  • @ashish我在上面代码的最后一行添加了注释。我们向模型添加一列来存储“文本”的长度。每次修改文本时都会更新。因此,当我们查询模型时,我们可以按文本长度进行过滤,我们已经在“保存”方法中预先计算了文本长度。 (2认同)