I want to group an entity based on one foreign key relation in rest django

Question:

I have two model here and records are related to employee:

class Employee(models.Model):
     name = models.CharField(max_length=100)
     position = models.CharField(max_length=100)
     site = models.CharField(max_length=100)
     wage = models.DecimalField(max_digits=4, decimal_places=0, default=0)

class Record(models.Model):
     employee = models.ForeignKey(Employee, related_name='employee', 
     on_delete=models.DO_NOTHING)
     date = models.DateField()
     cash = models.DecimalField(max_digits=4, decimal_places=0, default=0)

I would like to generate a which list all records of each employees
Something like below:

{
  "id": 1,
  "name": "John Doe",
  "position": "manager",
  "Records": [
    {
      "date": "2020-12-09T18:30:00.000Z",
      "cash": 888
    },
    {
      "date": "2020-10-10T18:30:00.000Z",
      "cash": 999
    }
  ]
}

Please help me to write the serialiser and view set for my above requirement.

Asked By: Arun J

||

Answers:

It makes no sense that related_name='employee': the related_name=… parameter [Django-doc] is the name of the relation in reverse, so for example records:

class Record(models.Model):
    employee = models.ForeignKey(
        Employee, related_name='records', on_delete=models.DO_NOTHING
    )
    date = models.DateField()
    cash = models.DecimalField(max_digits=4, decimal_places=0, default=0)

Then we can work with a subserializer:

from rest_framework import serializers


class RecordSerializer(serializers.ModelSerializer):
    class Meta:
        model = Record
        fields = ['date', 'cash']


class EmployeeSerializer(serializers.ModelSerializer):
    records = RecordSerializer(many=True)

    class Meta:
        model = Employee
        fields = ['id', 'name', 'position', 'records']

In the serializer, we can prefetch the records:

from rest_framework import viewsets


class EmployeeViewSet(viewsets.ModelViewSet):
    serializer_class = EmployeeSerializer
    queryset = Employee.objects.prefetch_related('records')
Answered By: Willem Van Onsem