hmmm. Thanks for your help everyone. The solution I have come up ( with your help ofcourse :) is as follows:

I have two custom templates:

   my_model_list.html
   my_model_detail.html

Under views.py:

class MyModel(object):
    # ... Access other models
    # ... process / normalise data 
    # ... store data

@staff_member_required
def my_model_list_view(request) #show list of all objects
    #. . . create objects of MyModel . . .
    #. . . call their processing methods . . .
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_list.html', context, RequestContext(request))
    return HttpResponse(r)

@staff_member_required
def my_model_detail_view(request, row_id) # Shows one row (all values in the object) in detail     
    #. . . create object of MyModel . . .
    #. . . call it's methods . . .
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_detail.html', context, RequestContext(request))
    return HttpResponse(r)

Under the main django urls.py:

urlpatterns = patterns( 
    '',
    (r'^admin/myapp/mymodel/$', my_model_list_view),
    (r'^admin/myapp/mymodel/(\d+)/$', my_model_detail_view),
    ( r'^admin/', include( admin.site.urls ) )
)
Answer from sysasa on Stack Overflow
Top answer
1 of 3
29

hmmm. Thanks for your help everyone. The solution I have come up ( with your help ofcourse :) is as follows:

I have two custom templates:

   my_model_list.html
   my_model_detail.html

Under views.py:

class MyModel(object):
    # ... Access other models
    # ... process / normalise data 
    # ... store data

@staff_member_required
def my_model_list_view(request) #show list of all objects
    #. . . create objects of MyModel . . .
    #. . . call their processing methods . . .
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_list.html', context, RequestContext(request))
    return HttpResponse(r)

@staff_member_required
def my_model_detail_view(request, row_id) # Shows one row (all values in the object) in detail     
    #. . . create object of MyModel . . .
    #. . . call it's methods . . .
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_detail.html', context, RequestContext(request))
    return HttpResponse(r)

Under the main django urls.py:

urlpatterns = patterns( 
    '',
    (r'^admin/myapp/mymodel/$', my_model_list_view),
    (r'^admin/myapp/mymodel/(\d+)/$', my_model_detail_view),
    ( r'^admin/', include( admin.site.urls ) )
)
2 of 3
9

You can add your views directly to the AdminSite object, rather than to any particular ModelAdmin subclass which you then register.

The default AdminSite is accessed via django.contrib.admin.site, which is what you call register and autodiscover on. Instead of using this, you could create your own subclass and add your own views to it, and then register your models against that rather than the default one.

Top answer
1 of 8
39

You need to add your admin URL before the URL patterns of the admin itself:

urlpatterns = patterns('',
   url(r'^admin/preferences/$', TemplateView.as_view(template_name='admin/preferences/preferences.html')),
   url(r'^admin/', include('django.contrib.admin.urls')),
)

This way the URL won't be processed by Django's admin.

2 of 8
29

Years go by and still a relevant answer to this can be posted.

Using Django 1.10+ you can do:

security/admin.py (this is your app's admin file)

from django.contrib import admin
from django.conf.urls import url
from django.template.response import TemplateResponse
from security.models import Security


@admin.register(Security)
class SecurityAdmin(admin.ModelAdmin):

    def get_urls(self):

        # get the default urls
        urls = super(SecurityAdmin, self).get_urls()

        # define security urls
        security_urls = [
            url(r'^configuration/$', self.admin_site.admin_view(self.security_configuration))
            # Add here more urls if you want following same logic
        ]

        # Make sure here you place your added urls first than the admin default urls
        return security_urls + urls

    # Your view definition fn
    def security_configuration(self, request):
        context = dict(
            self.admin_site.each_context(request), # Include common variables for rendering the admin template.
            something="test",
        )
        return TemplateResponse(request, "configuration.html", context)

security/templates/configuration.html

{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %}

See Official ModelAdmin.get_urls description (make sure you select proper Django version, this code is valid for 1.10 above)

  • Note the use of get_urls() above.
  • This new admin page will be accessible under: https://localhost:8000/admin/security/configuration/
  • This page will be protected under admin login area
Discussions

python - Add custom page to django admin without a model - Stack Overflow
This is actually working but the problem is that with this solution I loose some apps from the Django admin interface (account, auth, socialaccounts, sites). ... Instead of replacing the AdminSite, try creating a custom ModelAdmin, for which you can define custom views: docs.djangoproject.... More on stackoverflow.com
🌐 stackoverflow.com
January 2, 2017
Django admin, section without "model"? - Stack Overflow
in the Django administration console, all section (menu links) come from models with database tables, but what would I need to do if I need a section without a corresponding model object (no database More on stackoverflow.com
🌐 stackoverflow.com
March 8, 2019
Django how to add admin page without using model - Stack Overflow
Yes, I have already tried that, it did not help. I cannot see my link in admin site. 2021-06-20T01:08:41.04Z+00:00 ... Yes Sorry I re read your post. I honestly dont know if there is a way to add custom links to the side bar, there are for models. Without modifying the template of course. More on stackoverflow.com
🌐 stackoverflow.com
Custom admin page
Hello, I created a page that allows me to modify some parameters in a json file. this page extends admin/base_site.html. fot the moment, i have added this to the urls path("admin/parameters/", views.all_parameters, n… More on forum.djangoproject.com
🌐 forum.djangoproject.com
4
0
January 27, 2024
🌐
Reddit
reddit.com › r/django › has anyone succeeded creating admin pages without a modeladmin ?
r/django on Reddit: Has anyone succeeded creating admin pages without a modeladmin ?
November 7, 2022 -

I’m trying to create a custom view instead of just model pages, it looks like all implementation for admin is closely tied to the models themselves.

The admin comes prebuilt with search, change form, autocomplete and plenty of apps that add functionality on top of it as well as builtin permissions support.

I find it purely logical that i do not want to be rewriting all that if i can extend the admin with just one or two views to satisfy my requirements for internal use.

Are there libs that extend or rethink the admin ?

🌐
YouTube
youtube.com › luke chaffey
Add custom page to django admin without a model - YouTube
python: Add custom page to django admin without a modelThanks for taking the time to learn more. In this video I'll go through your question, provide various...
Published   November 2, 2022
Views   421
🌐
PyPI
pypi.org › project › django-nonmodel-admin
django-nonmodel-admin · PyPI
September 6, 2021 - Allows to add sections to django admin which are not tied to any model. They can render some template for example.
      » pip install django-nonmodel-admin
    
Published   Sep 06, 2021
Version   0.1.1
Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 68051519 › django-how-to-add-admin-page-without-using-model
Django how to add admin page without using model - Stack Overflow
I needed to create a admin page which is not associated with any model. I have followed the below documentation. https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_urls ... from django.urls import path from django.http import HttpResponse class MyModelAdmin(admin.ModelAdmin): def get_urls(self): urls = super().get_urls() my_urls = [ path('statistic/', self.my_custom_view), ] return my_urls + urls def my_custom_view(request): .
🌐
Ovalerio
blog.ovalerio.net › archives › 2251
Django Friday Tips: Custom Admin Pages – Gonçalo Valério
At this point the custom page should be available at /admin/custom_page/, but users will not be able to find it, since no other link or button points to it. The final step is to include a link to the new page in the existing menu, in order for it to be easily accessible. First we need to replace the current index_template: ... class YourCustomAdminSite(admin.AdminSite): index_template = "admin/custom_index.html" ...
🌐
DEV Community
dev.to › daiquiri_team › creating-a-custom-page-in-django-admin-4pbd
Creating a custom page in Django Admin - DEV Community
September 16, 2022 - Django Admin allows you to manage your data without creating your own views. The primary use case of the Admin is CRUD operations. You can populate your local database with test data or change some real data in the production environment. Sometimes, you need some custom interfaces to perform your routines on the project. Fortunately, Django Admin has a lot of room for customization. In this guide, I'll show how to create a custom detail page in Django Admin.
🌐
Django Forum
forum.djangoproject.com › using django › the admin
Custom admin page - The Admin - Django Forum
January 27, 2024 - Hello, I created a page that allows me to modify some parameters in a json file. this page extends admin/base_site.html. fot the moment, i have added this to the urls path("admin/parameters/", views.all_parameters, n…
🌐
DataFlair
data-flair.training › blogs › django-admin-customization
Django Admin Customization - Step-by-step tutorial for novice learners - DataFlair
June 21, 2021 - Then we simply unregister the Group model in the 9th line. ... There are so many parts that can be changed from the front-end perspective. Like you can change the title written in the top-left corner of the web-page. Django administration can be changed to anything you like. Add this line in products/admin.py file. ... You can assign any string value you like. Just put the value in this variable. There is much more to the customization ...
🌐
Webforefront
webforefront.com › django › admincustomlayout.html
Django admin custom page layout, data & behaviors
Note Only the templates admin/index.html-admin/app_index.html, change_form.html, change_list.html, delete_confirmation.html, object_history.html and popup_response.html can be customized on a per app and per model basis. If you customize the Django admin admin/base.html template in your project with custom CSS or JavaScript files, these static resources take effect on every Django admin page.
Top answer
1 of 5
32

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:

2 of 5
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>&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 %}

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.

🌐
TestDriven.io
testdriven.io › blog › customize-django-admin
Customizing the Django Admin | TestDriven.io
August 24, 2023 - In this article, we'll look at how to customize Django's admin site through practical examples. We'll cover the built-in customization options as well as customization via third-party packages such as DjangoQL, django-import-export, and django-admin-interface.
🌐
Django
docs.djangoproject.com › en › 3.2 › intro › tutorial07
Writing your first Django app, part 7 | Django documentation | Django
November 25, 2020 - After all, the index is probably the most important page of the admin, and it should be easy to use. The template to customize is admin/index.html. (Do the same as with admin/base_site.html in the previous section – copy it from the default directory to your custom template directory). Edit the file, and you’ll see it uses a template variable called app_list. That variable contains every installed Django app.
🌐
Real Python
realpython.com › customize-django-admin-python
Customize the Django Admin With Python – Real Python
August 7, 2024 - In this tutorial, you'll learn how to customize Django's admin with Python. You'll use AdminModel objects to add display columns, calculate values, link to referring objects, and search and filter results. You'll also use template overriding to gain full control over the admin's HTML.
🌐
Rock and Null
paleblueapps.com › rockandnull › django-admin-custom-view
Django admin custom pages - Pale Blue
July 17, 2022 - Notice that custom admin pages are included before the regular admin URLs because the regular ones are quite permissive (documentation) Create an instance of your own custom admin site and use that instance to register any models with the admin site ...