programing

Django 관리자의 기본 쿼리 세트 재정의

nasanasas 2020. 11. 27. 08:11
반응형

Django 관리자의 기본 쿼리 세트 재정의


내 모델 중 하나에는 전역 적으로 개체를 숨기는 데 사용되는 삭제 된 플래그가 있습니다.

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 관리 모듈에서 사용하는 기본 쿼리 셋을 어떻게 재정의 할 수 있습니까?


모델 관리자 클래스에서 메서드를 재정의 할 수 있습니다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

다음과 같은 문제는 무엇입니까?

class Conversation(BaseModel):
    ...
    deleted = models.BooleanField(default=False)
    objects = models.Manager() # includes deleted conversations
    nondeleted_conversations = NondeletedManager()

따라서 자신의 앱 / 프로젝트 Conversation.nondeleted_conversations()에서 기본 제공 관리자 앱 을 사용 하고이를 수행하도록합니다.


허용 된 솔루션은 저에게 잘 작동하지만 조금 더 유연성이 필요했기 때문에 변경 목록보기를 확장하여 사용자 지정 쿼리 셋 매개 변수를 추가했습니다. 이제 기본 쿼리 셋 / 필터를 구성 할 수 있으며 다른 필터 (매개 변수 가져 오기)를 사용하여 수정할 수 있습니다.

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)

Django 프록시 모델을 사용 하여이 작업을 수행 할 수 있습니다 .

# 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()

The admin implementation of get_queryset() use ._default_manager instead .objects, as show next

qs = self.model._default_manager.get_queryset()

ref Django github BaseModelAdmin implementation

This only ensures that every time you use YourModel.objects, you will not include deleted objects, but the generic views and others uses ._default_manager too. Then if you don't override get_queryset is not a solution. I've just check on a ListView and admin.

참고URL : https://stackoverflow.com/questions/12354099/override-default-queryset-in-django-admin

반응형