[django] Django 관리자, 모델 숨기기

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

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

어떻게 할 수 있습니까?



답변

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 1.8 이상

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

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

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


답변

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

이전 솔루션과 마찬가지로 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)


답변

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

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


답변

이것은 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 가 필요 합니다.


답변

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

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

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

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

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


답변

더 많은 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)

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