Django. Своя кнопка в админке.
В Django, как мы знаем, очень много уже реализованного функционала идет сразу в комплекте, так сказать, «из коробки». Сделано это разработчиками для нашего удобства и, соответственно, для простоты разработки пользовательских проектов на данном вебфреймворке. За что, конечно-же, отдельное спасибо разработчикам.
Давайте рассмотрим админку. Админ панель в Django представляет из себя своего рода пункт управления для администратора, где можно созвать, редактировать, удалять модели, объединять в группы созданных пользователей, назначать им права и многое другое. Для того, чтобы попасть в админку, необходимо пройти по адресу http://127.0.0.1:8000/admin/
. Далее мы попадем на страницу авторизации. Но для того, чтобы мы успешно авторизовались, необходимо заранее создать суперпользователя (собственно, самого админа).
python manage.py createsuperuser
- где мы указываем username , email и password с подтверждением.
Теперь мы можем успешно пройти авторизацию и попасть в админку с возможностью использовать весь функционал администратора.
Но в процессе разработки бывают ситуации, когда необходимо «подогнать» под себя, или кастомизировать стандартную админку Django. Сейчас я не буду углубляться во все способы и возможности это сделать (например, через наследование от класса admin.ModelAdmin
и переопределение поля для отображения полей модели, добавление фильтров и поиска и т.д.).
Сегодня я хотел бы рассказать, как быстро сделать свою пользовательскую кнопку прямо в админ страничке, по нажатию на которую происходил бы GET запрос, и нам представлялся бы пользовательский шаблон HTML (ну или какой-либо user interface).
Итак, для добавления своей кнопки нам необходимо убедиться, что наше приложение указано в settings.py
в списке NSTALLED_APPS
. Далее нам необходимо создать «расширение» для стандартного админ-шаблона change_form.html
. Разместить его можно по одной из следующих схем:
# Шаблон применяется ко всем change_form:
myproject/myapp/templates/admin/change_form.html
# Шаблон применяется к change_lists моего приложения myapp:
myproject/myapp/templates/admin/myapp/change_form.html
# Шаблон применяется к change_list моего приложения myapp и только для модели mymodel:
myproject/myapp/templates/admin/myapp/mymodel/change_form.html
Тут стоит сделать оговорку, и проверить правильно ли размещена директория templates. Она должна быть на одном уровне дерева каталогов с файлом manage.py
и нашей базой данных bd.sqlite3
.
Если, все же, после размещения шаблона по одному из указанных путей, шаблон не определяется Django автоматически, то можно прописать его принудительно в виде атрибута внутри класса админ-модели в admin.py
:
class MyModelAdmin(admin.ModelAdmin):
#...
change_list_template = "path/to/change_form.html"
Затем, нам необходимо отредактировать содержимое нашего расширения для стандартного change_form.html
:
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block submit_buttons_bottom %}
<input value="Button_title" type="button" onclick="location.href='{% url 'admin:user_view' %}'" />
{{ block.super }}
{% endblock %}
Данным кодом мы расширяем стандартный джанговский функционал, который внедрит нашу кнопку с именем Button_title
, и при нажатии отправит GET запрос для user_view
.
Всю механику отлова url и подстановки под этот url нашей пользовательской user_view
будем делать внутри админ-модели в методе get_urls()
.
Ниже в моем примере, использовался шаблон для расширения (отрисовки кнопки) – my_change_form.html
, пользовательская функция-вьюха - get_repayment()
:
class RepaymentAdmin(admin.ModelAdmin):
class Meta:
model = Repayment
list_display = ['customer', 'payment_summ', 'create_data', 'processing_date', 'status', 'account_number'] # определяем отображаемые поля модели Repayment внутри админ-модели RepaymentAdmin
def get_urls(self):
# метод обработки url, с подстановкой необходимой view.
urls = super(RepaymentAdmin, self).get_urls()
custom_urls = [
path('get/', self.admin_site.admin_view(self.get_repayment), name='repayment_view'), ]
return custom_urls + urls
def get_repayment(self, request):
# внутри данного метода (который подставится под запрос url), мы выполним какую-либо логику, и вернем в ответ пользовательский шаблон index.html
return render(request, 'index.html', locals())
# переопределяем атрибут для принудительного использования нашего шаблона:
change_form_template = 'admin/myapp/repayment/my_change_form.html'
В итоге у нас должна отрисоваться пользовательская кнопка внутри админ страницы в модели пользователя, при нажатии на которую отработает метод def get_repayment
и вернет пользовательский HTML шаблон: