API调用来更新对象

问题描述:

所以我有它由API调用来更新对象

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

的模型串行的领域这是我的视图集中

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

这是我URLs.py文件:

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')) 
] 

使用序列化程序,我可以使它打印出我的数据库中的对象。如果我有对象PK/ID,我希望能够更新对象的字段idname。有没有办法通过使用序列化器的补丁/发布请求来做到这一点?我对此很陌生,所以如果有人能帮助我解决这个问题,我很乐意。

我想的只是做一个POST请求,则有它这样做:

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

但我想做到这一点使用串行,使用PATCH请求。

+0

我的回答下面回答你的问题吗?如果不是,你遇到问题了吗? – dkhaupt

下面的代码,将有助于你,

**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) 

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

Django的休息框架提供了一些预先定义concrete generic viewsUpdateAPIViewRetrieveUpdateAPIView

首先您需要为user创建一个视图,其中使用的视图之一可以是update。更新视图为视图上的patch方法提供处理程序。

RetrieveUpdateAPIView

用于读取或更新端点来表示单个模型实例。

提供了get,putpatch方法处理程序。

现在,用它来创建一个视图:

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

要访问此视图,你需要有一个使用用户的主键访问用户的URL:

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

然后使用PATCH调用您可以更新用户的name

+0

我认为你的代码可以工作,但是OP的代码使用ModelViewset,默认提供更新功能:http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset – dkhaupt

+0

我同意, generics.RetrieveUpdateAPIView'和'ModelViewSet'使用'mixins.UpdateModelMixin'。所以我认为OP需要的唯一东西就是带有'pk'的url。 – AKS

由于您使用的是ModelViewset,因此应该内置此功能。如果使用可浏览的API导航到/user/<pk>/,您将看到可以在该对象上执行的操作。默认情况下,ModelViewset提供了list()retrieve(),create(),update()destroy()的功能。

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

您还可以覆盖任何或所有的提供的方法,但是单个对象的更新内置于DRF ModelViewsets。使用curl尝试使用您想要更新的信息尝试PATCH到/user/<pk>/