Search code examples
pythondjangorestdjango-rest-frameworkdjango-rest-viewsets

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.


Solution

  • 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