3

So I have an model serializer which consists of

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'name', 'description')

This is my ViewSet

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

This is my URLs.py file:

from django.conf.urls import include, url
from rest_framework import routers
import views

router = DefaultRouter()
router.register('user', views.UserViewSet)
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^login/', include('rest_framework.urls', namespace='rest_framework'))
]

Using the serializer, I can make it print out the objects inside my database. If I have the object PK/ID, I want to be able to update the field id or name of the object. Is there a way I can do that with a patch/post request using the serializer? I'm new to this so I'd love it if someone can help me out with this.

I'm thinking of just doing a POST request, then have it do this:

user = User.objects.get(id=id)
user.name = "XXXXX"
user.save()

But I want to do this using the serializer, using a PATCH request.

Joe
  • 77
  • 10

3 Answers3

0

the below code will help to you,

**filename : views.py**

from user.models import User
from users.serializers import UserSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class UserList(APIView):
    """
    List all users, or create a new user.
    """
    def get(self, request, format=None):
        users = User.objects.all()
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class UserDetail(APIView):
    """
    Retrieve, update or delete a user instance.
    """
    def get_object(self, pk):
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        user = self.get_object(pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        user = self.get_object(pk)
        serializer = UserSerializer(user, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        user = self.get_object(pk)
        user.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


**filename : urls.py**

from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from users import views

urlpatterns = [
    url(r'^users/$', views.UserList.as_view()),
    url(r'^user/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

Reference : http://www.django-rest-framework.org/tutorial/3-class-based-views/

GThamizh
  • 2,054
  • 3
  • 17
  • 19
0

Django rest framework comes with some pre-defined concrete generic views such as UpdateAPIView, RetrieveUpdateAPIView.

First you need to create a view for user which uses one of the views which can update. The update views provides handlers for patch method on the view.

RetrieveUpdateAPIView

Used for read or update endpoints to represent a single model instance.

Provides get, put and patch method handlers.

Now, use this to create a view:

class UserDetail(generics.RetrieveUpdateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

To access this view you need to have a url which uses user's primary key to access the user:

url(r'users/(?P<pk>\d+)/$', UserDetail.as_view(), name='api-user-detail'),

Then using PATCH call you can update the user's name.

Community
  • 1
  • 1
AKS
  • 18,983
  • 3
  • 43
  • 54
  • I think your code would work, but OP's code uses a ModelViewset, which provides update capability by default: http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset – dkhaupt Feb 29 '16 at 13:37
  • I agree, both `generics.RetrieveUpdateAPIView` and `ModelViewSet` use `mixins.UpdateModelMixin`. So I think the only thing OP need is a url with `pk` in it. – AKS Feb 29 '16 at 15:04
0

Since you're using a ModelViewset, this capability should be built in. If you use the browsable API to navigate to /user/<pk>/, you'll see the operations you can perform on that object. By default, a ModelViewset provides list(), retrieve(), create(), update(), and destroy() capability.

http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset

You can also override any or all of the provided methods, however an update of a single object is built in to DRF ModelViewsets. Use curl to try a PATCH to /user/<pk>/ with the information you'd like to update.

dkhaupt
  • 2,220
  • 3
  • 23
  • 37