【问题标题】:API call to update a field of an object用于更新对象字段的 API 调用
【发布时间】:2016-06-09 04:40:01
【问题描述】:

所以我有一个模型序列化器,它包含

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 请求。

【问题讨论】:

  • 我的回答是否回答了您的问题?如果没有,您遇到问题了吗?

标签: python django django-rest-framework


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    Django rest 框架自带一些预定义的concrete generic viewsUpdateAPIViewRetrieveUpdateAPIView

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

    RetrieveUpdateAPIView

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

    提供getputpatch 方法处理程序。

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

    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

    【讨论】:

    • 我认为您的代码可以工作,但 OP 的代码使用 ModelViewset,默认提供更新功能:django-rest-framework.org/api-guide/viewsets/#modelviewset
    • 我同意,generics.RetrieveUpdateAPIViewModelViewSet 都使用 mixins.UpdateModelMixin。所以我认为 OP 唯一需要的是一个带有pk 的网址。
    【解决方案3】:

    下面的代码会对你有所帮助,

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

    【讨论】:

      猜你喜欢
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      • 2020-05-20
      • 2014-07-24
      相关资源
      最近更新 更多