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

发布于 2024-10-31 12:12:51 字数 932 浏览 4 评论 0原文

我想做的是功能视图的 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))

What I'm trying to do is Django boilerplate for functional views. Any help here is very much appreciated, as the docs show examples for the template view and list view, but I've found very little for the model-based generic views. Am I missing an example in the docs?

I have a model that represents an entry in a calendar. There's a foreign key to another object (not a user) that owns the entry. What I want to do is simply to create the entry, ensuring that the entry's foreign key is properly set and then return the user to the appropriate calendar page.

I don't know, though, how class-based generic views receive their URL arguments and I'm not clear on how to set the success_url so that it reuses the id that was originally passed to the creation URL. Again, thank you in advance for your help.

What I'm asking, essentially, is, what is the class-based generic view equivalent of the following:

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))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时常饿 2024-11-07 12:12:51

您可以对 edit.CreateView 通用视图进行子类化,在 dispatch() 方法中设置类/课程,并通过覆盖 form_valid() 来保存它code> 方法:

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 属性。

不幸的是,不可能在 form_valid() 方法中调用 super() - 因为它的编写方式意味着对象将被再次保存。

如果您需要模板上下文中的类(课程?)实例,那么您可以将其添加到 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

You could subclass the edit.CreateView generic view, set the class/course in the dispatch() method, and save this by overriding the form_valid() method:

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())

If you're not customising the CourseEntryForm ModelForm, then you can leave out the form_class property.

Unfortunately, it is not possible to call super() in the form_valid() method - due to the way it has been written would mean the object would be saved again.

If you need the Class (course?) instance in the template context, then you can add this in the get_context_data() method:

    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
微暖i 2024-11-07 12:12:51

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

这样,.course 位于上下文中的 CourseEntry 实例上,并且在 POST 保存表单时创建的实例上。

An alternative to Matt Austin's answer might be to override the get_form method:

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

This way, .course is on the CourseEntry instance in the context, and on the instance created when the form is saved upon POST.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文