7

モデルに、誰かがメンバーシップをキャンセルしたかどうかを表すブール フィールドがあります。このフィールドをフィルタリングできるカスタム SimpleListFilter を作成しようとしています。

ただし、デフォルトでキャンセルされていない人だけを表示したいのです。デフォルトで「いいえ」オプションを選択する方法はありますか?これはこれまでの私のフィルターです:

class CanceledFilter(SimpleListFilter):

    title = 'Canceled'

    # Parameter for the filter that will be used in the URL query.
    parameter_name = 'canceled'

    def lookups(self, request, model_admin):
        return (
            (True, 'Yes'),
            (False, 'No'),
        )

    def queryset(self, request, queryset):

        if self.value() is True or self.value() is None:
            return queryset.filter(canceled=True)
        if self.value() is False:
            return queryset.filter(canceled=False)

編集:もう少し明確にする必要がありました。私は特に管理者インターフェースでこれをやろうとしています。上記のフィルターを管理者の list_filter として追加すると。管理ページの横にフィルターがあり、すべて、はい、いいえの 3 つの選択肢があります。

「いいえ」を選択するか、デフォルトで何も設定しないでください。代わりに、「すべて」の選択肢が常にデフォルトで設定されています。デフォルトのフィルター選択などを設定するためのハックではない方法はありますか。

基本的に、管理者がメンバーを表示するときに、デフォルトでアクティブな(キャンセルされていない)のみを表示したい. 「すべて」または「はい」をクリックすると、キャンセルされたものを表示したいと思います。

更新: これはDjango adminの質問 Default filter と同じであることに注意してください。ただし、その質問は現在 6 歳です。受け入れられた回答は、Django 1.4 を必要とするものとしてマークされています。その答えが新しい Django バージョンでも機能するのか、それとも最良の答えなのかはわかりません。

他の質問への回答が古くなっていることを考えると、どのように進めるべきかわかりません。両者を融合させる方法はないと思います。

4

3 に答える 3

8

同じことをしなければならず、あなたの質問に出くわしました。これが私のコードで修正した方法です(あなたの例に適応):

class CanceledFilter(SimpleListFilter):

    title = 'Canceled'

    # Parameter for the filter that will be used in the URL query.
    parameter_name = 'canceled'

    def lookups(self, request, model_admin):
        return (
            (2, 'All'),
            (1, 'Yes'),
            (0, 'No'),
        )

    def queryset(self, request, queryset):

        if self.value() is None:
            self.used_parameters[self.parameter_name] = 0
        else:
            self.used_parameters[self.parameter_name] = int(self.value())
        if self.value() == 2:
            return queryset
        return queryset.filter(cancelled=self.value())

若干の説明が必要です。クエリ文字列は URL の一部であり、まさにその名前が示すとおり、クエリ文字列です。値は、ブール値や整数としてではなく、文字列として取得されます。したがって、 を呼び出すと、文字列self.value()が返されます。

[はい/いいえ] をクリックして取得した URL を調べると、カスタム リスト フィルターを使用していない場合、True/False ではなく 1/0 としてエンコードされていることがわかります。私は同じ計画で行きました。

完全性と将来の読者のために、2 for All も追加しました。確認せずに、それはNone以前だったと思います。ただしNone、何も選択されていない場合にも使用されます。デフォルトは [すべて] です。ただし、この場合はデフォルトで にする必要がFalseあるため、別の値を選択する必要がありました。All オプションが必要ない場合は、メソッドの最後の if ブロックとquerysetメソッドの最初のタプルを削除するだけlookupsです。

それが邪魔にならないように、それはどのように機能しますか?self.value()トリックは、それが単に返されることを認識することです:

self.used_parameters.get(self.parameter_name, None)

Noneこれは、キーが辞書にあるかどうかに応じて、文字列または のいずれかになります。これが中心的な考え方です。文字列ではなく整数が含まれていることを確認してself.value()、 への呼び出しで使用できるようにしqueryset.filter()ます。2 である All の値の特別な処理: この場合、querysetフィルター処理されたクエリセットではなく、単に返されます。もう 1 つの特別な値は です。これは、ディクショナリにNoneキーがないことを意味します。parameter_nameその場合、値 0 で作成するため、それFalseがデフォルト値になります。

注:あなたのロジックは間違っていました。デフォルトで非キャンセルが必要ですがNone、 と同じように扱いますTrue。私のバージョンはこれを修正します。

ps: はい、メソッドで and ではなく and をチェックできますが、'True'タプル'False'True最初の要素が一致しないため、正しい選択が強調表示されないことに気付くでしょう (文字列をブール値と比較しています) )。タプル文字列の最初の要素も作成しようとしましたが、文字列比較を行うか、 に一致させる必要があり、これは醜い/安全ではありません。したがって、私の例のように、整数に固執するのが最善です。Falsequerystringeval'True'True

于 2014-11-28T17:47:55.717 に答える
-1

以下のリンクの「Adding Extra Manager Methods」というセクションを見てください。

http://www.djangobook.com/en/2.0/chapter10.html

モデルに追加の models.Manager を追加して、メンバーシップをキャンセルしていない人のみを返すことができます。追加の models.Manager の大まかな実装は次のようになります。

class MemberManager(models.Manager):
  def get_query_set(self):
    return super(MemberManager, self).get_query_set().filter(membership=True)

class Customer(models.Model):
  # fields in your model
  membership = BooleanField() # here you can set to default=True or default=False for when they sign up inside the brackets

  objects = models.Manager  # default Manager
  members = MemberManager() # Manager to filter for members only

現在のメンバーのみのリストを取得する必要がある場合はいつでも、次のように呼び出します。

Customer.members.all()
于 2013-09-04T01:39:11.443 に答える