To change
page in Django Admin, you can add the custom button which runs an admin action.
For example first, copy submit_line.html
from django/contrib/admin/templates/admin/submit_line.html
in your virtual environment to templates/admin/
, templates/admin/app1/
or templates/admin/app1/person/
to override it as shown below. *submit_line.html
in templates/admin/
, templates/admin/app1/
or templates/admin/app1/person/
applies to all admins in all apps, all admins in only app1
or only person
admin in only app1
respectively and you can see the original submit_line.html:
Django Project
|-core
| └-settings.py
|-app1
| |-models.py
| └-admin.py
|-app2
└-templates
└-admin
|-app1
| |-person
| | └-submit_line.html # Or
| |-model1
| |-model2
| └-submit_line.html # Or
|-app2
└-submit_line.html # Or
Then, add {% if custom_button %}<input ...
to submit_line.html
as shown below:
# "templates/admin/submit_line.html" Or
# "templates/admin/app1/submit_line.html" Or
# "templates/admin/app1/person/submit_line.html"
# ...
{% if show_delete_link and original %}
{% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %}
<p class="deletelink-box"><a href="{% add_preserved_filters delete_url %}" class="deletelink">{% translate "Delete" %}</a></p>
{% endif %}
{# ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ #}
{% if custom_button %}<input type="submit" value="{% translate 'Custom button' %}" name="_custom_button">{% endif %}
{# ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ #}
{% if show_save_as_new %}<input type="submit" value="{% translate 'Save as new' %}" name="_saveasnew">{% endif %}
{% if show_save_and_add_another %}<input type="submit" value="{% translate 'Save and add another' %}" name="_addanother">{% endif %}
{% if show_save_and_add_another %}<input type="submit" value="{% translate 'Save and add another' %}" name="_addanother">{% endif %}
# ...
And, set BASE_DIR / 'templates'
to 'DIRS'
in TEMPLATES
in settings.py
as shown below:
# "core/settings.py"
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BASE_DIR / 'templates' # Here
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
And, there is Person
model in models.py
as shown below:
# "app1/models.py"
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
And, there is Person
admin with uppercase
admin action in admin.py
as shown below:
# "app1/admin.py"
from django.contrib import admin, messages
from .models import Person
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
actions = ("uppercase", )
# Here
@admin.action(description='Make selected persons uppercase')
def uppercase(modeladmin, request, queryset):
for obj in queryset:
obj.name = obj.name.upper()
obj.save()
messages.success(request, "Successfully made uppercase!")
So, if you use uppercase
admin action as shown below:
Then, you can make the selected persons uppercase as shown below:
And, a custom button is not displayed yet on change
page as shown below:
Now, override change_view() and response_change() in Person
admin as shown below. *You can see the original change_view() and response_change():
# "app1/admin.py"
from django.contrib import admin, messages
from .models import Person
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
actions = ("uppercase", )
@admin.action(description='Make selected persons uppercase')
def uppercase(modeladmin, request, queryset):
for obj in queryset:
obj.name = obj.name.upper()
obj.save()
messages.success(request, "Successfully made uppercase!")
# Here
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context['custom_button'] = True
return self.changeform_view(request, object_id, form_url, extra_context)
# Here
def response_change(self, request, obj):
if "_custom_button" in request.POST:
queryset = self.get_queryset(request).filter(id=obj.id)
self.uppercase(request, queryset)
return super().response_change(request, obj)
Then, a custom button is displayed on change
page as shown below, then if you click on the custom button:
Then, you can make the person uppercase as shown below:
In addition, override add_view() and response_add() in Person
admin as shown below. *You can see the original add_view() and response_add():
# "app1/admin.py"
from django.contrib import admin, messages
from .models import Person
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
actions = ("uppercase", )
@admin.action(description='Make selected persons uppercase')
def uppercase(modeladmin, request, queryset):
for obj in queryset:
obj.name = obj.name.upper()
obj.save()
messages.success(request, "Successfully made uppercase!")
# Here
def add_view(self, request, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context['custom_button'] = True
return self.changeform_view(request, None, form_url, extra_context)
# Here
def response_add(self, request, obj, post_url_continue=None):
if "_custom_button" in request.POST:
queryset = self.get_queryset(request).filter(id=obj.id)
self.uppercase(request, queryset)
return super().response_add(request, obj, post_url_continue)
Then, a custom button is displayed on add
page as shown below, then if you click on the custom button:
Then, you can make the person uppercase as shown below: