Изменение админки django

категория: Django
Попало под руки небольшое задание именно по django admin, а я давно уже обещал немного пролить свет на этот топик. Задача звучала примерно такая: создать приложение, в котором недовольные продавцы будут клацать на кнопку "Вернуть комиссию", будет открываться форма для сообщения, дальше это все будет сохраняться в модель и отправляться оповещение о оставленной заявке администрации. Админ будет заходить в админке в раздел "Заявки на возврат комиссии", будет получать список этих всех заявлений с возможностью вернуть комиссию или отказать. В случае отказа в админке будет появляться форма для ответа и объяснения причины отказа пользователю. После отправки этой формы будет прислано уведомление в личный профиль и на почту продавца, написавшего заявление. Здесь я упущу, то что не относится к админке. Нам понадобится только стандартно создать класс в admin.py, создать в нем три метода, один будет отвечать за возврат комиссии, второй - за отмену возврата и третий будет выводить в list_display кнопки для этих действий и состояние. Добавим ссылки на эти методы в админке и шаблон формы для отказа комиссии, который будет унаследован от джанговской admin/base.html. Может звучит не очень понятно пока или я не особо умею выражать свои мысли доступно, но давайте выложу весь код и в конце подробно все постараюсь объяснить. admin.py
class ReturnComAdmin(admin.ModelAdmin):
    list_display = ('timestamp', 'item', 'description', 'text', '_status')
#
    def __init__(self, *args, **kwargs):
        super(ReturnComAdmin, self).__init__(*args, **kwargs)
        self.list_display_links = (None, )
#
    def get_urls(self):
        urls = super(ReturnComAdmin, self).get_urls()
        my_urls = patterns(
            '',
            url(r'^return_com/(\d+)/$', self.admin_site.admin_view(
                self._return_com)),
            url(r'^reject_com/(\d+)/$', self.admin_site.admin_view(
                self._reject_com)),
        )
        return my_urls + urls
#
    def _get_absolute_url(self):
        content_type = ContentType.objects.get_for_model(ReturnCom)
        return reverse("admin:%s_%s_changelist" % (
                       content_type.app_label, content_type.model))
#
    def _return_com(self, request, com_id):
        # Тут возвращаем комиссию, и оповещаем 
        # об этом пользователя
        ...
        return redirect(self._get_absolute_url())
#
    def _reject_com(self, request, com_id):
        form = RejectComForm()
        if request.method == 'POST':
            form = RejectComForm(request.POST)
            if form.is_valid():
                # Тут отмечаем, что возврата не произошло
                # и отправляем сообщение пользователю,
                # введенное в форму
                ...
                return redirect(self._get_absolute_url())
        return render(request, 'admin/com_form.html', {'form': form})
#
    def _status(self, request):
        if request.is_returned:
            status = u'Комиссия возвращена'
        elif request.is_rejected:
            status = u'Заявка отклонена'
        else:
            status = u'<a href="return_com/%s">Вернуть комиссию</a> | \
                <a href="reject_com/%s">Отклонить заявку</a>' % (
                request.id, request.id)
        return status
    _status.allow_tags = True
    _status.short_description = u'Статус'
com_form.html
{% extends 'admin/base.html' %}
{% block content %}
<form action="" method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Отправить"/>
</form>
{% endblock %}
Итак, как я и обещал начну разбор кода. Здесь используется обычная модель с полями 'timestamp', 'item', 'description', 'text', информация из которых будет у нас отображаться в списке list_display в админке. К ним добавляется еще одно поле _status - это функция в которой будут отображаться ссылки "Вернуть комиссию" и "Отклонить заявку", если администратор нажмет первую, то поле поменяется на 'Комиссия возвращена', вторую - 'Заявка отклонена'. allow_tags позволяет отображать html теги, short_description - переопределяет отображение названия поля В конструкторе __init__ переопределяем list_display_links, чтобы не было ссылок в списке заявок - они просто не нужны здесь. В методе get_urls добавляем ссылки на наши методы _return_com и _reject_com В _get_absolute_url - делаем абсолютный линк на список заявок, оно просто пригодится для редиректов Метод _return_com будет отвечать за функционал возврата комиссии за сделки, если администратор нажмет "Вернуть комиссию" Метод _reject_com будет выводить шаблон с формой com_form.html, обрабатывать ее содержимое и оповещать продавца об отмене возврата, если администратор нажмет "Отклонить заявку" Шаблон com_form.html - это просто шаблон с формой для отправки сообщения, который наследуется от base.html админки джанго. Как видно из этого небольшого примера - django admin мощный инструмент администрирования, который очень легко расширяется под любые нужды разработчика. Надеюсь этот пример откроет для вас занавес тайн django admin)) и подтолкнет к новым свершениям.


blog comments powered by Disqus