Django Admin에서 동일한 모델에 대한 여러 ModelAdmins / views


150

동일한 모델에 대해 둘 이상의 ModelAdmin을 작성하고 각각 다른 방식으로 사용자 정의하고 다른 URL에 링크하려면 어떻게해야합니까?

Posts라는 Django 모델이 있다고 가정 해 봅시다. 기본적으로이 모델의 관리자보기에는 모든 Post 객체가 나열됩니다.

list_display와 같은 변수를 설정하거나 querysetModelAdmin 에서 메소드를 재정 의하여 다양한 방법으로 페이지에 표시되는 객체 목록을 사용자 정의 할 수 있다는 것을 알고 있습니다 .

class MyPostAdmin(admin.ModelAdmin):
    list_display = ('title', 'pub_date')

    def queryset(self, request):
        request_user = request.user
        return Post.objects.filter(author=request_user)

admin.site.register(MyPostAdmin, Post)

기본적으로 URL에서 액세스 할 수 있습니다 /admin/myapp/post. 그러나 동일한 모델의 여러보기 / ModelAdmins를 갖고 싶습니다. 예를 들어 /admin/myapp/post모든 게시물 개체를 /admin/myapp/myposts나열하고 사용자에게 속한 /admin/myapp/draftpost모든 게시물을 나열하고 아직 게시되지 않은 모든 게시물을 나열 할 수 있습니다. (이것은 단지 예일 뿐이며 실제 사용 사례는 더 복잡합니다)

동일한 모델에 대해 둘 이상의 ModelAdmin을 등록 할 수 없습니다 (이로 인해 AlreadyRegistered예외 가 발생 함). 이상적으로는 모든 것을 단일 ModelAdmin 클래스에 넣고 URL에 따라 다른 쿼리 세트를 반환하기 위해 내 'urls'함수를 작성 하지 않고 이를 달성하고 싶습니다 .

Django 소스를 살펴본 결과 ModelAdmin.changelist_viewurls.py에 어떻게 든 포함될 수있는 기능 이 있지만 어떻게 작동하는지 확실하지 않습니다.

업데이트 : 원하는 것을 수행하는 한 가지 방법을 찾았지만 (아래 참조) 여전히 다른 방법을 듣고 싶습니다.

답변:


275

프록시 모델을 사용하여 각 모델이 한 번만 등록 될 수 있다는 사실을 극복함으로써 원하는 것을 달성하는 한 가지 방법을 찾았습니다.

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'pubdate','user')

class MyPost(Post):
    class Meta:
        proxy = True

class MyPostAdmin(PostAdmin):
    def get_queryset(self, request):
        return self.model.objects.filter(user = request.user)


admin.site.register(Post, PostAdmin)
admin.site.register(MyPost, MyPostAdmin)

그러면 기본값에 PostAdmin액세스 /admin/myapp/post할 수 있고 사용자가 소유 한 게시물 목록은에 있습니다 /admin/myapp/myposts.

http://code.djangoproject.com/wiki/DynamicModels 를 본 후 동일한 기능을 수행하기 위해 다음 함수 유틸리티 함수를 찾았 습니다.

def create_modeladmin(modeladmin, model, name = None):
    class  Meta:
        proxy = True
        app_label = model._meta.app_label

    attrs = {'__module__': '', 'Meta': Meta}

    newmodel = type(name, (model,), attrs)

    admin.site.register(newmodel, modeladmin)
    return modeladmin

다음과 같이 사용할 수 있습니다.

class MyPostAdmin(PostAdmin):
    def get_queryset(self, request):
        return self.model.objects.filter(user = request.user)

create_modeladmin(MyPostAdmin, name='my-posts', model=Post)

8
대단해. 프록시 사이트가 관리 사이트에 등록 될 수 있다는 것을 몰랐습니다. 이것은 실제로 크게 도움이 될 것입니다.
Brandon Henry

8
django admin에서 동일한 모델을 두 번 등록해야했고 프록시 모델이 작동하는 것 같습니다. 그러나 권한 시스템에서 한 가지 문제가 발견되었습니다. 여기를 참조하십시오 : code.djangoproject.com/ticket/11154
bjunix

4
ModelAdmin 쿼리 세트 대신 기본 관리자를 변경하는 것도 좋습니다. 따라서 프록시 모델의 동작은 관리자 외부에서도 일관됩니다.
bjunix

4
이제 진정한 대답은 왜 django가 동일한 모델에 대해 두 명의 관리자를 허용하지 않는 것입니까? 우리는 그것을 확인하고 오류를 던지는 단 2 줄에 대해 해킹 할 필요가 없습니다 : s. 여전히 좋은 대답입니다!
Hassek

1
@zzart : 단지 문서를 누락 된 것으로 나타납니다 보류 끌어 오기 요청이있다 : github.com/django/django/pull/146/files
blueyed

3

폴 스톤의 답변은 절대적으로 좋습니다! 추가하기 위해 Django 1.4.5의 경우 사용자 정의 클래스를 상속해야했습니다.admin.ModelAdmin

class MyPostAdmin(admin.ModelAdmin):
    def queryset(self, request):
        return self.model.objects.filter(id=1)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.