How do I use an UpdateView to update a Django Model?

50,124

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'),
)
Share:
50,124
xyzjace
Author by

xyzjace

Writer of code, seeker of scotch.

Updated on July 09, 2022

Comments

  • xyzjace
    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
    xyzjace over 12 years
    Thanks for clarifying. I've simplified my code significantly.
  • sleblanc
    sleblanc over 11 years
    I prefer wrapping my views in myapp.views. E.g. in myapp.views: portfolio_update = UpdateView.as_view(...), then in the urlconf I only need to type url(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
    Jacob Valenta almost 11 years
    While 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
    Burhan Khalid almost 11 years
    There is no logic in the snippet I posted. @JacobValenta
  • Jacob Valenta
    Jacob Valenta almost 11 years
    I 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
    radtek almost 10 years
    The 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
    danidee about 7 years
    @BurhanKhalid shouldn't the regex be (?P<pk>\d+)/$. Your regex would also match a slug
  • cezar
    cezar over 6 years
    Using the verb update (or any verb like create, get, etc.) in the URL isn't a best practice for ReSTful web sevices.