web-dev-qa-db-ja.com

Djangoでは、動的フィールド検索でQuerySetをどのようにフィルタリングしますか?

クラスが与えられた場合:

from Django.db import models

class Person(models.Model):
    name = models.CharField(max_length=20)

動的な引数に基づいてフィルタリングするQuerySetを使用することは可能ですか?例えば:

 # Instead of:
 Person.objects.filter(name__startswith='B')
 # ... and:
 Person.objects.filter(name__endswith='B')

 # ... is there some way, given:
 filter_by = '{0}__{1}'.format('name', 'startswith')
 filter_value = 'B'

 # ... that you can run the equivalent of this?
 Person.objects.filter(filter_by=filter_value)
 # ... which will throw an exception, since `filter_by` is not
 # an attribute of `Person`.
147
Brian M. Hunt

Pythonの引数展開を使用して、この問題を解決できます。

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}

Person.objects.filter(**kwargs)

これは非常に一般的で便利なPythonイディオム。

282
Daniel Naab

簡単な例:

Django=調査アプリでは、登録ユーザーを表示するHTML選択リストが必要でした。ただし、登録ユーザーは5000人であるため、クエリ条件(人など)調査要素を再利用できるようにするには、調査質問を作成する人がその質問にそれらの基準を付けることができるようにする必要がありました(クエリをハードコーディングしないでください)アプリ)。

私が思いついた解決策は100%ユーザーフレンドリーではありません(クエリを作成するには技術者の助けが必要です)が、それは問題を解決します。質問を作成するとき、編集者は辞書をカスタムフィールドに入力できます。例:

{'is_staff':True,'last_name__startswith':'A',}

その文字列はデータベースに保存されます。ビューコードでは、self.question.custom_query。その値は、辞書のようなlooksの文字列です。 eval()を使用してreal辞書に戻し、** kwargsを使用してクエリセットに挿入します。

kwargs = eval(self.question.custom_query)
user_list = User.objects.filter(**kwargs).order_by("last_name")   
6
shacker

Django.db.models.Q は、Djangoの方法で望み通りです。

5
Brent81