Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django class based view with GET parameters

Using django rest framework I'm trying to create a view that allows to retrieve and update a single user but I don't understand how to do it. At the moment I don't care about permissions and authentication.

views.py

class UserDetailsView(RetrieveUpdateAPIView):
    def get_object(self, user_id):
        user = get_user_model().objects.get(pk=user_id)
        return user

urls.py

urlpatterns = [
    #rest of code
    url(r'^user/(?P<user_id>[0-9]+)/$', views.UserDetailsView.as_view(), name="profile"),
]

if I try to access localhost:8000/user/1 I get:

TypeError at /user/1/
get_object() missing 1 required positional argument: 'user_id'

Request Method:     GET
Request URL:    http://localhost:8000/user/1/
Django Version:     1.11.1
Exception Type:     TypeError
Exception Value:    

get_object() missing 1 required positional argument: 'user_id'

I am missing something because with function based views everything works just fine. For example:

views.py

def game(request, id_game):
    # rest of code

urls.py

 url(r'^games/(?P<id_game>[0-9]+)/$', views.game, name="game"),
like image 517
Mr. Blue Avatar asked Dec 23 '22 15:12

Mr. Blue


2 Answers

Firstly, it's a kwarg not an arg. There's a difference. So you would need to do user_id=None in the def get() of your class based view. You can also access the kwargs by going self.kwargs['user_id'].

Secondly, since you're using the RetrieveUpdateAPIView you can just add the property for the URL PK Kwarg like this:

class UserDetailsView(RetrieveUpdateAPIView):
    lookup_url_kwarg = 'user_id'

And then you don't need to override the get_object method. Some more info on the properties here: https://www.django-rest-framework.org/api-guide/generic-views/#genericapiview

Note I'm linking to the GenericAPIView here because that's what RetrieveUpdateAPIView inherits from (or one of the classes).

like image 173
Cory Madden Avatar answered Dec 28 '22 07:12

Cory Madden


You can access user_id as kwargs in get_object.

def get_object(self):
    user_id = self.kwargs['user_id']
    ...

Class based views offer far more flexibility and code reuse, but you do need to understand what each method means, and when it is called. Go through Django rest framework's documentation.

like image 38
hspandher Avatar answered Dec 28 '22 08:12

hspandher