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

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

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

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

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

Ответ 1

Когда несколько приложений предоставляют разные версии одного и того же ресурса (шаблон, статический файл, команда управления, перевод), приложение, указанное первым в 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, чтобы внедрить кнопку на стороне клиента. Если вам это нужно, смотрите ревизии.

Ответ 2

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

Я дам исходный код на основе этой ссылки (см. ссылку выше для получения дополнительной информации):

У меня есть приложение с продуктом продукта. Этот код добавляет кнопку "Do Evil", которая выполняет 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 %}  

Ответ 3

Этот пакет помогает добавлять пользовательские представления с помощью кнопок навигации к администратору django:

https://github.com/saxix/django-admin-extra-urls