Django Admin Actions — действия с промежуточной страницей

в 8:26, , рубрики: django, django-admin, метки: ,

Привет. Полезная штука экшены в админке! Хочу поделиться как можно сделать экшен который после выбора элементов будет отправлять пользователя на промежуточную страницу чтобы с этими элементами можно было сделать что то особенное. Пример? Например у вас есть интернет магазин, таблица товаров. Вы хотите перенести часть товаров из одного раздела (книги) в другой (книги технические). Выбираем нужные книги, выбираем действие «Перенести в другой раздел», жмем применить, переходим на промежуточную страницу, выбираем нужный раздел и жмем сохранить. Здорово? Давайте попробуем.

Описываем форму:

class ChangeCategoryForm(forms.Form):
    _selected_action = forms.CharField(widget=forms.MultipleHiddenInput)
    category = forms.ModelChoiceField(queryset=Category.objects.all(), label=u'Основная категория')

Загадочное поле _select_action, да? Тут будут ID выбранных элементов. Django заберет их потом из POST запроса и сделает из них Queryset для которого мы будем делать наши действия (см. код ниже).

Наш экшен это как и всегда метод. Назовем его move_to_category.

def move_to_category(modeladmin, request, queryset):
       form = None

       if 'apply' in request.POST:
           form = ChangeCategoryForm(request.POST)

           if form.is_valid():
               category = form.cleaned_data['category']

               count = 0
               for item in queryset:
                   item.category = category
                   item.save()
                   count += 1

               modeladmin.message_user(request, "Категория %s применена к %d товарам." % (category, count))
               return HttpResponseRedirect(request.get_full_path())

       if not form:
           form = ChangeCategoryForm(initial={'_selected_action': request.POST.getlist(admin.ACTION_CHECKBOX_NAME)})

       return render(request, 'catalog/move_to_category.html', {'items': queryset,'form': form, 'title':u'Изменение категории'})

move_to_category.short_description = u"Изменить категорию"

Объявляем экшен в класс ProductAdmin:

actions = [move_to_category,]

И создаем шаблон для показа всего этого

{% extends "admin/base_site.html" %}

{% block content %}
<form action="" method="post">{% csrf_token %}
    {{ form }}
    <p>Новая категория будет назначена для следующих позиций:</p>
    <ul>{{ items|unordered_list }}</ul>
    <input type="hidden" name="action" value="move_to_category" />
    <input type="submit" name="apply" value="Сохранить" />
</form>
{% endblock %}

Вот собственно и все. Подобным способом можно сделать очень очень очень много всяких важных, нужных и интересных вещей.

И напоследок хочу привести скриншоты с рабочего проекта которые показывают как все это работает.

image

image

image

image

Удачи!

Автор: moskrc


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js