私のモデルの1つには、オブジェクトをグローバルに非表示にするために使用される削除済みフラグがあります。
class NondeletedManager(models.Manager):
"""Returns only objects which haven't been deleted"""
def get_query_set(self):
return super(NondeletedManager, self).get_query_set().exclude(deleted=True)
class Conversation(BaseModel):
...
deleted = models.BooleanField(default=False)
objects = NondeletedManager()
all_conversations = models.Manager() # includes deleted conversations
Django= adminモジュールが使用するデフォルトのクエリセットをオーバーライドして、削除された会話を含めるにはどうすればよいですか?
オーバーライドget_queryset
モデル管理クラスのメソッド。
class MyModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(MyModelAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)
Django <= 1.5では、メソッドの名前はqueryset
だけでした。
Konradは正しいですが、これはドキュメントに記載されている例よりも困難です。
削除された会話は、既に除外されているクエリセットに含めることはできません。したがって、admin.ModelAdmin.querysetを完全に再実装する以外のオプションはありません。
class ConversationAdmin (admin.ModelAdmin):
def queryset (self, request):
qs = Conversation.all_conversations
ordering = self.get_ordering(request)
if ordering:
qs = qs.order_by(*ordering)
return qs
受け入れられたソリューションはうまく機能しますが、もう少し柔軟性が必要だったため、変更リストビューを拡張してカスタムクエリセットパラメーターを追加することになりました。デフォルトのクエリセット/フィルターをそのように構成できるようになりましたが、別のフィルターを使用して変更することができます(パラメーターを取得)。
def changelist_view(self, request, extra_context=None):
if len(request.GET) == 0 :
q = request.GET.copy()
q['status__gt'] = 4
request.GET = q
request.META['QUERY_STRING'] = request.GET.urlencode()
return super(WorksheetAdmin,self).changelist_view(request, extra_context=extra_context)
次の何がそんなに間違っているのでしょうか:
_class Conversation(BaseModel):
...
deleted = models.BooleanField(default=False)
objects = models.Manager() # includes deleted conversations
nondeleted_conversations = NondeletedManager()
_
したがって、独自のアプリ/プロジェクトでは、Conversation.nondeleted_conversations()
を使用し、組み込みの管理アプリにそれをさせます。
これを行うには、Django proxy model を使用します。
# models.py
class UnfilteredConversation(Conversation):
class Meta:
proxy = True
# this will be the 'default manager' used in the Admin, and elsewhere
objects = models.Manager()
# admin.py
@admin.register(UnfilteredConversation)
class UnfilteredConversationAdmin(Conversation):
# regular ModelAdmin stuff here
...
または、再利用したい既存のModelAdminクラスがある場合:
admin.site.register(UnfilteredConversation, ConversationAdmin)
このアプローチは、元の会話モデルでデフォルトマネージャーをオーバーライドすることで発生する可能性のある問題を回避します。これは、デフォルトマネージャーがManyToMany関係およびリバースForeignKey関係でも使用されるためです。
Natan Yellinは正しいですが、マネージャーの順序を変更できます。最初の順序がデフォルトになり、管理者によって使用されます。
_class Conversation(BaseModel):
...
deleted = models.BooleanField(default=False)
all_conversations = models.Manager() # includes deleted conversations
objects = NondeletedManager()
_
get_queryset()
の管理実装は、次に示すように_._default_manager
_の代わりに_.objects
_を使用します
_qs = self.model._default_manager.get_queryset()
_
ref Django github BaseModelAdmin implementation
これにより、YourModel.objectsを使用するたびに、削除されたオブジェクトは含まれなくなりますが、汎用ビューなどでは._default_managerも使用されます。次に、get_querysetをオーバーライドしない場合、解決策ではありません。 ListViewと管理者を確認しました。