【问题标题】:DRF Post to ViewSet without writing into ModelDRF 发布到 ViewSet 而不写入模型
【发布时间】:2020-11-10 03:45:58
【问题描述】:

通过 Django Rest Framework 端点发布时,我总是将数据写入数据库。这次我想处理接收到的数据并将其发送到其他地方而不写入数据库。我从ModelViewSet 切换到ViewSet,我可以发出 GET 请求 OK,但是当我通过 DRF URL curl 或 POST 时收到 Bad Request 400。这是一个有效的最小代码(消除了对身份验证等的需要):

  • urls.py
from django.urls import path, include
from .views import ContactView
from rest_framework import routers

router = routers.DefaultRouter()
router.register('message', ContactView, basename='message')

urlpatterns = [
    path('', include(router.urls)),
]
  • serializers.py
from rest_framework import serializers

class ContactSerializer(serializers.Serializer):
    text = serializers.CharField(max_length=250)
  • views.py
from rest_framework.response import Response
from .serializers import ContactSerializer
from rest_framework import viewsets

class ContactView(viewsets.ViewSet):
    def list(self, request):
        return Response('Got it')

    def create(self, request):
        serializer = ContactSerializer(data=request.data)
        if serializer.is_valid():
            return Response(serializer.data)
        else:
            return Response('Invalid')

非常感谢您的建议。

【问题讨论】:

    标签: python django rest django-rest-framework django-rest-viewsets


    【解决方案1】:

    您可以使用 GenericAPIView 获取或发布请求,并在 validate 方法中执行一些逻辑,例如使用信号执行某些操作或编辑某些内容。你也可以为任何 ModelViewSet 使用@detailt_route 或@list_route 来编写特殊的url,例如编辑额外的数据。

    我很少这样做:

    在 urls.py 中

    urlpatterns = [
        url('v1/message', ContactAPIView.as_view(), name='message'),
    ]
    

    在 view.py 中

    class ContactAPIView(GenericAPIView):
        serializer_class = ContactSerializer
        permission_classes = ()
    
        def post(self, request, *args, **kwargs):
            serializer_class = self.get_serializer_class()
            serializer = serializer_class(data=request.data, context={'request': request})
            serializer.is_valid(raise_exception=True)
            data = {"status": True}
    
            return Response(data)
    

    在 serializers.py 中

    class ContactSerializer(serializers.Serializer):
        text = serializers.TextField()
    
        def validate(self, attrs):
            write some logic
    
    

    【讨论】:

    • 这解决了这个问题,非常感谢,在控制台输出之后应用了一些小的修改。用例很简单,所以 GenericAPIView 就足够了。
    【解决方案2】:

    您收到此错误是因为您使用的 Viewsets 使用 DefaultRouter 为您注册路由器。它的作用是为您的视图集创建 2 个 url

    1. message
    2. message/id

    所以在你目前的情况下;即视图集,您需要在您的 url 中发送一些虚拟数字才能访问此发布功能(这不是一个好方法)。

    因此,您应该使用任何父类不包含ViewSetMixin(提供Router Registration 的功能)的类,例如在您的情况下从这些类继承您的视图

    • ListModelMixin
    • CreateModelMixin
    • 通用API视图

    【讨论】:

    • 谢谢,对urls.pyrouter的设置有什么影响?
    • 你需要像urlpatterns = [path('message', APIView.as_view(), name='message'), ]一样手动注册路由器
    猜你喜欢
    • 2021-05-18
    • 2021-08-07
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多