如何向 django 管理界面添加自定义视图?

问题描述 投票:0回答:4

我的 django 管理界面如下所示:

现在我想添加一个与模型不对应的视图。

我可以覆盖上面页面的模板并添加自定义链接。但我觉得这看起来很难看。

覆盖示例

admin/index.html

{% extends "admin/index.html" %}

{% block content %}

{{ block.super }}
<div class="app-sonstiges module">
   ....
</div>
{% endblock %}

但是也许有一种官方方法可以将自定义视图添加到管理界面?

就我而言,我想提供一个可以在远程服务器上执行

tcptraceroute
的表单。我的应用程序的管理员需要这个。

我使用了相同的 html 标签。现在链接“tcptraceroute”看起来不错,但不幸的是消息向下移动了:

有没有办法获得像屏幕截图中的“Sontiges ... tcptraceroute”这样的自定义部分,而不需要向下移动最新的操作?

这是 html 结构的样子。我的

<div class="app-sonstiges">
主要内容如下:

django django-admin
4个回答
25
投票

您有 3 个选择:

使用提供菜单的第三方软件包

这非常简单,有一些很好的软件包支持管理菜单,以及一些将项目添加到菜单的方法。

第 3 方软件包的示例为

django-admin-tools
(上次更新于 2021 年 12 月,检查于 2023 年 4 月)。缺点是学起来有点难。另一种选择是使用
django-adminplus
(最后更新于 2019 年 10 月,检查于 2023 年 4 月),但在撰写本文时,它不支持 Django 2.2。

使用 django 管理模板进行黑客攻击

您始终可以扩展管理模板并覆盖您想要的部分,如 @Sardorbek 答案中所述,您可以从管理模板复制一些部分并按照您想要的方式更改它们。

使用自定义管理网站

如果您的视图应该仅在管理站点上执行操作,那么您可以扩展管理站点(也许更改默认值),除了向模板添加链接之外,您应该使用此方法来定义仅用于管理的视图,因为它更容易以这种方式检查权限。

考虑到您已经扩展了管理站点,现在您可以使用之前的方法将链接添加到模板,甚至扩展

get_app_list
方法,例如:

class MyAdminSite(admin.AdminSite):
    def get_app_list(self, request):
        app_list = super().get_app_list(request)
        app_list += [
            {
                "name": "My Custom App",
                "app_label": "my_test_app",
                # "app_url": "/admin/test_view",
                "models": [
                    {
                        "name": "tcptraceroute",
                        "object_name": "tcptraceroute",
                        "admin_url": "/admin/test_view",
                        "view_only": True,
                    }
                ],
            }
        ]
        return app_list

您还可以在向他们显示链接之前检查当前员工用户是否可以访问模块。 最后它看起来像这样:


10
投票

这里的问题是你的

div
不在
main-content
里面。我建议延长
admin/index.html

放入

app/templates/admin/index.html

{% extends "admin/index.html" %}
{% load i18n static %}

{% block content %}
<div id="content-main">

{% if app_list %}
    {% for app in app_list %}
        <div class="app-{{ app.app_label }} module">
        <table>
        <caption>
            <a href="{{ app.app_url }}" class="section" title="{% blocktrans with name=app.name %}Models in the {{ name }} application{% endblocktrans %}">{{ app.name }}</a>
        </caption>
        {% for model in app.models %}
            <tr class="model-{{ model.object_name|lower }}">
            {% if model.admin_url %}
                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
            {% else %}
                <th scope="row">{{ model.name }}</th>
            {% endif %}

            {% if model.add_url %}
                <td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
            {% else %}
                <td>&nbsp;</td>
            {% endif %}

            {% if model.admin_url %}
                {% if model.view_only %}
                <td><a href="{{ model.admin_url }}" class="viewlink">{% trans 'View' %}</a></td>
                {% else %}
                <td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
                {% endif %}
            {% else %}
                <td>&nbsp;</td>
            {% endif %}
            </tr>
        {% endfor %}
        </table>
        </div>
    {% endfor %}

    <!-- here you could put your div -->
    <div class="app-sonstiges module">
    ....
    </div>
    <!-- here you could put your div -->
{% else %}
    <p>{% trans "You don't have permission to view or edit anything." %}</p>
{% endif %}
</div>
{% endblock %}

另一种方法是将自定义应用程序添加到

app_list
。但它丑陋得多。所以我建议重写模板。

我假设你在

get_urls
中覆盖了
AdminSite


1
投票

如果您需要自定义页面来处理用户输入(来自表单),您可能需要尝试一下 django-etc 1.3.0+:

    from etc.admin import CustomModelPage

    class MyPage(CustomModelPage):
    
        title = 'My custom page'  # set page title

        # Define some fields you want to proccess data from.
        my_field = models.CharField('some title', max_length=10)

        def save(self):
            # Here implement data handling.
            super().save()

    # Register the page within Django admin.
    MyPage.register()

0
投票

注意:我合并了这个答案这个答案中的说明:

  • 使用
    MyAdminSite
    get_urls
     实现 
    get_app_list
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path("my-func", self.my_func, name="myfunc"),
        ]
        return my_urls + urls

    def get_app_list(self, request, **kwargs):
        """Show some links in the admin UI.

        See also https://stackoverflow.com/a/56476261"""
        app_list = super().get_app_list(request, kwargs)
        app_list += [
            {
                "name": "Other actions",
                "app_label": "other_actions_app",
                "models": [
                    {
                        "name": "my name",
                        "object_name": "my object name"my_admin:myfunc"),
                        "view_only": True,
                    }
                ],
            }
        ]
        return app_list
  • 设置
    admin_site = MyAdminSite(name="my_admin")
  • @admin.register(MyObject, site=admin_site)
    site
    参数一起使用,但使用
    admin
     中的 
    django.contrib
  • 没有更改设置(仍然使用
    django.contrib.admin
  • 将此行放入我的整体
    urls.py
    中以加载我的注册:
admin_site._registry.update(admin.site._registry)

我知道这看起来很奇怪,但这是唯一真正对我有用的东西,所以我想把它写下来,以防对其他人有用。

© www.soinside.com 2019 - 2024. All rights reserved.