DEV Community

tieje
tieje

Posted on

How to Create Nested JSON in Django REST APIs

Content

Introduction

  Nesting JSON with the Django REST Framework is not intuitive, but it is approachable once learned. Utilize the serializers.SerializerMethodField() from the rest_framework. By default, this method will call a method that begins with get_{your_variable_name}. From here, Django's QuerySet API can help you reduce multiple lines of a SQL into a single line of Python.

My Code as an Example

from django.db.models import QuerySet
from rest_framework import serializers
from skilltree.models import SkillTrees, SkillTreeHexagons, SkillTreePaths, SkillTreeHexagonNotes
from drf_queryfields import QueryFieldsMixin

class SkillTreesSerializer(QueryFieldsMixin, serializers.ModelSerializer):
    class Meta:
        model = SkillTrees
        fields = ('__all__')
    paths = serializers.SerializerMethodField()
    hexagons = serializers.SerializerMethodField()
    hex_string_list = serializers.SerializerMethodField()

    def get_hexagons(self, obj: SkillTrees) -> QuerySet:
        '''
        Get all hex ids that have the skill_tree_id
        The object is the SkillTrees instance
        For example, print(obj.skill_tree_id) will print each skill tree instance's skill_tree_id
        '''
        hexagons: QuerySet = SkillTreeHexagons.objects.filter(
            skill_tree_id=obj.skill_tree_id).values()
        return hexagons

    def get_paths(self, obj: SkillTrees) -> QuerySet:
        '''Get all hex ids that have the skill_tree_id'''
        paths: QuerySet = SkillTreePaths.objects.filter(
            skill_tree_id=obj.skill_tree_id).values()
        return paths

    def get_hex_string_list(self, obj: SkillTrees) -> QuerySet:
        '''Collect all hex string ids'''
        hex_string_ids_obj: QuerySet = SkillTreeHexagons.objects.filter(
            skill_tree_id=obj.skill_tree_id).values_list('hex_string')
        return hex_string_ids_obj
Enter fullscreen mode Exit fullscreen mode

Resulting JSON

{
  "skill_tree_id": 3,
  "paths": [
    {
      "path_id": 1,
      "skill_tree_id": 3,
      "starting_hex_q": 0,
      "starting_hex_r": 0,
      "starting_hex_s": 0,
      "ending_hex_q": 2,
      "ending_hex_r": 0,
      "ending_hex_s": -2,
      "starting_hex_string": "0,0,0",
      "ending_hex_string": "2,0,-2"
    },
    {
      "path_id": 2,
      "skill_tree_id": 3,
      "starting_hex_q": 0,
      "starting_hex_r": 0,
      "starting_hex_s": 0,
      "ending_hex_q": 0,
      "ending_hex_r": 2,
      "ending_hex_s": -2,
      "starting_hex_string": "0,0,0",
      "ending_hex_string": "0,2,-2"
    }
  ],
  "hexagons": [
    {
      "hex_id": 1,
      "note_id": null,
      "hex_q": 1,
      "hex_r": 1,
      "hex_s": 1,
      "skill_tree_id": 3,
      "allow_verbal_feedback": false,
      "allow_quantitative_feedback": true,
      "image_address": "https://www.knowol.com/wp-content/uploads/2017/02/abraham-lincoln-1863.jpg",
      "title": "ok",
      "hex_string": "1,1,1"
    },
    {
      "hex_id": 2,
      "note_id": 1,
      "hex_q": 2,
      "hex_r": 2,
      "hex_s": 2,
      "skill_tree_id": 3,
      "allow_verbal_feedback": true,
      "allow_quantitative_feedback": false,
      "image_address": "https://thecolloquial.com/wp-content/uploads/2020/07/Thomas_Paine_rev1-e1593883311631-319x180.jpg",
      "title": "asdf",
      "hex_string": "2,2,2"
    }
  ],
  "hex_string_list": [["1,1,1"], ["2,2,2"]],
  "name": "test tree",
  "theme": "yagami"
}
Enter fullscreen mode Exit fullscreen mode

Helpful Links Section

Stack Overflow link that helped me

Django REST Framework documentation on serializers

Discussion (0)