Django管理员,隐藏模型


84

在显示已注册模型的管理站点的根页面上,我要隐藏已注册到Django admin的多个模型。

如果我直接注销这些记录,由于添加新符号“ +”消失了,因此我无法添加新记录。

如何才能做到这一点 ?

Answers:


122

基于x0nix的答案,我做了一些实验。似乎从返回空dictget_model_perms会将模型从index.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中列出,才能使派生应用程序正常工作。显然,基本应用程序不应显示,但同时我也不想使其保持不变和可重用。请参阅[here](Stack Exchange / questions / 13923968 /)。
2012年

6
一种较短的方法:get_model_perms = lambda self, req: {}
Tigran Saluev

2
如果我想从某个userAdmin隐藏模型怎么办?
Alireza Sanaee 2014年

请谨慎使用此解决方案-即使链接消失了,用户也可以像这样跳到对象本身:/ admin / main / comment / 2333 / change /
goodgrief

31

对于Django 1.8及更高版本

从Django 1.8开始,ModelAdmin有一个名为的新方法has_module_permission(),该方法负责在admin索引中显示模型。

要从admin索引隐藏模型,只需在您的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索引页面仍链接到/ admin /,则可以通过来避开该错误return request.path!='/admin/'。不幸的是,这重新启用了应用程序模型列表中的那些模型。
ecp

我已经在这里打开了此错误的。这已在此处修复。希望它应该包含在下一发行版中。
xyres

在Django 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

丑陋的解决方案:覆盖管理索引模板,即将index.html从django复制到您的/admin/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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.