avatarNuno Bispo

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

8817

Abstract

rovided'</span></pre></div><p id="8bd5">Customize the template used for respective admin views.</p><div id="60fc"><pre>admin.site.login_template = <span class="hljs-string">'my_custom_template/login.html'</span></pre></div><p id="68cd">By understanding and leveraging these configurations, you can enhance the backend experience for yourself and other administrators.</p><h1 id="913b">4. Admin Media Customization:</h1><p id="3652">While Django’s admin provides a visually appealing interface, you might want to style it according to your brand.</p><p id="b8a6">You can override the default CSS and JavaScript by creating a custom template.</p><p id="afe8">Customizing the media (CSS, JavaScript, etc.) of the Django admin site can greatly enhance its appearance and usability.</p><p id="5dc6">The Django admin interface uses its own set of media files.</p><p id="bd7a">However, sometimes you might want to override these or add your own to provide a unique look and feel or add additional functionalities.</p><h1 id="541f">Override CSS:</h1><p id="223e">If you want to change the appearance of the Django admin, one common approach is to override its CSS.</p><p id="ee69">a) Create a new CSS file, say <code>custom_admin.css</code>, and place it in a directory within one of your app's static directories. For instance, <code>myapp/static/myapp/css/custom_admin.css</code>.</p><p id="2264">b) Inside the <code>ModelAdmin</code> class or the <code>AdminSite</code> class, override the <code>Media</code> class:</p><div id="8777"><pre><span class="hljs-keyword">from</span> django.contrib <span class="hljs-keyword">import</span> admin

<span class="hljs-keyword">class</span> <span class="hljs-title class_">CustomAdminMedia</span>(admin.ModelAdmin): <span class="hljs-keyword">class</span> <span class="hljs-title class_">Media</span>: css = { <span class="hljs-string">'all'</span>: (<span class="hljs-string">'myapp/css/custom_admin.css'</span>,) } admin.site.register(MyModel, CustomAdminMedia)</pre></div><h1 id="a16a">Override JavaScript:</h1><p id="98c9">If you want to add new functionalities or change existing ones, you can add or override JavaScript.</p><p id="d63f">a) Create a new JS file, say <code>custom_admin.js</code>, and place it in a directory like <code>myapp/static/myapp/js/custom_admin.js</code>.</p><p id="ce94">b) Override the <code>Media</code> class in a similar manner:</p><div id="7cc1"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">CustomAdminJS</span>(admin.ModelAdmin): <span class="hljs-keyword">class</span> <span class="hljs-title class_">Media</span>: js = (<span class="hljs-string">'myapp/js/custom_admin.js'</span>,)

admin.site.register(MyModel, CustomAdminJS)</pre></div><h1 id="7d75">Combining CSS & JS:</h1><p id="cf53">You can combine both CSS and JS in the <code>Media</code> class.</p><div id="483c"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">CustomAdminMediaJS</span>(admin.ModelAdmin): <span class="hljs-keyword">class</span> <span class="hljs-title class_">Media</span>: css = { <span class="hljs-string">'all'</span>: (<span class="hljs-string">'myapp/css/custom_admin.css'</span>,) } js = (<span class="hljs-string">'myapp/js/custom_admin.js'</span>,)

admin.site.register(MyModel, CustomAdminMediaJS)</pre></div><h1 id="b3af">Admin Templates Customization:</h1><p id="612a">Beyond CSS and JS, you can also customize the templates that the Django admin uses. For instance, you can override <code>admin/base_site.html</code> to make broad changes to the admin site's layout.</p><p id="f5ea">To do this:</p><p id="1454">a) Within your project’s templates directory, create a directory named <code>admin</code>.</p><p id="9bd5">b) Inside the <code>admin</code> directory, mimic the path to the template you wish to override. For example, to override <code>base_site.html</code>, the path would be <code>templates/admin/base_site.html</code>.</p><p id="1a17">c) Now modify this template. For instance, to change the title:</p><div id="c8de"><pre>{% extends "admin/base.html" %} {% load i18n static %}

{% block title %} My Custom Admin {% endblock %}</pre></div><p id="5d09">Remember, when overriding templates, always extend from the original template (as shown above) to ensure you maintain all the necessary blocks and content.</p><p id="3b0b">By customizing media and templates, you can make the Django admin interface align more closely with the branding and functionality needs of your project.</p><h1 id="3b54">5. Admin Actions:</h1><p id="113e">Admin actions allow performing batch operations on selected items from the list view.</p><p id="613e">By default, Django provides a delete action, but you can write custom actions tailored to your needs.</p><p id="fdc5">They can be a powerful tool to enhance the usability of your admin site.</p><p id="be58">Let’s walk through some examples.</p><h1 id="b5c1">Marking Books as Published</h1><p id="7987">Let’s use a <code>Book</code> model with an <code>is_published</code> field:</p><div id="11ad"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">Book</span>(models.Model): title = models.CharField(max_length=<span class="hljs-number">200</span>) is_published = models.BooleanField(default=<span class="hljs-literal">False</span>)</pre></div><p id="4ee9">You want an action to mark selected books as published:</p><div id="40e9"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">mark_as_published</span>(<span class="hljs-params">modeladmin, request, queryset</span>): queryset.update(is_published=<span class="hljs-literal">True</span>) mark_as_published.short_description = <span class="hljs-string">"Mark selected books as published"</span></pre></div><p id="2c6d">Then, in your <code>ModelAdmin</code>, add the action:</p><div id="3b41"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): list_display = [<span class="hljs-string">'title'</span>, <span class="hljs-string">'is_published'</span>] actions = [mark_as_published]

admin.site.register(Book, BookAdmin)</pre></div><h1 id="16b6">Exporting Selected Items to CSV</h1><p id="ec8e">This is useful if you want to download data from the admin interface:</p><div id="de7a"><pre><span class="hljs-keyword">import</span> csv <span class="hljs-keyword">from</span> django.http <span class="hljs-keyword">import</span> HttpResponse

<span class="hljs-keyword">def</span> <span class="hljs-title function_">export_to_csv</span>(<span class="hljs-params">modeladmin, request, queryset</span>): response = HttpResponse(content_type=<span class="hljs-string">'text/csv'</span>) response[<span class="hljs-string">'Content-Disposition'</span>] = <span class="hljs-string">'attachment; filename="books.csv"'</span>

writer = csv.writer(response)
writer.writerow([<span class="hljs-string">'Title'</span>, <span class="hljs-string">'Published'</span>])
<span class="hljs-keyword">for</span> book <span class="hljs-keyword">in</span> queryset:
    writer.writerow([book.title, book.is_published])

<span class="hljs-keyword">return</span> response

export_to_csv.short_description = <span class="hljs-string">"Export selected books to CSV"</span></pre></div><p id="1552">Then, just like the previous example, add the action to <code>ModelAdmin</code>:</p><div id="cf23"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): list_display = [<span class="hljs-string">'title'</span>, <span class="hljs-string">'is_published'</span>] actions = [mark_as_published, export_to_csv]

admin.site.register(Book, BookAdmin)</pre></div><h1 id="331a">Custom Confirmation Page for Admin Action</h1><p id="5ca7">Sometimes, you might want to present a confirmation page before an action is performed:</p><div id="bf90"><pre><span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path <span class="hljs-keyword">from</span> django.shortcuts <span class="hljs-keyword">import</span> render

<span class="hljs-keyword">def</span> <span class="hljs-title function_">delete_selected_books</span>(<span class="hljs-params">modeladmin, request, queryset</span>): <span class="hljs-keyword">if</span> <span class="hljs-string">'apply'</span> <span class="hljs-keyword">in</span> request.POST: queryset.delete() modeladmin.message_user(request, <span class="hljs-string">"Deleted selected books"</span>) <span class="hljs-keyword">return</span> <span class="hljs-keyword">return</span> render(request, <span class="hljs-string">'adm

Options

in/confirm_delete.html'</span>, {<span class="hljs-string">'books'</span>: queryset}) delete_selected_books.short_description = <span class="hljs-string">"Delete selected books with confirmation"</span> <span class="hljs-comment"># Inside the ModelAdmin class:</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): list_display = [<span class="hljs-string">'title'</span>, <span class="hljs-string">'is_published'</span>] actions = [mark_as_published, export_to_csv, delete_selected_books]

<span class="hljs-keyword">def</span> <span class="hljs-title function_">get_urls</span>(<span class="hljs-params">self</span>):
    urls = <span class="hljs-built_in">super</span>().get_urls()
    custom_urls = [
        path(<span class="hljs-string">'delete_selected/'</span>, self.admin_site.admin_view(delete_selected_books), name=<span class="hljs-string">'delete_selected_books'</span>),
    ]
    <span class="hljs-keyword">return</span> custom_urls + urls</pre></div><p id="6aa8">In this example, before books are deleted, the admin user will be directed to a confirmation page (<code>confirm_delete.html</code>).</p><p id="7867">This allows for an extra layer of validation before performing destructive actions.</p><h1 id="4caf">6. Advanced Features:</h1><ul><li><b>form</b>: Override the default form used for the edit page.</li><li><b>filter_horizontal</b> and <b>filter_vertical</b>: Widgets to manage many-to-many relationships.</li><li><b>readonly_fields</b>: Fields that should be displayed as read-only.</li><li><b>save_as</b>: Allows adding objects via duplication.</li><li><b>save_on_top</b>: Show save buttons at both the top and bottom of the change form.</li></ul><p id="3b80">Let’s dive into each of these advanced features:</p><h1 id="1c1b">form — Override the default form used for the edit page.</h1><p id="73bf">You can define a custom form for the admin page of a model.</p><p id="ee18">This can be useful if you want to modify field ordering, add custom validation, or adjust widgets.</p><div id="ffca"><pre><span class="hljs-keyword">from</span> django <span class="hljs-keyword">import</span> forms

<span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> Book

<span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdminForm</span>(forms.ModelForm): <span class="hljs-keyword">class</span> <span class="hljs-title class_">Meta</span>: model = Book fields = <span class="hljs-string">'all'</span> widgets = { <span class="hljs-string">'title'</span>: forms.TextInput(attrs={<span class="hljs-string">'class'</span>: <span class="hljs-string">'custom-class'</span>}), } <span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): form = BookAdminForm admin.site.register(Book, BookAdmin)</pre></div><h1 id="83f7">filter_horizontal and filter_vertical — Widgets to manage many-to-many relationships.</h1><p id="30e0">These widgets are designed to make it more user-friendly to manage many-to-many relationships.</p><p id="ed3a">Assuming a model <code>Author</code> and modifying our <code>Book</code> model to have a many-to-many relationship:</p><div id="a46c"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">Author</span>(models.Model): name = models.CharField(max_length=<span class="hljs-number">100</span>)

<span class="hljs-keyword">class</span> <span class="hljs-title class_">Book</span>(models.Model): title = models.CharField(max_length=<span class="hljs-number">200</span>) authors = models.ManyToManyField(Author)</pre></div><p id="0ce3">In the <code>ModelAdmin</code>:</p><div id="3947"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): filter_horizontal = (<span class="hljs-string">'authors'</span>,)

admin.site.register(Book, BookAdmin)</pre></div><p id="0005">Use <code>filter_vertical</code> instead of <code>filter_horizontal</code> if you prefer a vertical layout.</p><h1 id="4cf4">readonly_fields -Fields that should be displayed as read-only.</h1><p id="d65b">This ensures some fields can be displayed but not edited.</p><div id="80f3"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): readonly_fields = (<span class="hljs-string">'title'</span>,)

admin.site.register(Book, BookAdmin)</pre></div><h1 id="5f73">save_as — Allows adding objects via duplication.</h1><p id="6d15">When set to <code>True</code>, this provides a "Save as new" button on the change form, allowing admins to save a duplicate of the existing object.</p><div id="ae19"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): save_as = <span class="hljs-literal">True</span>

admin.site.register(Book, BookAdmin)</pre></div><h1 id="ee15">save_on_top — Show save buttons at both the top and bottom of the change form.</h1><p id="c2a4">This can be useful for long forms:</p><div id="ce8e"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">BookAdmin</span>(admin.ModelAdmin): save_on_top = <span class="hljs-literal">True</span>

admin.site.register(Book, BookAdmin)</pre></div><p id="6104">By leveraging these advanced features of Django’s admin interface, you can tailor the admin backend to be more user-friendly and efficient for your project’s specific needs.</p><h1 id="9309">Conclusion:</h1><p id="3b89">Django Admin’s configuration options are a testament to its flexibility and adaptability.</p><p id="ace6">Whether you’re looking to make simple tweaks or overhaul the entire interface, Django provides you with the tools to make it happen.</p><p id="6581">Properly utilized, the Django Admin interface can save developers countless hours, allowing them to focus on building unique features and improving their applications.</p><p id="8e5b">Thank you for reading and I will see you on the Internet.</p><p id="4e4e">Follow me on Twitter: <a href="https://twitter.com/DevAsService">https://twitter.com/DevAsService</a></p><p id="3cee">Check out my website at: <a href="https://developer-service.io/">https://developer-service.io/</a></p><p id="5ecb">Check out other articles that might interest you:</p><div id="2121" class="link-block"> <a href="https://readmedium.com/django-otp-strengthening-authentication-and-safeguarding-web-applications-ca162d85279f"> <div> <div> <h2>Django-OTP: Strengthening Authentication and Safeguarding Web Applications</h2> <div><h3>Enhancing Security and User Protection with OTP-based Authentication in Django</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*la_C2sechHy1DlNK)"></div> </div> </div> </a> </div><div id="1c6a" class="link-block"> <a href="https://readmedium.com/mastering-image-processing-in-django-with-django-imagekit-a-comprehensive-guide-5af5c23fdab0"> <div> <div> <h2>Mastering Image Processing in Django with Django Imagekit: A Comprehensive Guide</h2> <div><h3>Unleash the Power of Django Imagekit for Seamless Image Manipulation and Optimization in Your Django Projects</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*Mb0Vdg3-IiwT8k5c)"></div> </div> </div> </a> </div><div id="f436" class="link-block"> <a href="https://readmedium.com/securing-django-a-comprehensive-guide-to-best-practices-and-common-vulnerabilities-76f93d2ceeb0"> <div> <div> <h2>Securing Django: A Comprehensive Guide to Best Practices and Common Vulnerabilities</h2> <div><h3>Taking Advantage of Django’s Robust Security Features and Implementing Proactive Measures for a Fortified Web…</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*j_VPPVzlcM0WFudi)"></div> </div> </div> </a> </div><p id="8d8e">If you want to stay updated when I post a new article, you can <a href="https://blog.developer-service.io/subscribe">signup for my free newsletter</a>!</p></article></body>

Django Admin Configuration Options

Photo by Sear Greyson / Unsplash

Django, the high-level web framework written in Python, has made it easy for developers to build robust web applications quickly.

One of Django’s most powerful features is its built-in admin interface, which allows developers and site administrators to manage application data without having to build custom CRUD (Create, Read, Update, Delete) interfaces.

This article will delve deep into the configuration options for Django Admin.

1. Basic Setup:

Before diving into configuration options, ensure you’ve included 'django.contrib.admin' and 'django.contrib.auth' in the INSTALLED_APPS settings of your project.

Also, you should wire up the admin URL in your project’s URL configuration.

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

2. ModelAdmin Options:

Once your models are created, you can register them with the admin interface. The ModelAdmin class provides numerous options to customize their representation:

  • list_display: Define which fields of the model should be displayed on the object list page.
  • list_filter: Adds filter sidebar for fields specified.
  • search_fields: Provide a search bar allowing users to search model fields.
  • ordering: Specify the default sorting order.
  • date_hierarchy: Adds date-based drill-down navigation.
  • list_editable: Allows in-place editing of specified fields directly from the list view.
  • exclude: Fields to be excluded from the form on the change page.
  • fields: Control the layout of the admin form.
  • inlines: Used for editing related models inline.

Let’s illustrate some of the ModelAdmin options using an example model Book:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=200)
    published_date = models.DateField()
    is_published = models.BooleanField(default=True)
    genre = models.CharField(max_length=50, choices=[
        ('fiction', 'Fiction'),
        ('non-fiction', 'Non-fiction'),
        ('biography', 'Biography'),
        ('children', 'Children'),
    ])

For this model, we’ll now create a custom BookAdmin class with various configuration options and register it with the admin site.

To show specific fields in the object list page:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date', 'is_published')

To add a filter sidebar:

class BookAdmin(admin.ModelAdmin):
    list_filter = ('is_published', 'genre', 'published_date')

To search specific fields:

class BookAdmin(admin.ModelAdmin):
    search_fields = ['title', 'author']

Default ordering:

class BookAdmin(admin.ModelAdmin):
    ordering = ['-published_date']

Date-based drill-down navigation:

class BookAdmin(admin.ModelAdmin):
    date_hierarchy = 'published_date'

In-place editing:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date', 'is_published')
    list_editable = ['is_published']

Note: Fields in list_editable must also be in list_display.

Excluding fields from the form:

class BookAdmin(admin.ModelAdmin):
    exclude = ('published_date',)

To customize the layout:

class BookAdmin(admin.ModelAdmin):
    fields = ('title', 'author', ('genre', 'is_published'), 'published_date')

Finally, register the model with its custom admin configuration:

admin.site.register(Book, BookAdmin)

These are just a few of the various options available in ModelAdmin.

By integrating these options, you can customize the Django admin interface according to the needs of your application, streamlining the management of your data.

3. Admin Site Configuration:

The AdminSite class provides various attributes and methods to customize the look and feel of the admin site at a higher level:

  • site_header: Customize the text that appears at the top of the admin index page.
  • site_title: Set the title text for admin pages.
  • index_title: Title for the admin site’s home page.
  • site_url: URL for the “View site” link at the top of each admin page.
  • empty_value_display: Set a custom display string for empty fields.
  • login_template, index_template, etc.: Customize the template used for respective admin views.

Here’s how you can set these options:

Customize the text at the top of the admin index page.

from django.contrib import admin

admin.site.site_header = "My Custom Admin Portal"

Change the title text for admin pages.

admin.site.site_title = "My Site Admin"

Title for the admin site’s home page.

admin.site.index_title = "Welcome to the Custom Admin Area"

URL for the “View site” link at the top of each admin page. Set it to None to remove the link.

admin.site.site_url = "/my-custom-site-url/"

Set a custom display string for fields that are empty.

admin.site.empty_value_display = 'Not Provided'

Customize the template used for respective admin views.

admin.site.login_template = 'my_custom_template/login.html'

By understanding and leveraging these configurations, you can enhance the backend experience for yourself and other administrators.

4. Admin Media Customization:

While Django’s admin provides a visually appealing interface, you might want to style it according to your brand.

You can override the default CSS and JavaScript by creating a custom template.

Customizing the media (CSS, JavaScript, etc.) of the Django admin site can greatly enhance its appearance and usability.

The Django admin interface uses its own set of media files.

However, sometimes you might want to override these or add your own to provide a unique look and feel or add additional functionalities.

Override CSS:

If you want to change the appearance of the Django admin, one common approach is to override its CSS.

a) Create a new CSS file, say custom_admin.css, and place it in a directory within one of your app's static directories. For instance, myapp/static/myapp/css/custom_admin.css.

b) Inside the ModelAdmin class or the AdminSite class, override the Media class:

from django.contrib import admin

class CustomAdminMedia(admin.ModelAdmin):
    class Media:
        css = {
            'all': ('myapp/css/custom_admin.css',)
        }
admin.site.register(MyModel, CustomAdminMedia)

Override JavaScript:

If you want to add new functionalities or change existing ones, you can add or override JavaScript.

a) Create a new JS file, say custom_admin.js, and place it in a directory like myapp/static/myapp/js/custom_admin.js.

b) Override the Media class in a similar manner:

class CustomAdminJS(admin.ModelAdmin):
    class Media:
        js = ('myapp/js/custom_admin.js',)

admin.site.register(MyModel, CustomAdminJS)

Combining CSS & JS:

You can combine both CSS and JS in the Media class.

class CustomAdminMediaJS(admin.ModelAdmin):
    class Media:
        css = {
            'all': ('myapp/css/custom_admin.css',)
        }
        js = ('myapp/js/custom_admin.js',)

admin.site.register(MyModel, CustomAdminMediaJS)

Admin Templates Customization:

Beyond CSS and JS, you can also customize the templates that the Django admin uses. For instance, you can override admin/base_site.html to make broad changes to the admin site's layout.

To do this:

a) Within your project’s templates directory, create a directory named admin.

b) Inside the admin directory, mimic the path to the template you wish to override. For example, to override base_site.html, the path would be templates/admin/base_site.html.

c) Now modify this template. For instance, to change the title:

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

{% block title %} My Custom Admin {% endblock %}

Remember, when overriding templates, always extend from the original template (as shown above) to ensure you maintain all the necessary blocks and content.

By customizing media and templates, you can make the Django admin interface align more closely with the branding and functionality needs of your project.

5. Admin Actions:

Admin actions allow performing batch operations on selected items from the list view.

By default, Django provides a delete action, but you can write custom actions tailored to your needs.

They can be a powerful tool to enhance the usability of your admin site.

Let’s walk through some examples.

Marking Books as Published

Let’s use a Book model with an is_published field:

class Book(models.Model):
    title = models.CharField(max_length=200)
    is_published = models.BooleanField(default=False)

You want an action to mark selected books as published:

def mark_as_published(modeladmin, request, queryset):
    queryset.update(is_published=True)
mark_as_published.short_description = "Mark selected books as published"

Then, in your ModelAdmin, add the action:

class BookAdmin(admin.ModelAdmin):
    list_display = ['title', 'is_published']
    actions = [mark_as_published]

admin.site.register(Book, BookAdmin)

Exporting Selected Items to CSV

This is useful if you want to download data from the admin interface:

import csv
from django.http import HttpResponse

def export_to_csv(modeladmin, request, queryset):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="books.csv"'
    
    writer = csv.writer(response)
    writer.writerow(['Title', 'Published'])
    for book in queryset:
        writer.writerow([book.title, book.is_published])
    
    return response
export_to_csv.short_description = "Export selected books to CSV"

Then, just like the previous example, add the action to ModelAdmin:

class BookAdmin(admin.ModelAdmin):
    list_display = ['title', 'is_published']
    actions = [mark_as_published, export_to_csv]

admin.site.register(Book, BookAdmin)

Custom Confirmation Page for Admin Action

Sometimes, you might want to present a confirmation page before an action is performed:

from django.urls import path
from django.shortcuts import render

def delete_selected_books(modeladmin, request, queryset):
    if 'apply' in request.POST:
        queryset.delete()
        modeladmin.message_user(request, "Deleted selected books")
        return
    return render(request, 'admin/confirm_delete.html', {'books': queryset})
delete_selected_books.short_description = "Delete selected books with confirmation"
# Inside the ModelAdmin class:
class BookAdmin(admin.ModelAdmin):
    list_display = ['title', 'is_published']
    actions = [mark_as_published, export_to_csv, delete_selected_books]
    
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('delete_selected/', self.admin_site.admin_view(delete_selected_books), name='delete_selected_books'),
        ]
        return custom_urls + urls

In this example, before books are deleted, the admin user will be directed to a confirmation page (confirm_delete.html).

This allows for an extra layer of validation before performing destructive actions.

6. Advanced Features:

  • form: Override the default form used for the edit page.
  • filter_horizontal and filter_vertical: Widgets to manage many-to-many relationships.
  • readonly_fields: Fields that should be displayed as read-only.
  • save_as: Allows adding objects via duplication.
  • save_on_top: Show save buttons at both the top and bottom of the change form.

Let’s dive into each of these advanced features:

form — Override the default form used for the edit page.

You can define a custom form for the admin page of a model.

This can be useful if you want to modify field ordering, add custom validation, or adjust widgets.

from django import forms
from .models import Book

class BookAdminForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = '__all__'
        widgets = {
            'title': forms.TextInput(attrs={'class': 'custom-class'}),
        }
class BookAdmin(admin.ModelAdmin):
    form = BookAdminForm
admin.site.register(Book, BookAdmin)

filter_horizontal and filter_vertical — Widgets to manage many-to-many relationships.

These widgets are designed to make it more user-friendly to manage many-to-many relationships.

Assuming a model Author and modifying our Book model to have a many-to-many relationship:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=200)
    authors = models.ManyToManyField(Author)

In the ModelAdmin:

class BookAdmin(admin.ModelAdmin):
    filter_horizontal = ('authors',)

admin.site.register(Book, BookAdmin)

Use filter_vertical instead of filter_horizontal if you prefer a vertical layout.

readonly_fields -Fields that should be displayed as read-only.

This ensures some fields can be displayed but not edited.

class BookAdmin(admin.ModelAdmin):
    readonly_fields = ('title',)

admin.site.register(Book, BookAdmin)

save_as — Allows adding objects via duplication.

When set to True, this provides a "Save as new" button on the change form, allowing admins to save a duplicate of the existing object.

class BookAdmin(admin.ModelAdmin):
    save_as = True

admin.site.register(Book, BookAdmin)

save_on_top — Show save buttons at both the top and bottom of the change form.

This can be useful for long forms:

class BookAdmin(admin.ModelAdmin):
    save_on_top = True

admin.site.register(Book, BookAdmin)

By leveraging these advanced features of Django’s admin interface, you can tailor the admin backend to be more user-friendly and efficient for your project’s specific needs.

Conclusion:

Django Admin’s configuration options are a testament to its flexibility and adaptability.

Whether you’re looking to make simple tweaks or overhaul the entire interface, Django provides you with the tools to make it happen.

Properly utilized, the Django Admin interface can save developers countless hours, allowing them to focus on building unique features and improving their applications.

Thank you for reading and I will see you on the Internet.

Follow me on Twitter: https://twitter.com/DevAsService

Check out my website at: https://developer-service.io/

Check out other articles that might interest you:

If you want to stay updated when I post a new article, you can signup for my free newsletter!

Django
Technology
Programming
Python
Admin
Recommended from ReadMedium