问题
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