Как создать сложное административное действие, требующее дополнительной информации? - PullRequest
8 голосов
/ 31 августа 2010

Я заинтересован в создании действия для интерфейса администратора, которое требует некоторой дополнительной информации помимо выбранных элементов. Мой пример - массовое добавление комиксов в серию. (Да, я знаю, что очевидный ответ - создать схему с отношениями X-X, но потерпите меня ради простого примера.)

В этом примере я создал 100 комиксов. После того, как они созданы, я бы хотел связать их с объектом серии, который уже был создан. Чтобы выполнить это действие в администраторе, я бы хотел выбрать элементы, а затем начать действие. Затем меня спросят, какой объект серии использовать (через всплывающее окно, промежуточную форму и т. Д.).

Я следовал инструкциям здесь , которые утверждают, что выполняют это через промежуточную форму. После работы с ним я больше не получаю ошибок, но само действие также не выполняется - forloop никогда не выполняется. Вместо этого он возвращается к списку комиксов с сообщением: «Никаких действий не выбрано».

мой метод admin.py:

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
def addSeries(self, request, queryset):
    form = None
    if 'cancel' in request.POST:
        self.message_user(request, 'Canceled series linking.')
        return
    elif 'link_series' in request.POST:
        form = self.SeriesForm(request.POST)
        if form.is_valid():
            series = form.cleaned_data['series']
            for x in queryset:
                y = Link(series = series, comic = x)
                y.save()
            self.message_user(request, self.categorySuccess.render(Context({'count':queryset.count(), 'series':series})))
            return HttpResponseRedirect(request.get_full_path())
    if not form:
        form = self.SeriesForm(initial={'_selected_action': request.POST.getlist(admin.ACTION_CHECKBOX_NAME)})
    return render_to_response('setSeries.html', {'comics': queryset, 'form': form, 'path':request.get_full_path()}, context_instance=RequestContext(request))
addSeries.short_description = 'Set Series'

Моя промежуточная форма setSeries.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Create Series Links</title>
    </head>
    <body>
        <h1>Create Series Links</h1>
        <p>Choose the series for the selected comic(s):</p>
        <form method="post" action="{{ path }}">
            <table>
                {{ form }}
            </table>
            <p>
                <input type="hidden" name="action" value="changeSeries" />
                <input type="submit" name="cancel" value="Cancel" />
                <input type="submit" name="link_series" value="link_series" />
            </p>
        </form>
        <h2>This categorization will affect the following:</h2>
        <ul>
            {% for comic in comics %}
                <li>{{ comic.title }}</li>
            {% endfor %}
        </ul>
    </body>
</html>

1 Ответ

5 голосов
/ 02 сентября 2010

Одна вещь, которую я заметил, это то, что метод вашего действия - «addSeries», но в форме, которую вы называете «changeSeries».

В вашем ModelAdmin у вас должна быть строка, подобная этой:

actions = ['addSeries']

Если это ваша строка, вам нужно изменить:

<input type="hidden" name="action" value="changeSeries" />

на:

<input type="hidden" name="action" value="addSeries" />

Вот как администратор Django знает, какое действие было выбрано.Если у вас есть промежуточная форма между выбором действия и его выполнением, вам нужно сохранить имя действия из меню выбора в интерфейсе администратора.

...