如何为模型创建基于通用类的创建视图?

Loc*_*jaw 7 django django-generic-views

我正在尝试做的是用于功能视图的Django样板.这里的任何帮助都非常感谢,因为文档显示了模板视图和列表视图的示例,但我发现基于模型的通用视图很少.我在文档中遗漏了一个例子吗?

我有一个代表日历中条目的模型.拥有该条目的另一个对象(不是用户)有一个外键.我想要做的只是创建条目,确保正确设置条目的外键,然后将用户返回到相应的日历页面.

但是,我不知道基于类的通用视图如何接收其URL参数,我不清楚如何设置success_url以便它重用最初传递给创建URL的id.再次感谢您的帮助.

基本上,我要问的是,基于类的通用视图等效于以下内容:

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))
Run Code Online (Sandbox Code Playgroud)

Mat*_*tin 23

您可以子类化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())
Run Code Online (Sandbox Code Playgroud)

如果您没有自定义CourseEntryForm ModelForm,那么您可以遗漏该form_class物业.

不幸的是,不可能调用super()form_valid()方法 - 由于它的编写方式意味着该对象将被再次保存.

如果您需要模板上下文中的Class(course?)实例,则可以在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
Run Code Online (Sandbox Code Playgroud)

  • 您可以简单地使用`form.instance`来设置`course`,而不是手动将对象保存在`form_valid()`中.这使得再次调用`super()`成为可能. (2认同)

mes*_*shy 6

替代Matt Austin的答案可能是覆盖该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
Run Code Online (Sandbox Code Playgroud)

这样,.course就是在CourseEntry上下文中的实例上,以及在POST时保存表单时创建的实例.