已经有一个类似的问题How do you add a new entry into the django admin index?,但提供的所有答案对我来说都不是很满意。
因此,我浏览了源代码,并正在寻找一种不涉及覆盖任何模板的可能性,既不是index.html,也不是app_index.html。
文件django/contrib/admin/sites.py包含负责渲染index.html和app_index.html的代码,第一个是显示问题中所示内容的模板。
方法index 渲染模板index.html 并显示注册模型管理员的可用应用程序。它使用方法get_app_list 来获取应用程序。在这个方法中调用了方法_build_app_dict,获取模型和模型管理员。
方法app_index 呈现模板app_index.html 并显示单个应用程序的注册模型管理员。它使用了前面提到的方法_build_app_dict。
因此,我决定在我的自定义管理员中覆盖此方法。根据问题中的示例,它可能看起来像这样(与原始示例的差异以粗体显示):
class MyAdmin(admin.AdminSite):
def get_urls(self):
urls = super().get_urls()
my_urls = [
path('stats/', self.admin_site.admin_view(self.stats), name='stats'),
]
return my_urls + urls
def stats(self, request):
request.current_app = self.admin_site.name
context = dict(
# Include common variables for rendering the admin template.
self.admin_site.each_context(request),
# Anything else you want in the context...
key='blah',
)
return TemplateResponse(request, "sometemplate.html", context)
def _build_app_dict(self, request, label=None):
# we create manually a dict to fake a model for our view 'stats'
# this is an example how the dict should look like, i.e. which keys
# should be present, the actual values may vary
stats = {
'name': 'Stats',
'admin_url': reverse('my_admin:stats'),
'object_name': 'Stats',
'perms': {'delete': False, 'add': False, 'change': False},
'add_url': ''
}
# get the app dict from the parent method
app_dict = super(MyAdmin, self)._build_app_dict(request, label)
# check if there is value for label, then the app_index will be rendered
if label:
# append the manually created dictionary 'stats'
app_dict['models'].append(stats)
# otherwise the index will be rendered
# and we have to get the entry for our app,
# which is in this case 'traffic'
# using TrafficConfig.name or TrafficConfig.label
# might be better than hard coding the value
else:
app = app_dict.get('traffic', None)
# if an entry for 'traffic' has been found
# we append our manually created dictionary
if app:
app['models'].append(stats)
return app_dict
my_admin = MyAdmin(name='my_admin')
my_admin.register(Traffic)
现在,当我们打开自定义管理员时,我们会看到如下内容:
TRAFFIC
---------------------------------
Traffics + Add \ Change
Stats \ Change
这是因为我们操纵了用于渲染模板的字典,它使用了我们指定的值,在这种情况下,最相关的是 name Stats,admin_url 将调用自定义视图stats。由于我们将add_url留空,因此不会显示+添加链接。
重要的是倒数第二行,在这里我们调用我们的自定义管理员并传递一个名称,它将用作 url 命名空间。
编辑:
不幸的是,我在发布答案后才注意到问题是询问如何显示在ModelAdmin 中创建的自定义视图的链接,而我的答案解释了如何为自定义管理员AdminSite 执行此操作。我希望它仍然有一些帮助。