6

私のモデルの多くは、「会社」モデルへの外部キーを持っています。ログインしているすべてのユーザーは、1 つ以上の会社に所属できます (User m2m Company、null 以外)。

現在の管理者ユーザーに、「現在の」会社を切り替えることができる管理者インデックス ページまたはベース ヘッダーの選択リストなど、「会社ゴーグル」をオンにしてもらいたいと思います。これを行うと、他のフィルターに加えて、Company への外部キーを持つモデルに対して、「company equals」フィルターが自動的に適用されます。

これを達成するための最良の方法は何ですか?

注意: これは管理インターフェイスの快適な機能として意図されています。この段階では、モデルを実際に保護する必要はありません (クライアント ビューには必要ですが、カスタム マネージャーを使用して、そこで request.user を介してルックアップすることができます)。

私の現在の考えは次のとおりです。

  1. 現在の会社をセッションに保存します。

  2. ミドルウェアを使用してセッションから現在の会社を検索し、関連するすべてのリンクに会社を追加します。

    a) change_list: (?/&)"company__eq=42"

    b) Company への外部キーを持つモデルの change_view "add?company=42"。

    これには、モデルを見つけて外部キーの存在を確認するために、URL を反転またはパターン マッチングする必要がある場合があります (または、パフォーマンスを向上させるために事前にそのリストを準備する場合があります)。

  3. 各 ModelAdmin フォームに外部キー フィールドを含めますが、CSS を介して非表示にします。これにより、change_view add ("new") はリンクから事前設定された外部キー値を言及せずに含めます。

これは実行可能なアプローチだと思いますか?

http://code.djangoproject.com/ticket/10761が実装されていれば、request.session から現在の会社を読み取るカスタム クエリセットを指定するだけで済むと思います。代わりに、そのチケットを迅速に追跡する (= パッチを作成して送信する) ほうがよいでしょうか?

編集:または、それを必要とする/外部キーを持つすべてのModelAdminでqueryset()メソッドを再定義するだけですか?

4

2 に答える 2

4

ModelAdmin.querysetあなたはそこでリクエストに便利にアクセスできるので、私の投票はオーバーライドすることです。save_modelポイント 3 をオーバーライドします。

 class MyModelAdmin(admin.ModelAdmin):
    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        if request.session.get('company_goggles'):
             return qs.filter(company=request.session['company_goggles'])
        return qs

多くのモデルがある場合は、ModelAdmin次のようにサブクラス化しGogglesAdmin、フィールド名を取得するフィールド/デフォルトを定義し、会社の事前保存自動注入も行います。

class CompanyGogglesAdmin(admin.ModelAdmin):
    def queryset(self, request):
        qs = super(CompanyGoggleAdmin, self).queryset(request)
        if request.session.get('company_goggles'):
            return qs.filter(**{ getattr(self, 'company_field', 'company') : 
                          request.session['company_goggles'] })

ところで、私はこの「会社のゴーグル」という用語がとても好きです。

于 2011-03-17T20:41:21.830 に答える
1

最後の質問に答えるには: クエリセットの特定のアイテムを表示したいだけなら、ModelAdminqueryset()メソッドを問題なくオーバーライドできます。たとえば、現在のセッションで会社を設定するとします。save_model()さらに、メソッドを上書きしてcompany ForeignKey、フォームを保存するときに常にユーザーの会社を指すようにすることができます。

class MyAdmin(admin.ModelAdmin):
    def queryset(self, request):
        company = request.session.get('company', None)
        qs = self.model._default_manager.get_query_set()
        if not company is None:
            qs = qs.filter(company=company)
        return qs

    def save_model(self, request, obj, form, change):
        company = request.session.get('company', None):
        instance = form.save(commit=False)
        if not change or not instance.company:
            instance.company = company
        instance.save()
        form.save_m2m()
        return instance
于 2011-03-17T20:42:10.367 に答える