Django 管理员,隐藏模型

发布于 2024-08-25 14:51:40 字数 108 浏览 6 评论 0原文

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

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

这怎么办?

At the root page of the admin site where registered models appear, I want to hide several models that are registered to the Django admin.

If I directly unregister those, I am not able to add new records as the add new symbol "+" dissapears.

How can this be done ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

谈场末日恋爱 2024-09-01 14:51:40

根据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)

Based on x0nix's answer I did some experiments. It seems like returning an empty dict from get_model_perms excludes the model from index.html, whilst still allowing you to edit instances directly.

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)
十级心震 2024-09-01 14:51:40

对于 Django 1.8 及更高版本

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

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

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

For Django 1.8 and above

Since Django 1.8, ModelAdmin has got a new method called has_module_permission() which is responsible for displaying a model in admin index.

To hide a model from admin index, just create this method in your ModelAdmin class and return False. Example:

class MyModelAdmin(admin.ModelAdmin):
    ...
    def has_module_permission(self, request):
        return False
三岁铭 2024-09-01 14:51:40

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

就像之前的解决方案一样 - 将 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)

Got the same problem, here what I came up with.

Like in previous solution - copy index.html from django to your /admin/index.html and modify it like this:

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

And create ModelAdmin subclass:

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

Now any model registered with HiddenModelAdmin subclass won't show up in admin list, but will be available via "plus" symbol in detail:

class MyModelAdmin(HiddenModelAdmin):
    ...

admin.site.register(MyModel, MyModelAdmin)
忘年祭陌 2024-09-01 14:51:40

从 Django 1.8.18 开始,has_module_permission() 仍然存在问题。因此,在我们的例子中,我们还使用了 get_model_perms()。同样,我们只需要为特定用户隐藏模型,但超级用户应该能够访问其索引条目。

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)

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)
深陷 2024-09-01 14:51:40

丑陋的解决方案:覆盖管理索引模板即从 django 复制 index.html 到 /admin/index.html 并添加如下内容:

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

Ugly solution: override admin index template i.e. copy index.html from django to your /admin/index.html and add something like this:

{% for for model in app.models %}
    {% ifnotequal model.name "NameOfModelToHide" %}
    ...
浅唱ヾ落雨殇 2024-09-01 14:51:40

这是建立在 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 才能使上述功能正常工作。

This is an alternative building on top x0nix's answer, and only if you are happy hiding the the rows with jquery.

Copy pasting from the other answer the part that I reused

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)

Then install django-jquery and then add the following block in your /admin/index.html template:

{% 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.

梦境 2024-09-01 14:51:40

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

Saygoodbye 2024-09-01 14:51:40

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

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

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

但在改变任何东西之前,我认为人们应该考虑这一点......

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

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".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文