How do I use an UpdateView to update a Django Model?
Solution 1
It should be:
def get_object(self, queryset=None):
obj = Portfolios.objects.get(id=self.kwargs['id'])
return obj
Look at class based generic view dispatch explains that keyword arguments are assigned to self.kwargs.:
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
self.request = request
self.args = args
self.kwargs = kwargs
return handler(request, *args, **kwargs)
Solution 2
id = self.request.GET.get('id',None)
is what you needed when trying to access the GET query string.
However, your view can be simplified:
from django.conf.urls import *
from django.views.generic import UpdateView
from yourapp.models import Portfolios
from yourapp.forms import PortfoliosCreateForm
urlpatterns = patterns('',
url('^portfolios/update/(?P<pk>[\w-]+)$', UpdateView.as_view(
model=Portfolios,
form_class=PortfoliosCreateForm,
template_name='portfolios/create.html',
success_url='/portfolios'
), name='portfolio_update'),
)
Comments
-
xyzjace almost 2 years
I'm trying to update a model in Django using the class-based generic view UpdateView.
I read the page Updating User model in Django with class based UpdateView to try and get me started, but I'm getting an error 'WSGIRequest' object has no attribute 'id'
I'm a fresh face to Django, so please be forgiving if I'm doing something stupid.
//urls.py
url(r'^portfolios/update/(?P<id>\d+)/$',PortfoliosUpdateView.as_view()),
//views.py
class PortfoliosUpdateView(UpdateView): form_class = PortfoliosCreateForm model = Portfolios template_name = 'portfolios/create.html' def get(self, request, **kwargs): self.object = Portfolios.objects.get(id=self.request.id) form_class = self.get_form_class() form = self.get_form(form_class) context = self.get_context_data(object=self.object, form=form) return self.render_to_response(context) def get_object(self, queryset=None): obj = Portfolios.objects.get(id=self.request.id) return obj
It's mostly just a modified version of the code originally posted, but I thought it'd work. I know that I'm trying to retrieve the id passed as a GET parameter, but that doesn't seem to come through in the request variable. Am I going about this the wrong way?
Thanks
Edit: I think I fixed it, but this may be wrong: I changed the lines
self.object = Portfolios.objects.get(id=self.request.id) obj = Portfolios.objects.get(id=self.request.id)
to
self.object = Portfolios.objects.get(id=self.kwargs['id']) obj = Portfolios.objects.get(id=self.kwargs['id'])
I could be wrong.
-
xyzjace over 12 yearsThanks for clarifying. I've simplified my code significantly.
-
sleblanc over 11 yearsI prefer wrapping my views in
myapp.views
. E.g. inmyapp.views
:portfolio_update = UpdateView.as_view(...)
, then in the urlconf I only need to typeurl(r'pattern', "myapp.views.portfolio_update", name="portfolio_update")
. Does not fit every purpose, but I find it cleaner for most of my views. -
Jacob Valenta almost 11 yearsWhile this is a totally valid solution, best Django practices suggest keeping that logic for views.py instead of in the url pattern. -- From Two Scoops of Django
-
Burhan Khalid almost 11 yearsThere is no logic in the snippet I posted. @JacobValenta
-
Jacob Valenta almost 11 yearsI meant logic as in the model, form_class, template_name and success url, CBV are just that, class based Views, and the best way to implement them (from Two Scoops of Django) are .as_view()
-
radtek almost 10 yearsThe way I do it is I add this to just below where the view is defined in views.py, my_view = login_required(MyView.as_view()), then in my urls.py: urlpatterns = patterns('my_app.views', url(r'^my_view_url/$', 'my_view', name='my_view'), )
-
danidee about 7 years@BurhanKhalid shouldn't the regex be
(?P<pk>\d+)/$
. Your regex would also match a slug -
cezar over 6 yearsUsing the verb
update
(or any verb likecreate
,get
, etc.) in the URL isn't a best practice for ReSTful web sevices.