Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework Custom Endpoints

I have recently inherited an API built with Django and DRF. I need to add some endpoints to the API but have never worked with Django or DRF before so I am trying to come up to speed as quickly as possible.

I am wondering how to do custom endpoints that don't just translate data too/from the backend database. A for instance might be an endpoint that reads data from the DB then compiles a report and returns it to the caller in JSON. But I suppose that right now the simplest method would be one that when the endpoint is hit just prints 'Hello World' to the log and returns a blank page.

I apologize if this seems basic. I've been reading through the docs and so far all I can see is stuff about serializers when what I really need is to be able to call a custom block of code.

Thanks.

like image 742
thompsbp Avatar asked Sep 01 '25 02:09

thompsbp


1 Answers

if you want your REST endpoint to have all: GET, POST, PUT, DELETE etc. functionality then you have to register a route in your urls.py:

urls.py:

from rest_framework import routers
from django.urls import path, include
from . import views

router = routers.DefaultRouter()
router.register(r'hello', views.HelloWorldViewSet)

urlpatterns = [
    # Wire up our API using automatic URL routing.
    # rest_framework api routing
    path('api/', include(router.urls)),
    # This requires login for put/update while allowing get (read-only) for everyone.
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

now the url: /hello/ points to the HelloWorldViewSet.

in your views.py add the HelloWorldViewSet that will inherits from the rest_framework.viewsets.ViewSet class. You can override the ViewSet default class behavior by defining the following "actions": list(), create(), retrieve(), update(), partial_update(), destroy(). For displaying "hello world" on GET you only need to override list():

so in your views.py:

from rest_framework import viewsets
from rest_framework.response import Response

class HelloWorldViewSet(viewsets.ViewSet):
    def list(self, request):
        return Response('Hello World')

So, in your more advanced list() function you have to interact with the database, to retrieve the data you want, process it and create the report as a json serializable dictionary and return it as a Response object.

If you don't want to override the standard list action, you could instead add a new action to the HelloWorldViewSet let's call it report:

so in your views.py:

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import action

class HelloWorldViewSet(viewsets.ViewSet):
    @action(detail=False)
    def report(self, request, **kwargs):
        return Response('Hello World')

I hope this is what you were looking for.

Note that you don't need django-rest-framework if you are not interested in POST, PUT, PATCH, DELETE, etc... you can simply add a path to your urls.py that points to a Django view function that returns a Django JsonResponse object containing your report.

like image 125
Ouss Avatar answered Sep 02 '25 15:09

Ouss