14

Preface

I have a django project. I've wired it up so it serves a bunch of views for a bunch of models. Now I want to add an endpoint which just dumps a good fraction of the database out as json.

The way I would assume you do this is add a URL to a view class / method which returns a HTTPResponseObject full of json. Unfortunately, after quite a bit of googling, all I can find are references to Django REST framework. This is the sort of thing you would think Django would provide internally not as part of an external plugin library. But searching the django docs doesn't yield an immediate answer -- I don't think there are any docs about how to build an endpoint which just serves a bunch of json.

Questions:

  • Do I really need "Django REST framework" to serve json in django?
  • Did I overlook docs in Django for serving json?
  • What is the canonical way to serve json in a django project?
Alex Lenail
  • 12,992
  • 10
  • 47
  • 79
  • You don't really need anything, but if it makes your life easier and you like using it, why not employ that? Django is a framework, but that's not to say it comes with every tool you will ever conceivably need, which is why things like that extension exist. Doing REST in Django isn't hard, but that library might make things easier for you, less messy if you have a big API. – tadman Oct 13 '17 at 19:36
  • I feel like this is the sort of thing django would provide internally, being a heavier framework. I'm kind of boggled that it doesn't, if in fact it doesn't. I still feel like I must be missing something... – Alex Lenail Oct 13 '17 at 19:38
  • Django is pretty minimal as far as frameworks go, it's philosophically closer to Express.js and Ruby's Sinatra than it is to Rails. They take the approach of "if you want this additional functionality, add a dependency" versus Rails where they give you a ton out of the box on the basis you probably want it. – tadman Oct 13 '17 at 20:19
  • Hmm I always thought django was to rails as Flask was to Sinatra. Oh well. – Alex Lenail Oct 14 '17 at 21:18
  • @tadman you say "Doing REST in Django isn't hard, but that library might make things easier for you, less messy if you have a big API.". I only want to have 1 method in my API, so I'd rather not add the framework. How do you do REST in django? That's what this question is. – Alex Lenail Oct 15 '17 at 14:50
  • [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) isn't software, it's just a series of standards you try to adhere to. Since Django is a perfectly capable HTTP framework, it'll do it *if* you design your application accordingly. The extension only serves to make your life easier if you think that's necessary. With one method, who cares? – tadman Oct 15 '17 at 19:42

3 Answers3

17

After more googling, I found what I was looking for in the Django docs: JsonResponse

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

I think googling using the word "REST" was kind of a red herring which made the search space always direct my queries towards "Django REST framework" which is not what I wanted, though I do want to add a RESTful API.

Alex Lenail
  • 12,992
  • 10
  • 47
  • 79
6

You can write GET API using this method, but for POST method this will not work. For Post method we need to use some REST Library.

POST Method will check for CSRF token in the cookies and where it fails to execute the request, as your django server will treat this request as forged.

Anurag Pathak
  • 61
  • 1
  • 2
0

You should go with Django Rest Framework but if you want to do it yourself then:

  1. For POST request, if the client is sending you data as JSON, then you can use the json module to read the data from the request body.
import json

def add_new_user(self, request):
    data = request.body.decode('utf8')
    data = json.loads(data)
  1. If plain name/value pair is sent, then use request.POST or request.GET

  2. Use JsonResponse to send the response

  3. After authentication, the server usually send a token to the client. The client then sends that token when sending a request to 'protected' api end-point. A custom header (like auth_token) is used to send the token.

In the server code, you need to do something like request.META['HTTP_AUTH_TOKEN'] to get the token (see Custom HTTP Header in Django)

There are more things to consider like CSRF token or JWT.

See this site for a complete example https://jee-appy.blogspot.com/2018/02/make-rest-api-django.html. Be warned, it use old version of django.

S Ghosh
  • 376
  • 4
  • 5