DEV Community

Cover image for Creating a RESTFul API with Django without DjangoRestFramework
Alex Merced
Alex Merced

Posted on

Creating a RESTFul API with Django without DjangoRestFramework

Find tutorials for django at my website, devNursery.com

Often times when making a RESTFul API with Django it can seem like... "how would this work in?"

Django has a lot of great aspects to it:

  • Modularity, creating chunks of your application as "apps" allows you to reuse and repurpose features you've already created. (example, build out an auth app then just reuse it in all future projects)

  • A fairly robust built suite of authentication features

This is all great but when making a microservice or RESTFul API Django can seem a bit clunky (cause its design seems to really be built for handling both the front and backend, a full-stack framework).

This is why we often rely on the DjangoRestFramework library for building RESTful APIs and Microservices with Django (or use alternatives like Flask, FastAPI, Masonite, etc.)

Although, being curious as I am I decided to see what it would look like to create a full crud Restful API with Pure Django and no helper libraries. Below are the results.

models.py

from django.db import models

class Todo(models.Model):
    item = models.CharField(max_length = 100)
Enter fullscreen mode Exit fullscreen mode

views.py


from django.shortcuts import render
from django.http import JsonResponse
from themodels.models import Todo
from django.core import serializers
from django.views.decorators.csrf import csrf_exempt
import json

@csrf_exempt ## To exempt from default requirement for CSRF tokens to use postman
def TheModelView(request):

    if (request.method == "GET"):
        #Serialize the data into json
        data = serializers.serialize("json", Todo.objects.all())
        # Turn the JSON data into a dict and send as JSON response
        return JsonResponse(json.loads(data), safe=False)

    if (request.method == "POST"):
        # Turn the body into a dict
        body = json.loads(request.body.decode("utf-8"))
        #create the new item
        newrecord = Todo.objects.create(item=body['item'])
        # Turn the object to json to dict, put in array to avoid non-iterable error
        data = json.loads(serializers.serialize('json', [newrecord]))
        # send json response with new object
        return JsonResponse(data, safe=False)

@csrf_exempt ## To exempt from default requirement for CSRF tokens to use postman
def TheModelViewTwo(request, id):
        if (request.method == "PUT"):
        # Turn the body into a dict
            body = json.loads(request.body.decode("utf-8"))
        # update the item
            Todo.objects.filter(pk=id).update(item=body['item'])
            newrecord = Todo.objects.filter(pk=id)
        # Turn the object to json to dict, put in array to avoid non-iterable error
            data = json.loads(serializers.serialize('json', newrecord))
        # send json response with updated object
            return JsonResponse(data, safe=False)

        if (request.method == "DELETE"):
        # delete the item, get all remaining records for response
            Todo.objects.filter(pk=id).delete()
            newrecord = Todo.objects.all()
        # Turn the results to json to dict, put in array to avoid non-iterable error
            data = json.loads(serializers.serialize('json', newrecord))
        # send json response with updated object
            return JsonResponse(data, safe=False)
Enter fullscreen mode Exit fullscreen mode

urls.py

from django.contrib import admin
from django.urls import path
from themodels.views import TheModelView, TheModelViewTwo

urlpatterns = [
    path('admin/', admin.site.urls),
    path('themodel/', TheModelView),
    path('themodel/<int:id>/', TheModelViewTwo)
]

Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
mrambig profile image
Gajendra D Ambi

I was wondering if you can call the rest api function in a wrapper separate function and return it with a template! In this way you can still use the restapi for your mobile apps or other purposes and these wrapper functions will keep serving the browser version. A reply or follow up in this regard will be helpful and greatly appreciated.

Collapse
 
alexmercedcoder profile image
Alex Merced

I don’t see why not, although if your serving the same data you can save yourself sometime and just do the database queries in the view function for that template. Although yes I could call the api, but it’s like calling pizza delivery from the pizza place.

A application can have a mix of template views and api routes, to the extent the data is being used to render a template just query the data in that views view function, if the data is needed after page load you can call the api from Javascript running on that page.