Как я могу создать представление создания на основе общего класса для модели?

То, что я пытаюсь сделать, это шаблон Django для функциональных представлений. Любая помощь здесь очень ценится, так как документы показывают примеры для представления шаблона и представления списка, но я нашел очень мало для общих представлений на основе модели. Я пропустил пример в документах?

У меня есть модель, представляющая запись в календаре. Существует внешний ключ к другому объекту (не пользователю), которому принадлежит запись. Что я хочу сделать, так это просто создать запись, убедившись, что внешний ключ записи правильно установлен, а затем вернуть пользователя на соответствующую страницу календаря.

Однако я не знаю, как общие представления на основе классов получают свои аргументы URL-адреса, и я не понимаю, как установить success_url, чтобы он повторно использовал идентификатор, который изначально был передан в URL-адрес создания. Еще раз спасибо заранее за вашу помощь.

По сути, я спрашиваю, что такое общее представление на основе классов, эквивалентное следующему:

def create_course_entry(request, class_id):
'''Creates a general calendar entry.'''
if request.method == 'POST':
    form = CourseEntryForm(request.POST)
    if form.is_valid():
        new_entry = form.save(commit=False)
        new_entry.course = Class.objects.get(pk=class_id)
        new_entry.full_clean()
        new_entry.save()
        return HttpResponseRedirect('/class/%s/calendar/' % class_id)
else:
    form = CourseEntryForm()

return render_to_response('classes/course_entry_create.html',
        { 'class_id': class_id, 'form': form, },
        context_instance=RequestContext(request))

person Lockjaw    schedule 09.04.2011    source источник


Ответы (2)


Вы можете создать подкласс общего представления edit.CreateView, установить класс/курс в методе dispatch() и сохранить его, переопределив метод form_valid():

from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.views.generic.edit import CreateView


class CourseEntryCreateView(CreateView):
    form_class = CourseEntryForm
    model = CourseEntry

    def dispatch(self, *args, **kwargs):
        self.course = get_object_or_404(Class, pk=kwargs['class_id'])
        return super(CourseEntryCreateView, self).dispatch(*args, **kwargs)

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.course = self.course
        self.object.save()
        return HttpResponseRedirect(self.get_success_url())

Если вы не настраиваете CourseEntryForm ModelForm, вы можете не указывать свойство form_class.

К сожалению, вызвать super() в методе form_valid() невозможно - из-за того, как он написан, объект будет сохранен снова.

Если вам нужен экземпляр класса (курса?) в контексте шаблона, вы можете добавить его в метод get_context_data():

    def get_context_data(self, *args, **kwargs):
        context_data = super(CourseEntryCreateView, self).get_context_data(
            *args, **kwargs)
        context_data.update({'course': self.course})
        return context_data
person Matt Austin    schedule 08.05.2011
comment
Вместо сохранения объекта в form_valid() вручную вы можете просто использовать form.instance для установки course. Это также позволяет снова вызвать super(). - person stschindler; 16.08.2013

Альтернативой ответу Мэтта Остина может быть переопределение метода get_form:

from django.shortcuts import get_object_or_404
from django.views.generic import CreateView

class CourseEntryCreateView(CreateView):
    form_class = CourseEntryForm
    model = CourseEntry

    def get_form(self, form_class):
        form = super(CustomCreateView, self).get_form(form_class)
        course = get_object_or_404(Class, pk=self.kwargs['class_id'])
        form.instance.course = course
        return form

Таким образом, .course находится в экземпляре CourseEntry в контексте и в экземпляре, созданном при сохранении формы при POST.

person meshy    schedule 14.05.2012