Как добавить кнопку на страницу просмотра списка изменений администратора django

Я хотел бы добавить кнопку рядом с кнопкой «добавить» в представлении списка в модели для моей модели, а затем создать функцию представления, в которой я буду делать свои вещи, а затем перенаправляю пользователя обратно в представление списка.

Я проверил, как перегрузить шаблон администратора, но я все еще не знаю, где мне разместить функцию просмотра, где я буду делать свои вещи, и как я могу зарегистрировать это представление в URL-адресах администратора.

Также есть вопрос о безопасности. Я хотел бы, чтобы это действие было внутри администратора, поэтому, если вы не вошли в систему, вы не можете его использовать.

Я нашел это, но не знаю, правильный ли это путь: http://www.stavros.io/posts/how-to-extend-the-django-admin-site-with-custom/


person n1_    schedule 29.07.2013    source источник


Ответы (2)


Когда несколько приложений предоставляют разные версии одного и того же ресурса (шаблон, статический файл, команда управления, перевод), приложение, указанное первым в INSTALLED_APPS, имеет приоритет. - Документация Django по INSTALLED_APPS

Убедитесь, что ваше приложение указано перед 'django.contrib.admin' в INSTALLED_APPS.

Создайте шаблон change_list.html в одном из следующих каталогов:

# Template applies to all change lists.
myproject/myapp/templates/admin/change_list.html      

# Template applies to change lists in myapp.
myproject/myapp/templates/admin/myapp/change_list.html  

# Template applies to change list in myapp and only to the Foo model.
myproject/myapp/templates/admin/myapp/foo/change_list.html  

Шаблон должен быть выбран автоматически, но в случае, если он не находится ни на одном из путей, перечисленных выше, вы также можете указать на него с помощью атрибута модели администратора:

class MyModelAdmin(admin.ModelAdmin):

    #... 
    change_list_template = "path/to/change_list.html"

Вы можете просмотреть содержимое исходного файла change_list.html, который находится в path/to/your/site-packages/django/contrib/admin/templates/admin/change_list.html. Другой ответ также показывает, как отформатировать шаблон. Николай Сайко покажет вам, как переопределить соответствующие части, используя extends и super. Резюме:

{% extends "admin/change_list.html" %} {% load i18n %} 
{% block object-tools-items %}
    {{ block.super }}
    <li>
        <a class="historylink" href="...">My custom admin page</a>
    </li>
{% endblock %}

Давайте заполним href="..." URL-адресом. Имена URL-адресов администратора находятся в пространстве имен admin, и их можно найти следующим образом:

{% url 'admin:custom_view' %}

Когда вы добавляете кнопку в change_form.html, вы, возможно, захотите передать текущий идентификатор объекта:

{% url 'admin:custom_view' original.pk %}

Теперь создайте собственный вид. Это может быть обычное представление (как и другие страницы вашего веб-сайта) или настраиваемое представление администратора в admin.py. Метод get_urls в ModelAdmin возвращает URL-адреса, которые будут использоваться для этого ModelAdmin, так же, как и URLconf. Поэтому вы можете расширить их, как описано в диспетчере URL-адресов:

class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super(MyModelAdmin, self).get_urls()
        my_urls = patterns('',
            url(r'^my_view/$', self.my_view, name="custom_view")
        )
        return my_urls + urls

    def my_view(self, request):
        # custom view which should return an HttpResponse
        pass

    # In case your template resides in a non-standard location
    change_list_template = "path/to/change_list.html"

Прочтите документацию о том, как установить разрешения для представления в ModelAdmin: https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_urls

Вы можете защитить свое представление и предоставить доступ только пользователям со статусом персонала:

from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def my_view(request):
    ...

Вы также можете проверить request.user.is_active и обработать неактивных пользователей.

Обновление: воспользуйтесь преимуществами фреймворка и настройте как можно меньше. Часто действия могут быть хорошей альтернативой: https://docs.djangoproject.com/en/1.5/ref/contrib/admin/actions/.

Обновление 2: я удалил пример JS, чтобы добавить кнопку на стороне клиента. Если вам это нужно, просмотрите исправления.

person allcaps    schedule 29.07.2013
comment
@allcaps - ваше решение отлично подходит для этого требования наличия кнопки для одного ModelAdmin. Что если мы создадим еще одну кнопку для второго ModelAdmin? Как мы можем сделать href = / path / to / something / динамическим? Спасибо - person thathashd; 28.06.2016
comment
@hashdava Используйте именованный URL, например (r'^my_view/$', self.my_view, name='foo'). Затем переопределите шаблон администратора change_form.html, скопировав его из исходного кода Django в соответствующий каталог шаблонов. Например: templates/admin/app_name/model_name/change_form.html. В блоке шаблонов {% block object-tools-items %} вы можете поместить свою кнопку: <li><a href="{% url 'admin:foo' %}">Foo</a></li>. Вы также можете поставить change_form.html на уровень выше, тогда это применимо ко всем формам изменения в этом приложении. Создайте папки, шаблоны и поиск URL-адресов для каждой модели ИЛИ используйте относительный URL-адрес. Например: <a href="foo/">. - person allcaps; 29.06.2016
comment
@allcaps - Спасибо за ответ. Для моей проблемы я использовал change_list.html вместо этого, но решение такое же, как вы предложили. - person thathashd; 06.07.2016
comment
Также теперь вы можете вызвать self.admin_site.admin_view (self.my_view) вместо self.my_view, чтобы проверить разрешения и пометить представление как некэшируемое. - person Lucas B; 19.09.2016
comment
@LucasB кажется полезным. Вы можете указать мне нужный раздел в документации? - person allcaps; 19.09.2016
comment
comment
Спасибо, все еще очень полезно. - person Eats Indigo; 02.03.2018

Вот другое решение без использования jQuery (например, предоставлено allcaps). Также это решение предоставляет объектный pk более интуитивно понятным способом :)

Я предоставлю свой исходный код на основе этой ссылки (перейдите по ссылке выше, чтобы узнать больше):

У меня есть приложение Товары с моделью Product. Этот код добавляет кнопку «Творить зло», которая выполняет ProductAdmin.do_evil_view ()

Файл products / models.py:

class ProductAdmin(admin.ModelAdmin):   
    def get_urls(self):
        urls = super().get_urls()
        my_urls = patterns('',
            (r'^(?P<pk>\d+)/evilUrl/$', self.admin_site.admin_view(self.do_evil_view))
        )
        return my_urls + urls

    def do_evil_view(self, request, pk):
        print('doing evil with', Product.objects.get(pk=int(pk)))
        return redirect('/admin/products/product/%s/' % pk)

self.admin_site.admin_view необходим, чтобы убедиться, что пользователь вошел в систему как администратор.

И это расширение шаблона стандартной страницы администратора Django для изменения записи:
Файл: {template_dir} /admin/products/product/change_form.html

В Django> = 1.8 (спасибо @jenniwren за эту информацию):

{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools-items %}
    {{ block.super }}
    <li><a class="historylink" href="evilUrl/">{% trans "Do Evil" %}</a></li>
{% endblock %}

Если ваша версия Django ниже 1.8, вам нужно написать еще код:

{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
    <li><a class="historylink" href="history/">{% trans "History" %}</a></li>
    <li><a class="historylink" href="evilUrl/">{% trans "Do Evil" %}</a></li>
{% if has_absolute_url %}
    <li><a class="viewsitelink" href="../../../r/{{ content_type_id }}/{{ object_id }}/">{% trans "View on site" %}</a></li>
{% endif%}</ul>
{% endif %}{% endif %}
{% endblock %}  
person Nikolai Saiko    schedule 03.07.2014
comment
Обратите внимание, что в django 1.8 теперь есть блок внутри тега <ul>: {% block object-tools-items %}, что означает, что вам больше не нужно копировать историю и просматривать кнопки сайта. Используйте {{ block.super }} и добавляйте свои собственные элементы списка до или после него. - person jenniwren; 05.02.2016
comment
Кнопка ссылается на /admin/products/product/1/change/evilUrl/, чем на /admin/products/product/1/evilUrl/. Я использую Django 1.9 - person avi; 21.05.2016