繁体   English   中英

Django Rest Framework中如何序列化三个多对多关系的模型

[英]How to serialize three models with many to many relationships in Django Rest Framework

我有三个基本模型:

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)

以及它们之间的三个多对多关系:

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'
            )
        ]

我的视图有一个 List.id 和一个 User.id,我想以以下格式或类似格式返回数据:

{"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}, ...]}

是否可以通过嵌套序列化器来做到这一点,或者我应该单独查询关系并在视图中加入数据? 任何有关这两种方法之间性能差异的信息都将受到额外的赞赏。

编辑(12/24)。 当前序列化程序:

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']

https://www.django-rest-framework.org/api-guide/relations/#nested-relationships

您可以制作嵌套的序列化程序。

  1. 为 model 制作每个序列化器。
  2. 使所有序列化程序嵌套。

首先,只需制作每个序列化器,然后将它们全部合并以进行嵌套。 它应该工作。

更新,

cell = models.ForeignKey(
        Cell,
        on_delete=models.CASCADE,
        related_name="user_cells"
    )

然后,您可以从像这样的单元格访问 user_cell

  cell_instance.user_cells.all()

或任何你想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM