たとえば、通常のビューからのpost_saveと管理者からのpost_saveを区別するにはどうすればよいですか?
2 に答える
ModelAdmin.response_add をオーバーライドすると、django 管理者がシグナルを送信していないように見えるため、同様の機能が得られる場合があります。
response_add 関数は、関連フィールドだけでなくオブジェクト自体などのすべてのデータを正常に検証して追加した後に呼び出されます。
そのため、独自の ModelAdmin クラスで response_add メソッドをオーバーライドすることにより、admin に何かが正常に追加された後にコードを実行できますが、他の場所では実行されません。
私はdjango 1.4で次のようにしました。コメントやフィードバックは大歓迎です! 私の場合はうまく機能しているようですが、Django のすべての内部構造についてはまだ詳しくなく、それが推奨される方法であるかどうかもわかりません。しかし、私にはスレッドローカルのハックよりも良いように思えます。
補足: ModelAdmin をオーバーライドすることで、自分でシグナルを発することもできると思いますが、それを経験したことはありません。
これは、product_get_initial_info(obj.id) を実行する response_add をオーバーライドするために使用したコードです。製品のみが管理者に正常に追加されました。
class ProductAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
inlines = [
ProductInline,
]
def response_add(self, request, obj, post_url_continue='../%s/'):
if obj and obj.id:
tasks.product_get_initial_info(obj.id)
return super(ProductAdmin, self).response_add(request, obj, post_url_continue='../%s/')
関連する django ソース コードは次のとおりです: django/contrib/admin/options.py
class ModelAdmin(BaseModelAdmin):
def add_view(self, request,...)
# .... Many lines of code ...... not putting them here as they're not so relevant
if all_valid(formsets) and form_validated:
self.save_model(request, new_object, form, False)
self.save_related(request, form, formsets, False)
self.log_addition(request, new_object)
# After saving everything response_add gets called with the newly created object
return self.response_add(request, new_object)
これを行う簡単な方法はありません。これは、post_save シグナルを使用してコードを適切な場所に配置していない可能性があることを意味します。
そうは言っても、どうしてもやりたい場合は、スレッドローカル ハックを使用してリクエスト オブジェクトにアクセスし、現在実行中のビューが管理ビューであるかどうかを調べることができます。threadlocal ハックの方法について読むには、django クックブックから始めますが、ユーザーの代わりにリクエスト全体を保存するだけです。多くの人が、スレッドローカルのハッキングは忌まわしいものだと考えていることに注意してください。これが議論です。私は彼らが非常に便利な場所を持っていると思いますが、もっと知らなくても、もっと良い解決策があると思います.