97

テキストの長さに基づいてモデルをフィルタリングしたい

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

ここで、textはMyModelモデルのCharまたはTextフィールドです。

4

6 に答える 6

263

Django> = 1.8の場合、長さ関数CHAR_LENGTH()を使用できます。これは、MySQLまたはLENGTH()その他のデータベースの内部で@Pratyushの内部にあります。

from django.db.models.functions import Length
qs = MyModel.objects.annotate(text_len=Length('text_field_name')).filter(
    text_len__gt=10)
于 2016-01-06T18:20:34.380 に答える
63

別の方法は次のとおりです。

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

これは、テキストの長さが255文字を超える場合にも使用できます。

于 2013-10-10T12:54:36.137 に答える
54

組み込み関数をルックアップの変換Lengthとして登録することで、Django>=1.9の優れたソリューションが可能になります。CharField

プロジェクトに変換を一度登録します。(最適な場所はおそらく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()ほとんどのバックエンドとCHAR_LENGTH()MySQLによってコンパイルされたすべてのバックエンドで正しく機能します。その後、CharFieldのすべてのサブクラス(EmailFieldなど)に自動的に登録されます。はTextField個別に登録する必要があります。トランスフォーム名は、同じ名前のフィールド名または関連するフィールド名によってシェーディングまたはシェーディングされることはないため、「length」という名前を登録しても安全です。

唯一の欠点は読みやすさのパズルかもしれません:「長さ」はどこから来たのですか?(ルックアップはグローバルですが、読みやすさのために役立つ場合は、クエリの実行時にオーバーヘッドが発生することなく、幸運にも同じものをより多くのモジュールに繰り返し安全に登録できます。)

他の同様に価値のある解決策は、登録が重要であり、同様のクエリが繰り返し使用されない場合に短くなる上記のホブです。

于 2017-07-23T00:45:33.730 に答える
32

正規表現フィルターを使用して、特定の長さのテキストを検索できます。

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

警告:MySQLの場合、最大長の値は255です。それ以外の場合は、例外がスローされます。

DatabaseError: (1139, "Got error 'invalid repetition count(s)' from regexp")
于 2012-09-07T09:03:09.363 に答える
-6

私はあなたのアプリサーバーの問題を解決し、あなたのデータベースに負担をかけません。これは次の方法で実行できます。

models_less_than_ten = []
mymodel = MyModel.objects.all()
for m in mymodel:
    if len(m.text) > 10:
          models_less_than_ten.append(m)
于 2017-09-28T15:07:54.923 に答える
-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`
于 2012-10-06T00:57:31.613 に答える