Как я могу сделать базовое представление на основе классов для модели? - PullRequest
7 голосов
/ 09 апреля 2011

То, что я пытаюсь сделать, это шаблон 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))

Ответы [ 2 ]

23 голосов
/ 08 мая 2011

Вы можете создать подкласс общего представления 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
6 голосов
/ 14 мая 2012

Альтернативой ответу Мэтта Остина может быть переопределение метода 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.

...