我的 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">
主要内容如下:
您有 3 个选择:
这非常简单,有一些很好的软件包支持管理菜单,以及一些将项目添加到菜单的方法。
django-admin-tools
(上次更新于 2021 年 12 月,检查于 2023 年 4 月)。缺点是学起来有点难。另一种选择是使用 django-adminplus
(最后更新于 2019 年 10 月,检查于 2023 年 4 月),但在撰写本文时,它不支持 Django 2.2。
您始终可以扩展管理模板并覆盖您想要的部分,如 @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
这里的问题是你的
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> </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> </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
。
如果您需要自定义页面来处理用户输入(来自表单),您可能需要尝试一下 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()
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)
我知道这看起来很奇怪,但这是唯一真正对我有用的东西,所以我想把它写下来,以防对其他人有用。