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:
1from .models import *
2
3from django.http import JsonResponse
4
5def covid19_json(request):
6 data = CaseState.objects.values()
7 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:
1from django.db import models
2
3class CaseState(models.Model):
4 date = models.DateField(primary_key=True)
5 country = models.CharField(max_length=255)
6 cases = models.IntegerField(blank=True, default=0)
7 today_cases = models.IntegerField(blank=True, default=0)
8 deaths = models.IntegerField(blank=True, default=0)
9 today_deaths = models.IntegerField(blank=True, default=0)
10 recovered = models.IntegerField(blank=True, default=0)
11 active = models.IntegerField(blank=True, default=0)
12 critical = models.IntegerField(blank=True, default=0)
13 cases_per_one_million = models.IntegerField(blank=True, default=0)
14 deaths_per_one_million = models.IntegerField(blank=True, default=0)
15
16 def json(self):
17 return {
18 'date': str(self.date),
19 'country': self.country,
20 'cases': self.cases,
21 }
Then, do the following in the view function:
1import json
2
3from .models import *
4
5from django.http import HttpResponse
6
7def covid19_json(request):
8 data = [i.json() for i in CaseState.objects.all()]
9 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.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.