Today, I wanted to add a view which outputs the result of a Django queryset as a JSON array.
Sounds simple, but it took me a couple of minutes to figure out how to do it properly:
from .models import * from django.http import JsonResponse def covid19_json(request): data = CaseState.objects.values() return JsonResponse(list(data), safe=False)
The things which are important:
- You need to call
.values()
to get the actual queryset result - You then need to run it through
list()
to get it as a list - Lastly, you need to return a
JsonResponse
object with the parametersafe
set toFalse
to output it. Thesafe
parameter is required as you're outputting a non-dictionary object.
If you want more control over how your models are converted to JSON, you can define for example a method called json
on your model class:
from django.db import models class CaseState(models.Model): date = models.DateField(primary_key=True) country = models.CharField(max_length=255) cases = models.IntegerField(blank=True, default=0) today_cases = models.IntegerField(blank=True, default=0) deaths = models.IntegerField(blank=True, default=0) today_deaths = models.IntegerField(blank=True, default=0) recovered = models.IntegerField(blank=True, default=0) active = models.IntegerField(blank=True, default=0) critical = models.IntegerField(blank=True, default=0) cases_per_one_million = models.IntegerField(blank=True, default=0) deaths_per_one_million = models.IntegerField(blank=True, default=0) def json(self): return { 'date': str(self.date), 'country': self.country, 'cases': self.cases, }
Then, do the following in the view function:
import json from .models import * from django.http import HttpResponse def covid19_json(request): data = [i.json() for i in CaseState.objects.all()] return HttpResponse(json.dumps(data), content_type="application/json")
The second approach doesn't require a one on one match between the model and the json output.