Django admin full Customization step by step

Welcome to my blog, hey everyone in this article you learn how to customize the Django app and view in the article you will know how to register and unregister models from the admin view how to add filtering how to add a custom input field, and a button that triggers an action on all objects and even how to change the look of your app and page using the Django suit package let’s get started.

Database

you might see we have a Company,Language,Programmer model in the model supplier.

from django.db import models

class Company(models.Model):
    name = models.CharField(max_length=20)
    location = models.CharField(max_length=20)
    date_created = models.DateField() 

    def __str__(self):
        return self.name

class Language(models.Model):
    name = models.CharField(max_length=20)
    creator = models.CharField(max_length=20)
    paradigm = models.CharField(max_length=20)
    date_created = models.DateField()
    font = models.IntegerField()

    def __str__(self):
        return self.name

class Programmer(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    languages = models.ManyToManyField(Language)

    def __str__(self):
        return self.name

let’s, first of all, create a superuser so we can access the app and view and manage supply create superuser then we’ll choose a username that’s fine and then a simple password then we can run a server.

create super user in django

now we are on slash admin and we can login with our credentials and as you can see we haven’t yet registered this network model.

django administration view

so let’s go ahead and head to the app in the admin.py file first of all once you add all the models and import all the models from the models.py file now you can register and unregister your models admin.site.register(classname) and of course from the models import all models then we can call admin topside don’t register your models and as you can see we get our samples now and on the other side you can of course also unregistered models so let’s call a admin.site.unregister we’re just going to unregister the Groups model put this step by default so let’s imported from django.contrib.auth.models import group.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *

admin.site.register(Language)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)
register and unregister model in django admin

Read More : How Model Queries Work in Django

Read More : How to make a Chatbot in Python

Custom Titles of Django Admin

we can also do some more basic actions such as customizing this site header , site title, site URL, index_title you can see the changes in the screenshot:

change admin site header and title
how to change header,title,site_url,index_title in django
customize django admin login form
Django admin login form title change
django admin customize
view the changes in admin dashboard

next up let’s dive deeper into the customization of the models let’s see what you can also do is pass this register function an admin class create a class called LanguageAdmin which has two subplus from admin.ModelAdmin and we can specify a variety of attributes for example the exclude and I set this equal to date_created and now we of course have to pass this LanguageAdmin to our register function and you will see that the date_created now has disappeared in our view.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *


class LanguageAdmin(admin.ModelAdmin):
	exclude = ('date_created',)

admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)

Exclude in Django Admin

exclude view in django admin,exclude in django admin

we can also instead of specifying which fields too hard to specify which fields to show so let’s add fields equal to name, creator and now we only get the name, creator fields in the Django admin Language model view.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *


class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	fields = ('name','creator')

admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)

Fields in Django Admin

fields in django admin,fields in admin

we can also customize which fields are already previewed to us in this view so let’s go ahead and set list_display equal to name, creator, paradigm and you can see that instead of only getting the name we now also get to create or paradigm option displayed in our list view then there’s also the lists_filter and anything we can specify which options we would like to be able to filter by for example if we chose date_created you see that in our sidebar now we get this filter and we can for example stuff today or past seven days.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *


class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	# fields = ('name','creator')
	list_display = ('name','creator','font')
	list_filter = ('date_created',)

admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)
list display and list filter in django admin

now that we covered the basics let’s try to add some more functionality to this app in view and for this purpose let’s go to our models.py and add another field called font we are just going to set it to a model store integer field and now make sure to mention make migrations.

make migration with default value

Let’s like option 1 and we are just going to set the default font size for the objects that were already created to 12 and then migrate and what we now want to achieve is basically have input and right beside state a button and as soon as we hit that button we will use some JavaScript to get the value out of the input and then modify all of these snippets we have in a database to have exactly the font size which we entered in and all we have to do to change our template is basically go in admin.py file.

And set the change_list_template and now we can specify we’re not templates this custom template we’re going to create it in path admin/query/query_change_list.html now inside of our templates directory let’s go ahead and create a new folder admin and in the admin folder another folder called query and any we want to create this query_change_list.html and remember that query is my app name now when you click Language model in admin then redirect to new assign page.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *

class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	# fields = ('name','creator')
	list_display = ('name','creator','font')
	list_filter = ('date_created',)
	change_list_template = 'admin/query/query_change_list.html'
	
admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)

what we now have to do is extend from the change list of HTML template which thing, of course, provides us with by default and as soon as we do that we can then of course customize the blocks if we want to and that’s the approach we are going to use so extends and it’s located under admin/change_list.html we can now override the block which is called object-tools and then end block objects-tools when you add the block code in your page then model data showing in the blank page.

custom list template in django
custom page data
# add code in new page query_change_list.html

{% extends 'admin/change_list.html' %}
{% block object-tools %}

{% endblock object-tools %}

and we want to call block.super just to make sure that everything that is included by default will also be included so any we can create a new form and give it an ID fontsize-form and then the method is POST and of course because we are using a POST form we have to include CSRF token and then let’s include input with the name of fontsize and then class vTextfield and we go ahead and inspect the default input fields you will see that they have a class of vTextfield and that’s where we just get the same look.

add new field and button in django model template

then we want to have a button for actually submitting this entire form and the type of button is submitted and now we actually have to setup the script for changing the action on the form as soon as the field changes but don’t worry it’s going to be quite simple first we want to get the entire form from a DOM and then we want to add an event listener for as soon as the input changes the font size.

we want to call a function and in this function, we want to get the fontsize input field value now we have to change the action of the form to actually redirect us to the correct view as soon as we enter in the desired font size.

{% extends 'admin/change_list.html' %}

{% block object-tools %}
	<form id="fontsize-form" method="POST">
		{% csrf_token %}
		<input type="text" name="fontsize" class="vTextField">
		<button class="button" type="submit">Change Font Size</button>
	</form>
	<br>
	<script type="text/javascript">
		let fontsizeform = document.querySelector('#fontsize-form')
		fontsizeform.querySelector('input[name="fontsize"]').addEventListener('change',function(e){
			let fontSize = e.target.value
			fontsizeform.action = 'fontsize/'+fontSize+'/'
		})
	</script>


{% endblock object-tools %}

so we’re here and you will see that we have a new input field and a (change font size) button now inspect and you see form action so we are entering the value in the field is 20 and if we now click on the (change font size) and the reason why nothing happens is because of course, we haven’t yet set up an URL to live under that path we just specified in the action.

admin model column change view
view custom input field and button

and for this we need to go back to the admin.py and over at the function which is called get_urls so first we need to get the URLs that are there automatically by default close that URLs equal to super.get_urls() let us specify our custom URL and we want to create a new path inside of this which leads to font size than an integer argument which we call size and of course, this has to resemble our action from the form for it to work and as soon as that is hit we want to call the method self.change_font_size and then we can create a new function called change_font_size.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *
from django.urls import path

class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	# fields = ('name','creator')
	list_display = ('name','creator','font')
	list_filter = ('date_created',)
	change_list_template = 'admin/query/query_change_list.html'

	def get_urls(self):
		urls = super().get_urls()
		custom_urls = [
			path('fontsize/<int:size>/',self.change_font_size)
		]
		return custom_urls + urls

	def change_font_size(self,request,size):
		pass


admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)

now go back to admin section now let’s type in 20 and change font size and return none because of course in a function we haven’t returned anything.

function return none

let’s call self.model.objects.all and then call the update and set the font_size equal to size then we can also give a message to user self top message user passing the request and then (font size set successfully) then we want to return.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *
from django.urls import path
from django.http import HttpResponseRedirect

class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	# fields = ('name','creator')
	list_display = ('name','creator','font')
	list_filter = ('date_created',)
	change_list_template = 'admin/query/query_change_list.html'

	def get_urls(self):
		urls = super().get_urls()
		custom_urls = [
			path('fontsize/<int:size>/',self.change_font_size)
		]
		return custom_urls + urls

	def change_font_size(self,request,size):
		self.model.objects.all().update(font=size)
		return HttpResponseRedirect('../')

admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)

now we set font size as 32 and you see that now all of us Languages have font 32 awesome. now we set font size as 32 and you see that now all of us Langage have font 32 awesome that’s how you can add custom interactivity to your admin dashboard I think that’s quite cool go back admin.py and create a new function called font_size_html_display and this takes self and object and it’s a nice function we can use for this purpose.

change all objects values

so let’s return format_html and now we can type in just some HTML we want to display. so as it’s been a set e style equal to a fontsize then we have to include the object.font in here to have to correct font size for the individual object and then pixels after that let’s choose a closing span tag and between the span tag we, of course, want to have object.font still displayed because this, of course, should change we still want to see the number and we can import the function from django.utils import format_html so instead of now change the font in list_display into function font_html_display and if we refresh the page then you see them both display bigger because they are the same font size.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *
from django.urls import path
from django.http import HttpResponseRedirect
from django.utils.html import format_html

class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	# fields = ('name','creator')
	list_display = ('name','creator','font_html_display')
	list_filter = ('date_created',)
	change_list_template = 'admin/query/query_change_list.html'

	def get_urls(self):
		urls = super().get_urls()
		custom_urls = [
			path('fontsize/<int:size>/',self.change_font_size)
		]
		return custom_urls + urls

	def change_font_size(self,request,size):
		self.model.objects.all().update(font=size)
		self.message_user(request,'font size set successfully')
		return HttpResponseRedirect('../')

	def font_html_display(self,obj):
		font_s = obj.font
		return format_html('<span style="font-size:'+str(font_s)+'px">'+str(font_s)+'</span>')

admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)
change column design in django admin
change custom value on each fields

now you can add the condition we can set display_size equal to object.font if object.font is smaller equal to let’s say 50 or 30 else it’s going to be 30 and then let’s just use that value like this view in the screenshot.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *
from django.urls import path
from django.http import HttpResponseRedirect
from django.utils.html import format_html

class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	# fields = ('name','creator')
	list_display = ('name','creator','font_html_display')
	list_filter = ('date_created',)
	change_list_template = 'admin/query/query_change_list.html'

	def get_urls(self):
		urls = super().get_urls()
		custom_urls = [
			path('fontsize/<int:size>/',self.change_font_size)
		]
		return custom_urls + urls

	def change_font_size(self,request,size):
		self.model.objects.all().update(font=size)
		self.message_user(request,'font size set successfully')
		return HttpResponseRedirect('../')

	def font_html_display(self,obj):
		font_s = obj.font
		display_size = font_s if font_s <=30 else 30
		return format_html('<span style="font-size:'+str(display_size)+'px">'+str(display_size)+'</span>')

admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)
column value condition

if you want to include the name_preview as a read-only fields for example so let’s set read-only ones and you see the name field is read-only.

from django.contrib import admin
from django.contrib.auth.models import Group
from . models import *
from django.urls import path
from django.http import HttpResponseRedirect
from django.utils.html import format_html

class LanguageAdmin(admin.ModelAdmin):
	# exclude = ('date_created',)
	# fields = ('name','creator')
	list_display = ('name','creator','font_html_display')
	list_filter = ('date_created',)
	change_list_template = 'admin/query/query_change_list.html'
	readonly_fields = ('name',)

	def get_urls(self):
		urls = super().get_urls()
		custom_urls = [
			path('fontsize/<int:size>/',self.change_font_size)
		]
		return custom_urls + urls

	def change_font_size(self,request,size):
		self.model.objects.all().update(font=size)
		self.message_user(request,'font size set successfully')
		return HttpResponseRedirect('../')

	def font_html_display(self,obj):
		font_s = obj.font
		display_size = font_s if font_s <=30 else 30
		return format_html('<span style="font-size:'+str(display_size)+'px">'+str(display_size)+'</span>')

admin.site.register(Language,LanguageAdmin)
admin.site.register(Company)
admin.site.register(Programmer)
admin.site.unregister(Group)
read only field in django

we are going to be using a nice package called Django suit which is free to use for non-commercial use and the setup is quite simple we only have pip install django-suit here is Django suit documentation.

if you liked the article and share it with your friends and if you have any questions about writing queries in Django feel free to leave me a comment and I will answer the question you have and that’s about it hopefully I will see you again in another article.

Leave a Reply

Your email address will not be published. Required fields are marked *