I have three base models:
class User(models.Model):
displayName= models.CharField(max_length=128)
class Cell(models.Model):
title = models.CharField(max_length=128)
class List(models.Model):
title = models.CharField(max_length=128)
And three many-to-many relationships between them:
class UserCell(models.Model):
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
cell = models.ForeignKey(
Cell,
on_delete=models.CASCADE
)
value = models.SmallIntegerField()
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'cell'],
name='unique_UserCell'
)
]
class UserList(models.Model):
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
target_list = models.ForeignKey(
List,
on_delete=models.CASCADE
)
last_updated = models.DateTimeField(default=timezone.now)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'target_list'],
name='unique_UserList'
)
]
class CellAssignment(models.Model):
target_list = models.ForeignKey(
List,
on_delete=models.CASCADE
)
cell = models.ForeignKey(
Cell,
on_delete=models.CASCADE
)
idx = models.SmallIntegerField()
class Meta:
ordering = ['idx']
constraints = [
models.UniqueConstraint(
fields=['target_list', 'idx'],
name='unique_cellAssignment'
)
]
My view is given a List.id and a User.id and I want to return data in the following format, or something similar:
{"List.id": 2, "List.title": "The Big List of Cells", "List.created_date": "2020-10-02T18:14:02Z", "cells": [{"target_list.id": 2, "Cell.id": 6, "CellAssignment.idx": 0, "Cell.title": "The first cell", "UserCell.value": 4}, {"target_list.id": 2, "Cell.id": 12, "CellAssignment.idx": 1, "Cell.title": "This is the second cell and so on", "UserCell.value": 9}, ...]}
Is it possible to do this by nesting serializers, or should I query the relationships separately and join the data in the view? Any info on the difference in performance between the two approaches would be additionally appreciated.
Edit (12/24). Current Serializers:
class UserCellSerializer(serializers.ModelSerializer):
class Meta:
model = UserCell
fields = '__all__'
class CellSerializer(serializers.ModelSerializer):
class Meta:
model = Cell
fields = ['id', 'title']
class CellAssignmentSerializer(serializers.ModelSerializer):
cell_title = serializers.ReadOnlyField(source='cell.title')
cell_value = serializers.ReadOnlyField(source='cell.user_cell.value')
class Meta:
model = CellAssignment
#target_list and cell are not strictly needed below, as of now. good for debug tho.
fields = ['target_list', 'idx', 'alt_title', 'cell_title', 'cell_value']
class ListSerializer(serializers.ModelSerializer):
cell_details = CellAssignmentSerializer(read_only=True, many=True)
class Meta:
model = List
fields = ['id', 'title', 'created_date', 'cell_details']