python - 如何使用 Django Rest Framework 将多个模型序列化为一个序列化器以实现层次结构?
问题描述
我有四个模型,我需要为我的 API 将三个模型序列化为一个模型。我可以让各个序列化程序按预期工作,但是当将它们组合成一个时,我没有得到我期望看到的结果。
模型.py
class President(models.Model):
name = models.CharField('Name', max_length=50,)
staff = models.ManyToManyField('Member',)
def __str__(self):
return self.name
"""
user creates a new member in this model below
if a new member is an employee, the object is copied into the Employee model
and the user chooses the manager of the employee in the manager field
if a new member is a manager, the object is copied into the Manager model
"""
class Member(models.Model):
president = models.ForeignKey(
President, on_delete=models.CASCADE, related_name='members',
)
manager = models.ForeignKey(
'Manager', on_delete=models.CASCADE, related_name='manager',
)
name = models.CharField('Name', max_length=50,)
email = models.EmailField('Email Address',)
title = models.CharField('Title', max_length=50,)
staff_type = (
('Manager', 'Manager'),
('Employee', 'Employee'),
)
def __str__(self):
return self.name
class Employee(models.Model):
president = models.ForeignKey(
President, on_delete=models.CASCADE, related_name='employeePresident'
)
manager = models.ForeignKey(
'Manager', on_delete=models.CASCADE, related_name='employeeManager'
)
name = models.CharField('Name', max_length=50,)
email = models.EmailField('Email Address',)
title = models.CharField('Title', max_length=50,)
def __str__(self):
return self.name
class Manager(models.Model):
president = models.ForeignKey(
President, on_delete=models.CASCADE, related_name='managerPresident'
)
name = models.CharField('Name', max_length=50,)
department = models.CharField('Department', max_length=50,)
def __str__(self):
return self.name
序列化程序.py
class PresidentSerializer(serializers.ModelSerializer):
class Meta:
model = President
fields = '__all__'
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = '__all__'
class ManagerSerializer(serializers.ModelSerializer):
members = EmployeeSerializer(many=True,)
class Meta:
model = Manager
fields = ('president', 'name', 'department', 'members')
到目前为止,所有这些序列化程序都按预期工作。ManagerSerializer 像我想要的那样在树视图中公开经理的姓名和他们下面的员工。
但是,员工不一定必须在经理之下,例如他们可以直接向总裁对象汇报,就像总裁助理一样。
我如何将这三个序列化程序组合成一个,我的 API 如下:
{
"name": "Presidents Name",
"staff": [
{
"name": "Employee No Manager",
"title": "Presidents Asst"
},
{
"name": "John Doe",
"title": "Finance Manager",
"employees": [
{
"name": "Mary Simpson",
"title": "Finance Asst"
}
]
}
}
不确定我的模型设计中是否需要更改总裁模型可以同时接受员工和经理模型的地方。任何帮助将不胜感激。
解决方案
我会将您的数据库结构简化为每个员工只有 1 个类(以及 2 个额外的类用于数据库规范化):
class JobTitle(models.Model):
title = models.CharField('Title', max_length=50)
def __str__(self):
return self.title
class Department(models.Model):
name = models.CharField('Department', max_length=50)
def __str__(self):
return self.name
class Employee(models.Model):
name = models.CharField('Name', max_length=50)
boss = models.ForeignKey("Employee", on_delete=models.CASCADE, related_name="staff", blank=True, null=True)
department = models.ForeignKey("Department", on_delete=models.CASCADE)
email = models.EmailField('Email Address')
title = models.ForeignKey("JobTitle", on_delete=models.CASCADE)
@property
def is_president(self):
return self.boss is None
@property
def is_manager(self):
return len(self.staff) > 0
def __str__(self):
return self.name
然后你可以使用这个答案中的递归序列化器:
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class EmployeeSerializer(serializers.ModelSerializer):
staff = RecursiveField(many=True)
class Meta:
model = Employee
fields = '__all__'
推荐阅读
- scheme - How to record scheme session in a file?
- csv - Merging two csv files, can't get rid of newline
- php - 如何在 Silverstripe 4.2 前端创建编辑表单?
- performance - 创建 MTLTexture 需要花费大量时间,如何改进它?
- jquery-ui-autocomplete - Jquery UI 自动完成,避免鼠标悬停选择
- excel - 关于 FSO 的问题以及如何验证文件完整性?
- python - I need help extracting a specific piece of text from a webpage
- c++ - 为什么我的滑动窗口算法没有提供正确的答案?
- svg - SVG问题:使透明路径变为白色
- javascript - 使用 express.js 时 HTML 页面无法正确呈现