Django 관리자, 모델 숨기기


85

등록 된 모델이 나타나는 관리자 사이트의 루트 페이지에서 Django 관리자에 등록 된 여러 모델을 숨기고 싶습니다.

직접 등록을 취소하면 새 레코드 추가 기호 "+"가 사라져서 새 레코드를 추가 할 수 없습니다.

어떻게 할 수 있습니까?

답변:


123

x0nix의 답변따라 몇 가지 실험을 수행했습니다. 에서 빈 dict를 반환하면 get_model_permsindex.html에서 모델이 제외되는 것처럼 보이지만 인스턴스를 직접 편집 할 수 있습니다.

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        """
        Return empty perms dict thus hiding the model from admin index.
        """
        return {}

admin.site.register(MyModel, MyModelAdmin)

동의합니다. 코드를 변경하고 싶지 않을 때만 문제가됩니다. 내 말은, 다른 앱에 대한 종속성으로부터 깨끗하게 유지하려는 기본 앱이 있다는 것입니다. 파생 된 프로젝트 별 앱에 이러한 종속성을 유지합니다. 이제 관리 인터페이스에 기본 앱이 아닌 파생 된 앱만 표시되기를 원합니다. Django는 파생 된 앱이 작동하려면 settings / INSTALLED_APPS에 기본 앱이 나열되어야합니다. 분명히 기본 앱은 표시되지 않아야하지만 동시에 수정하지 않고 재사용 할 수있는 상태로 유지하고 싶지 않습니다. [여기] ( Stack Exchange / questions / 13923968 /)를 참조하세요.
Sven

6
더 짧은 방법 :get_model_perms = lambda self, req: {}
Tigran Saluev

2
특정 userAdmin에서 모델을 숨기려면 어떻게해야합니까?
Alireza Sanaee 2014

1
이 솔루션에주의하십시오. 링크가 사라지더라도 사용자는 다음과 같이 객체 자체로 이동할 수 있습니다. / admin / main / comment / 2333 / change /
goodgrief

32

Django 1.8 이상

Django 1.8 이후 로 관리자 색인에 모델을 표시하는 ModelAdmin새로운 메서드가 호출 has_module_permission()되었습니다.

관리자 색인에서 모델을 숨기려면 ModelAdmin클래스 에서이 메서드를 만들고 False. 예:

class MyModelAdmin(admin.ModelAdmin):
    ...
    def has_module_permission(self, request):
        return False

불행히도 has_module_permission하나의 모델이 아닌 전체 앱에 영향을 미칩니다. 따라서이를 앱의 모델에 추가하면 앱 모델 목록 (/ admin / app_label /)에서 403 금지됨이 발생합니다. django / contrib / admin / sites.py를 참조하십시오 .
Fabian

1
@Fabian 나는 그것이 버그라고 생각합니다. Django의 IRC 채널에서이 질문을했는데, 일부 사람들은이 동작이 바람직하지 않다는 데 동의합니다.
xyres

@Fabian 관리자 색인 페이지가 여전히 / admin /에 링크되어 있다고 가정하면 .NET 과 같은 것으로 해당 버그를 피할 수 return request.path!='/admin/'있습니다. 불행히도 앱 모델 목록에서 해당 모델을 다시 활성화합니다.
ecp

이 버그에 대한 티켓을 여기 에서 열었습니다 . 이것은 여기 에서 수정되었습니다 . 다음 릴리스에 포함될 예정입니다.
xyres

장고 1.11에서 딥 링크는 여전히 작동하지만 실체는 메인 관리 화면에 표시되지 않습니다
사바 토스

22

같은 문제가 생겼습니다. 여기에서 제가 생각해 낸 것입니다.

이전 솔루션과 마찬가지로 django에서 index.html을 /admin/index.html로 복사하고 다음과 같이 수정합니다.

{% for model in app.models %}
    {% if not model.perms.list_hide %}
    <tr>
    ...
    </tr>
    {% endif %}
{% endfor %}

그리고 ModelAdmin 하위 클래스를 만듭니다.

class HiddenModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, *args, **kwargs):
        perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
        perms['list_hide'] = True
        return perms

이제 HiddenModelAdmin 하위 클래스에 등록 된 모델은 관리자 목록에 표시되지 않지만 "플러스"기호를 통해 자세히 볼 수 있습니다.

class MyModelAdmin(HiddenModelAdmin):
    ...

admin.site.register(MyModel, MyModelAdmin)

1

추악한 해결책 : 관리자 색인 템플릿을 재정의 하십시오. 즉 django에서 /admin/index.html로 index.html을 복사하고 다음과 같이 추가하십시오.

{% for for model in app.models %}
    {% ifnotequal model.name "NameOfModelToHide" %}
    ...

1

이것은 x0nix의 답변에 대한 대안 건물이며 jquery로 행을 숨기는 데 만족하는 경우에만 가능합니다.

내가 재사용 한 부분을 다른 답변에서 붙여 넣기 복사

class HiddenModelAdmin(admin.ModelAdmin):
def get_model_perms(self, *args, **kwargs):
    perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
    perms['list_hide'] = True
    return perms

class MyModelAdmin(HiddenModelAdmin):
...

admin.site.register(MyModel, MyModelAdmin)

그런 다음 django-jquery를 설치 하고 /admin/index.html템플릿에 다음 블록을 추가합니다 .

{% extends "admin:admin/index.html" %}

{% block extrahead %}
    <script type="text/javascript" src="{{ STATIC_URL }}js/jquery.js"></script>
    {% if app_list %}
      <script type="text/javascript">
        $(function(){
          {% for app in app_list %}
            {% for model in app.models %}
                {% if model.perms.list_hide %}
                    $('div.app-{{ app.app_label }}').find('tr.model-{{ model.object_name|lower }}').hide();
                {% endif %}
            {% endfor %}
          {% endfor %}
        });
     </script>
   {% endif %}
{% endblock %}

전체 템플릿을 복사하여 붙여 넣을 필요가 없으며 확장하고 extrahead블록을 재정의하기 만하면 됩니다. 위의 작업을 수행 하려면 django-apptemplates 가 필요 합니다.


0

Django 1.2에는 새로운 if 문이 있습니다. 즉, admin / index.html을 덮어 써서 원하는 기능을 얻을 수 있습니다.

{% if model.name not in "Name of hidden model; Name of other hidden model" %}
    ...
{% endif %}

이는 다국어 관리자를 신경 쓰지 않기 때문에 나쁜 솔루션입니다. 물론 지원되는 모든 언어로 모델 이름을 추가 할 수 있습니다. 핵심 Django 기능의 한 측면 이상을 덮어 쓰지 않기 때문에 좋은 솔루션입니다.

하지만 변경하기 전에 사람들이 이것에 대해 생각해야한다고 생각합니다.

본질적으로 문제는 가끔 드롭 다운에 옵션을 추가하는 것 이상으로 사용하고 싶지 않은 모델을 갖는 것과 관련이 있습니다. 모델이 너무 많으면 당황하는 "그렇지 않은"사용자를위한 권한 집합을 만들어 효과적으로 해결할 수 있습니다. 특정 모델의 변경이 필요한 경우 "고급 계정"으로 간단히 로그인 할 수 있습니다.


0

더 많은 DRY 솔루션을 원하면 등록하고 숨길 모델 관리자가 많았습니다 (Django 1.10, Python 3.5)

# admin.py

def register_hidden_models(*model_names):
    for m in model_names:
        ma = type(
            str(m)+'Admin',
            (admin.ModelAdmin,),
            {
                'get_model_perms': lambda self, request: {}
            })
        admin.site.register(m, ma)

register_hidden_models(MyModel1, MyModel2, MyModel3)

앱에서 재사용하고 싶다면 유틸리티 클래스로 롤링 할 수 있다고 생각합니다.


0

Django 1.8.18 부터 has_module_permission()여전히 문제가 있습니다. 그래서 우리의 경우에는 get_model_perms(). 마찬가지로 특정 사용자에 대해서만 모델을 숨길 필요가 있지만은 superuser색인 항목에 액세스 할 수 있어야합니다.

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        if not request.user.is_superuser:
            return {}
        return super(MyModelAdmin, self).get_model_perms(request)

admin.site.register(MyModel, MyModelAdmin)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.