简体   繁体   中英

DRF Post to ViewSet without writing into Model

I've always written data into database when posting via Django Rest Framework endpoints. This time I would like to process received data and send it somewhere else without writing into DB. I switched from ModelViewSet to ViewSet , I can issue GET request OK but receiving Bad Request 400 when I curl or POST via DRF URL. Here's a working minimal code (removed need for authentication etc):

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

Would greatly appreciate your suggestions.

You can use GenericAPIView for get or post request and do some logic in validate method, for example do something with signals or edit something. Also u can use @detailt_route or @list_route for any ModelViewSet for write special url for instance, example for edit extra data.

how i did rarely:

in urls.py

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

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

in serializers.py

class ContactSerializer(serializers.Serializer):
    text = serializers.TextField()

    def validate(self, attrs):
        write some logic

you are getting this error because you are using Viewsets which uses DefaultRouter to register routers for you. What it does is that it creates 2 urls for your viewset

  1. message
  2. message/id

so in your current case; ie viewset you need to send some dummy number in your url to access this post function (which is not a good approach).

So, you should use any class which parent doesn't include ViewSetMixin (which gives functionality of Router Registration ) like in your case inherit your view from these classes

  • ListModelMixin
  • CreateModelMixin
  • GenericAPIView

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM