如何在 CreateView 中获取创建的对象

Posted

技术标签:

【中文标题】如何在 CreateView 中获取创建的对象【英文标题】:How to get created object in CreateView 【发布时间】:2016-10-18 22:59:45 【问题描述】:

这里我使用 CreateView 创建项目,然后我重定向用户以更新当前创建的对象的其他字段。

这是我的代码:

Views.py

class DynamicCreate(CreateView):
    model = Dynamic
    form_class = DynamicForm
    template_name = 'book/dynamic_create.html'

    def form_valid(self, form):
        book = form.save(commit=False)
        book.user = User.objects.get(pk=(self.request.user.pk))
        book.save()
        return reverse('book:dynamicupdate', args=(self.object.id))


Urls.py

url(r'^book/create/$', views.DynamicCreate.as_view(), name='dynamiccreate'),
url(r'^book/delete/(?P<pk>[\w]+)/$', views.DynamicDelete.as_view(), name='dynamicdelete'),
url(r'^book/update/(?P<pk>[\w]+)/$', views.DynamicUpdate.as_view(), name='dynamicupdate'),

但这里我收到错误:

Exception Type:     AttributeError
Exception Value:    'NoneType' object has no attribute 'id'

我经历了其他以前提出的问题,例如This,但我不知道我在这里缺少什么。我的 CreateView 能够在表中创建/保存数据,但它无法重定向我以更新视图页面。

【问题讨论】:

对象不就是book吗? 是的,这本书是我的对象 那么,你的问题是什么? return reverse('book:dynamicupdate', args=(self.object.id)) 这一行给了我错误。之后我正在创建对象,我试图让它的 ID/PK 重定向到更新该对象......但 self.object.id 没有价值......它返回我没有,有没有其他方法来获取创建的对象身份证? 但是我们刚刚同意你的对象是book。那你为什么在那里使用self.object 【参考方案1】:

从 ModelFormMixin 继承的 form_valid 方法包含将 self.object 设置为新创建的对象的逻辑,但您的覆盖方法使用 book 变量。如上所述将 args 更改为参考书效果很好。

另一个选择是将 book 变量替换为 self.object,如果只是遵循默认方法设置的示例。

【讨论】:

【参考方案2】:

尝试将该行更改为:

return reverse('book:dynamicupdate', args=(book.id))

self.object 没有在您的代码中的任何地方定义。

【讨论】:

【参考方案3】:

我通过更改来修复它 来自return reverse('book:dynamicupdate', args=(self.object.id))return redirect('book:dynamicupdate', book.id)

reverse 需要 ViewName 而不是 url,所以我将 reverse 更改为 redirect,这里我的对象是书,所以我将 self.object 替换为 book

感谢@Daniel Roseman 的帮助

【讨论】:

【参考方案4】:

正如solarissmoke 所解释的,'form_valid' 必须返回响应对象而不是 url!

然后我会写:

class DynamicCreate(CreateView):
    model = Dynamic
    form_class = DynamicForm
    template_name = 'book/dynamic_create.html'
    success_url = reverse("dynamic_list")

    def form_valid(self, form):
        # Catch an instance of the object
        book = form.save(commit=False)
        book.user_id = self.request.user.id
        book.save()
        self.success_url = reverse('book:dynamic_detail', args=[str(book.id)])
        return super(DynamicCreate, self).form_valid(form)

注意:book.user.id = self.request.user.id 而不是用户实例

更简洁,在model.py中添加get_absolute_url

def get_absolute_url(self):
    return reverse('dynamic_detail', args=[str(self.id)])

并在视图中引用这个函数:

class DynamicCreate(CreateView):
    model = Dynamic
    form_class = DynamicForm
    template_name = 'book/dynamic_create.html'
    success_url = reverse("book_list")

    def form_valid(self, form):
        # Catch an instance of the object
        book = form.save(commit=False)
        book.user_id = self.request.user.id
        book.save()
        self.success_url = self.model.get_absolute_url(book)
        return super(DynamicCreate, self).form_valid(form)

【讨论】:

以上是关于如何在 CreateView 中获取创建的对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中,如何在提交 CreateView 时重定向到 UpdateView?

Django - 如何在相关模型上为外键创建多个选择(在 CreateView 上)?

如何在 Django 的 CreateView 提交操作中保存当前登录的用户名?

如何创建SSIS脚本任务以从平面文件中删除CR LF

Django:我可以以相同的形式使用 CreateView 和 DeleteView 吗?

SQL语句大全2