How to customize the django built-in admin panel using jazzmin
I have installed the jazzmin , and it has been integerated on the django built-in admin panel , but what i need is to customize it , I do not know how to do it , i have used the jazzmin github repo templates but i can not seem to integerate them but I also pasted the code from the jazzmin offical webiste in the Settings.py it work , it showed little change in the UI of thee built in admin panel , i can not seem to know what to do , i am stuck , and my brain went on a trip cuz no ideas are coming
First, get the relevant HTML templates from the Django source repository and place them inside your project's templates directory, preserving the exact same directory structure and file names.
If you also need to customize the styling, you can do the same thing with the static files. In my case, I created separate static files and included them in base.html after the existing stylesheets. However, a cleaner approach is usually to copy the relevant admin static files into your own static directory and customize them there.
If you only need to change the appearance or behavior of a specific admin page, you don't necessarily need to override everything. You can create a template specifically for that page and override only the blocks you need.
For example, suppose you have a model named AppBoo and you want to customize its change list page.
You can create the following directory:
templates/
└── admin/
└── app_boo/
└── change_list.html
The important part is that the directory and file names must match Django's expected template resolution structure.
Then, in change_list.html, extend the original admin template and override only the blocks you need. For example:
{% extends "admin/change_list.html" %}
{% load i18n %}
{% block extra_style %}
<style>
.btn-copy {
top: 0;
right: 0;
height: 100%;
}
</style>
{% endblock %}
{% block modal %}
<!-- ---- FILL ORDER MODAL ---- -->
<div class="modal fade modal-lg" id="custom_page_copy_link_modal" tabindex="-1"
aria-labelledby="admin_action_withdraw_modal"
aria-modal="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{% trans 'Copy Link' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="{% trans 'Close' %}"></button>
</div>
<div class="modal-body">
<div class="container">
<div class="d-flex justify-content-center align-items-center">
<fieldset>
<input type="radio" value="ar" name="copy_lang"
id="ar_lang_modal" checked>
<label for="ar_lang_modal">{% trans 'Arabic' %}</label>
</fieldset>
<fieldset class="mx-4">
<input type="radio" value="en" name="copy_lang"
id="en_lang_modal">
<label for="en_lang_modal">{% trans 'English' %}</label>
</fieldset>
</div>
<div class="mx-auto text-center mt-3">
<input type="hidden" id="copy_link_en">
<input type="hidden" id="copy_link_ar">
</div>
<div class="container">
<div class="alert alert-success mt-4 position-relative pe-5"
id="copy_link_result_sec">
<h5 class="text-truncate" id="link_res_text"></h5>
<button class="btn position-absolute btn-copy"
type="button"
onclick="set_link(true)">
{% trans 'copy' %}
</button>
</div>
<a href="#"
id="link_res_link"
target="_blank"
class="mt-1 btn btn-info w-100">
{% trans 'Open In New Tab' %}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extrajs %}
<script>
$("input[name='copy_lang']").on('change', () => {
set_link(false);
});
const copy_link_set = (ar_link, en_link) => {
$("#copy_link_ar").val(ar_link);
$("#copy_link_en").val(en_link);
set_link(false);
};
const set_link = (copy = false) => {
const lang = $("input[name='copy_lang']:checked").val();
const ar_link = $("#copy_link_ar").val();
const en_link = $("#copy_link_en").val();
const result_text = $("#link_res_text");
let result_text_value;
if (lang === "en") {
result_text_value = en_link;
} else {
result_text_value = ar_link;
}
navigator.clipboard.writeText(result_text_value);
if (copy) {
$(result_text).html("{% trans 'Successfully Copied' %}");
setTimeout(() => {
$(result_text).html(result_text_value);
}, 1500);
} else {
$(result_text).html(result_text_value);
}
$("#link_res_link").attr('href', result_text_value);
};
</script>
{% endblock %}
This way, Django's template inheritance does most of the work for you. You keep the original admin functionality and only override the specific blocks that need to be customized.
The same principle applies to other admin templates such as change_form.html, delete_confirmation.html, object_history.html, etc. The key is to preserve Django's expected template hierarchy so that its template loader can find your override before falling back to the built-in admin template.