26π
You have 3 options here:
Using third-party packages which provide menu
This is pretty straight forward, there are some good packages out there which support menu for admin, and some way to add your item to the menu.
An example of a 3rd party package would be django-admin-tools
(last updated Dec 2021, checked April 2023). The drawback is that it is a bit hard to learn. Another option would be to use django-adminplus
(last updated Oct 2019, checked April 2023) but at the time of writing this, it does not support Django 2.2.
Hacking with django admin templates
You can always extend admin templates and override the parts you want, as mentioned in @Sardorbek answer, you can copy some parts from admin template and change them the way you want.
Using custom admin site
If your views are supposed to only action on admin site, then you can extend adminsite (and maybe change the default), beside from adding links to template, you should use this method to define your admin-only views as itβs easier to check for permissions this way.
Considering you already extended adminsite, now you can use the previous methods to add your link to template, or even extend get_app_list
method, example:
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
You can also check if current staff user can access to module before you show them the links.
It will look like this at then end:
10π
Problem here that your div
is not inside main-content
. I suggest extending admin/index.html
Put in 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 %}
The another approach is to add custom app to app_list
. But it is far more ugly. So I suggest overriding template.
I assume you are overriding get_urls
in AdminSite
.
- [Django]-Django pipeline Cache Busting is not Updating Cached File/Hash
- [Django]-When to use Django get_absolute_url() method?
- [Django]-How to add clickable links to a field in Django admin?
1π
If you need a custom page to handle user input (from form), you may want to give django-etc 1.3.0+ a try:
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()
- [Django]-Django model fields validation
- [Django]-Django 1.9.2 AssertionError: database connection isn't set to UTC
- [Django]-Retrieving list items from request.POST in django/python
0π
Note: I combined instructions in this answer and this answer:
- Implemented
MyAdminSite
withget_urls
andget_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
- Set
admin_site = MyAdminSite(name="my_admin")
- Used
@admin.register(MyObject, site=admin_site)
with thesite
parameter but usingadmin
fromdjango.contrib
- Did not change settings (still uses
django.contrib.admin
) - Put this line in my overall
urls.py
to load my registered:
admin_site._registry.update(admin.site._registry)
I know this seems weird, but itβs the only thing that really worked for me, so I wanted to write it down in case itβs useful for others.
- [Django]-Django "Remember Me" with built-in login view and authentication form
- [Django]-Django Templating: how to access properties of the first item in a list
- [Django]-Why does Django's render() function need the "request" argument?