繁体   English   中英

Django 管理员,隐藏模型

[英]Django admin, hide a model

在显示注册模型的管理站点的根页面上,我想隐藏几个注册到 Django 管理员的模型。

如果我直接取消注册那些,我将无法添加新记录,因为添加新符号“+”消失了。

如何才能做到这一点 ?

根据x0nix 的回答,我做了一些实验。 get_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 1.8 及更高版本

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

要从管理索引隐藏模型,只需在ModelAdmin类中创建此方法并返回False 例子:

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

遇到了同样的问题,这是我想出的。

就像在之前的解决方案中一样 - 将 index.html 从 django 复制到您的 /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)

丑陋的解决方案: 覆盖管理索引模板,即将 index.html 从 django 复制到您的 /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 %}

您不需要复制粘贴整个模板,只需扩展它并覆盖extrahead块即可。 您需要django-apptemplates才能使上述工作正常进行。

我有很多模型管理员要注册和隐藏,如果你想要一个更干燥的解决方案,这对我有用(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)

如果您想在应用程序中重复使用它,我想您可以将它整合到一个实用程序类中。

从 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)

例如,只是不要将 admin.site.register(MyModel, MyModelAdmin) 放在 admin.py 中。 正常注册模型。

Django 1.2 有新的 if 语句,这意味着只有通过覆盖 admin/index.html 才能获得所需的功能

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

这是一个糟糕的解决方案,因为它不关心多语言管理员。 您当然可以添加所有支持语言的模型名称。 这是一个很好的解决方案,因为它不会覆盖核心 Django 函数的多个方面。

但在改变任何事情之前,我认为人们应该考虑一下这个......

从本质上讲,问题与拥有的模型有关,而不仅仅是偶尔向下拉列表中添加一个选项。 它可以通过为“不太高级”的用户创建一组权限来有效地解决,这些用户在模型过多时会感到恐慌。 如果需要更改特定型号,只需使用“高级帐户”登录即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM