0

I'm working on a small project ( Kanban board ) using Django / Rest Framework, I have two models one for tasks and one another for status ( columns ), like ( started, pending, Done ).

everything works fine with me. the only issue I have is my data structure, is not correctly nested,

this is my models : (Status)

from django.db import models
from django.conf import settings
from contact.models import Contact

# Create your models here.

class Status(models.Model):
    title = models.CharField(blank=False, null=False, max_length=255)
    slug = models.CharField(blank=False, null=False, max_length=255)
    order = models.SmallIntegerField(default=0)

    def __str__(self):
        return self.title

This is my Task Model :

class Task(models.Model):

    status = models.ForeignKey(Status, on_delete=models.CASCADE, default=1)
    title = models.CharField(blank=False, max_length=255)

This is my serializer :

from rest_framework import serializers
from task.models import Task


class TaskSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Task
        fields = '__all__'
        depth = 1

The result that i get :

[
    {
        "id": 1,
        "title": "my task title must be inside status ",
        "status": {
            "id": 1,
            "title": "step1",
            "slug": "step1",
            "order": 1
        }
    }
]

**I would like to get a nested Data structure, my tasks my be inside the status dictionary, so I can loop ever the status and the tasks ( nested for loop )

Alice Munin
  • 511
  • 2
  • 13

2 Answers2

0

Fixed this is the correct code :

from rest_framework import serializers
from task.models import Task, Status


class TaskSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Task
        fields = '__all__'



class StatusSerializer(serializers.ModelSerializer):
    tasks = TaskSerializer(many=True)
    class Meta:
        model = Status
        fields = '__all__'

This is the view:

def list(self, request):
        objectSerializer = StatusSerializer(Status.objects.all(), many=True)
        return Response(objectSerializer.data)
Alice Munin
  • 511
  • 2
  • 13
-1

You need to create a StatusSerializer and inside this declare a field that uses your TaskSerializer defining many and source attributes, example:

from rest_framework import serializers
from task.models import Task, Status


class TaskSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Task
        fields = ("title", )
        depth = 1


class StatusSerializer(serializers.ModelSerializer):
    tasks = TaskSerializer(many=True, source="task_set")


    class Meta:
        model = Status
        fields = '__all__'
        depth = 1

Another way using a SerializerMethodField instead of a serializer:

class StatusSerializer(serializers.ModelSerializer):
    tasks = serializers.SerializerMethodField()

    def get_tasks(self, obj):
        queryset = Task.objects.filter(status=obj)
        return TaskSerializer(queryset, many=True).data
    
    class Meta:
        model = Status
        fields = '__all__'

https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

More About Inverse Relations in django:

Django What is reverse relationship?