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

时间:2016-06-17 07:46:05

标签: django django-admin django-views

这里我使用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能够在Table中创建/保存数据,但它无法将我重定向到更新View Page。

4 个答案:

答案 0 :(得分:2)

从ModelFormMixin继承的form_valid方法包括将self.object设置为新创建的对象的逻辑,但是重写方法使用book变量。如上所述,将args更改为参考书可以正常工作。

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

答案 1 :(得分:0)

尝试将该行更改为:

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

self.object未在代码中的任何位置定义。

答案 2 :(得分:0)

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

反向需要ViewName不是网址所以我将reverse更改为redirect,此处我的对象已预订,因此我将self.object替换为book

感谢@Daniel Roseman的帮助

答案 3 :(得分:0)

solarissmoke所述,“ form_valid”必须返回响应对象而不是网址!

然后我会写:

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)