programing

Django admin에서 동일한 모델에 대한 여러 모델 관리자/뷰

padding 2023. 6. 17. 08:46
반응형

Django admin에서 동일한 모델에 대한 여러 모델 관리자/뷰

동일한 모델에 대해 각각 다르게 사용자 지정되고 서로 다른 URL에 연결된 두 개 이상의 ModelAdmin을 생성하려면 어떻게 해야 합니까?

제가 Posts라고 불리는 장고 모델을 가지고 있다고 칩시다.기본적으로 이 모델의 관리 보기에는 모든 게시 개체가 나열됩니다.

list_display와 같은 변수를 설정하거나 재정의하여 페이지에 표시되는 개체 목록을 다양한 방법으로 사용자 지정할 수 있습니다.queryset내 ModelAdmin의 메서드는 다음과 같습니다.

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' 함수를 작성하지 않고 를 달성하는 것이 이상적입니다.

장고 소스를 봤는데 다음과 같은 기능이 있습니다.ModelAdmin.changelist_view그것은 어떻게든 제 urls.py 에 포함될 수 있지만, 저는 그것이 어떻게 작동할지 정확히 모르겠습니다.

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

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

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)

폴 스톤의 대답은 정말 훌륭합니다!덧붙이자면, 장고 1.4.5의 경우 사용자 지정 클래스를 상속해야 했습니다.admin.ModelAdmin

class MyPostAdmin(admin.ModelAdmin):
    def queryset(self, request):
        return self.model.objects.filter(id=1)

정답에 근거하여, 나는 원숭이를 패치합니다.AdminSite클래스 및 메소드 추가register_via_proxy작업을 쉽게 하기 위해.

import re
from django.contrib import admin

def _register_proxy(self, model, admin_class):
    proxy_model = type(
        admin_class.__name__, (model,), {
            "__module__": re.sub(
                r'(^.*?)(\.[^\.]+)$', r'\1.proxy', model.__module__
            ),
            "Meta": type("Meta", tuple(), {
                "proxy": True,
                 "app_label": model._meta.app_label
            })
        }
    )

    return self.register(proxy_model, admin_class)


admin.sites.AdminSite.register_via_proxy = _register_proxy

사용 방법은 다음과 같습니다.

site = admin.sites.AdminSite()
site.register_via_proxy(models.ModelType, AdminClass)

언급URL : https://stackoverflow.com/questions/2223375/multiple-modeladmins-views-for-same-model-in-django-admin

반응형