Development Tip

Django 관리자, 모델 숨기기

yourdevel 2020. 10. 18. 19:41
반응형

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에서 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 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 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 %}

You don't need to copy paste the whole template, just extend it and override the extrahead block. You'll need django-apptemplates for the above to work.


Django 1.2 has new if-statements, meaning that the desired feature could be obtained only by overwriting admin/index.html

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

This is a bad solution, because it doesn't care about multi-language admins. You could of course add the names of models in all of the supported languages. It's a good solution because it doesn't overwrite more than one aspect of core Django functions.

But before changing anything, I think people should think about this...

Essentially the problem is related to having models that one does not wish to use for more than adding an option to a drop-down once in a while. It could effectively be worked around by creating a set of permissions for "not so advanced" users that panic when there are too many models. In case changes in the particular models are required, one can simply log in with the "advanced account".


I had lots of model admins to register and hide, if you want a more DRY solution, this worked for me (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)

I guess you could roll it into a utility class if you want to re-use it across apps.


As of Django 1.8.18, has_module_permission() still has issue. So, in our case we used also the get_model_perms(). Likewise, we need to hide the model for specific user only, but the superuser should be able to access its index entry.

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)

참고URL : https://stackoverflow.com/questions/2431727/django-admin-hide-a-model

반응형