How to get created object in CreateView

断了今生、忘了曾经 提交于 2020-08-24 11:16:30

问题


Here I am using CreateView to create item and after that i am redirecting user to update other fields of currently created object.

Here my code:

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

But Here I am getting error:

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

I go through other previously asked question like This, But I don't know What I am missing here. My CreateView is able to create/save data in Table but it is not able to redirect me to update View Page.


回答1:


The form_valid method inherited from ModelFormMixin includes logic to set self.object to the newly created object, but your overriding method uses the book variable instead. Changing the args to reference book as mentioned above works fine.

Another option would be to replace the book variable with self.object, if only to follow the example set by the default method.




回答2:


Try changing that line to:

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

self.object is not defined anywhere in your code.




回答3:


I Fixed it by changing from return reverse('book:dynamicupdate', args=(self.object.id)) to return redirect('book:dynamicupdate', book.id)

reverse need ViewName not url so i changed reverse to redirect and here my object was book so i replaced self.object with book

Thanks @Daniel Roseman for help




回答4:


As explained by solarissmoke 'form_valid' must return a response object not a url!

I would then write:

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)

Note: book.user.id = self.request.user.id instead of the user instance

Even cleaner, add get_absolute_url in model.py

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

And refer to this function in the view:

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)


来源:https://stackoverflow.com/questions/37875917/how-to-get-created-object-in-createview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!