私が達成したいことは次のとおりです。
- 管理サイトに移動し、オブジェクトのリストにいくつかのフィルターを適用します
- クリックしてオブジェクトを編集、編集、編集、[保存] をクリックします。
- サイトにオブジェクトのリストが表示されます... フィルタリングされていません。ステップ 1 のフィルターを記憶して適用したいと思います。
それを行う簡単な方法はありますか?
私が達成したいことは次のとおりです。
それを行う簡単な方法はありますか?
残念ながら、これを行う簡単な方法はありません。フィルタリングは、どのセッション変数にも保存されていないようです。
2 回戻るのが通常の方法ですが、フィルターを使用して表示されないようにオブジェクトを変更したばかりの場合は、扱いにくく煩わしい場合があります。
1 回限りの場合は、クリックして 2 回戻るか、もう一度フィルター処理を行うのが最も簡単な方法です。
より頻繁にフィルタリングする予定がある場合、または管理者のハッキング (非常にオープンで簡単です) について学びたい場合は、FilterSpecを作成する必要があります。
自分で書いている人の例については、こちらとこちらをご覧ください。
これを行うための非常にひどい方法は、管理インターフェースを編集して、[保存] をクリックした後に、フィルタリングされた URL にリダイレクトされるようにすることです。これはまったくお勧めしませんが、オプションです。
これを行うもう 1 つの非常に簡単な方法は、フィルター処理されたオブジェクトを表示する汎用ビューを記述し、Django フォームを使用してそこから項目を編集することです。これを見てみると、単純な表示/編集ページを作成するために記述しなければならないコードがどれだけ少ないかに驚かれることでしょう。
「戻る」を2回クリックしますか?
これを行うための簡単なハックがありますが、それは一般的な解決策ではなく、ModelAdmin
これをサポートするためにすべてを変更する必要があります。これを行う一般的な方法があるかもしれませんが、一般的なレベルで解決するために時間を費やしていません。
FilterSpec
最初のステップは、選択したフィルター値をセッションに保存する (不要になったら削除する) フィルターのカスタムを作成することです (役立つリンクについては、Harley の投稿を参照してください)。
# in cust_admin/filterspecs.py
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
class MyFilterSpec(ChoicesFilterSpec):
def __init__(self, f, request, params, model, model_admin):
super(MyFilterSpec, self).__init__(f, request, params, model,
model_admin)
if self.lookup_val is not None:
request.session[self.lookup_kwarg] = self.lookup_val
elif self.lookup_kwarg in request.session:
del(request.session[self.lookup_kwarg])
# Register the filter with a test function which will apply it to any field
# with a my_filter attribute equal to True
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'my_filter', False),
MyFilterSpec))
これがどこかにあるモジュールをインポートする必要がありますurls.py
。
# in urls.py
from cust_admin import filterspecs
フィルターを適用するフィールドにプロパティを設定します。
# in models.py
class MyModel(models.Model):
my_field = Models.IntegerField(choices=MY_CHOICES)
my_field.my_filter = True
カスタムModelAdmin
クラスでは、メソッドをオーバーライドして、ユーザーが [保存change_view
] をクリックした後、フィルター フィールドの値が URL に追加された状態でリスト ビューに戻るようにします。
class MyModelAdmin(admin.ModelAdmin):
def change_view(self, request, object_id, extra_context=None):
result = super(MyModelAdmin, self).change_view(request, object_id,
extra_context)
if '_save' in request.POST:
if 'my_field__exact' in request.session:
result['Location'] = '/admin/myapp/mymodel/?my_field__exact=%s' \
% request.session['my_field__exact']
return result
この機能は、1.6 リリースの一部として Django に追加され、デフォルトで有効になりました。リリースノートに記載されています:
ModelAdmin は、オブジェクトを作成、編集、または削除した後、リスト ビューのフィルターを保持するようになりました。preserve_filters 属性を False に設定することで、フィルターをクリアする以前の動作を復元することができます。
Django プロジェクトには、まさにこの機能を求める変更要求があります。
チェックインされるのを待っているのは、いくつかのテストとドキュメントだけです。それらを作成してプロジェクト全体を支援することも、提案されたパッチ (ページの下部近く) を入手して試してみることもできます。
これを行う別の方法は、フィルターをクエリセットに埋め込むことです。
必要な方法でフィルタリングするマネージャーを使用してプロキシ モデルを動的に作成し、admin.site.register() を呼び出して新しいモデル管理者を作成できます。すべてのリンクは、このビューに関連しています。
私の意見では、ModelAdminchangelist_view
と のメソッドをオーバーライドする方が良いでしょうchange_view
:
そのようです:
class FakturaAdmin(admin.ModelAdmin):
[...]
def changelist_view(self, request, extra_context=None):
result = super(FakturaAdmin, self).changelist_view(request, extra_context=None)
request.session['qdict'] = request.GET
return result
def change_view(self, request, object_id, extra_context=None):
result = super(FakturaAdmin, self).change_view(request, object_id, extra_context)
try:
result['location'] = result['location']+"?"+request.session['qdict'].urlencode()
except:
pass
return result
必要に応じて、オブジェクトを保存した後、アクティブなフィルターを持つオブジェクトのリストに戻ります。