没啥说的,挺基础的东西.
class Flow(models.Model):
flow_name = models.CharField(man_length=250)
class Stage(models.Model):
stage_name = models.CharField(man_length=250)
flow = models.ForeignKey(Flow,on_delete=models.CASCADE,related_name='stages')
class Task(models.Model):
task_name = models.CharField(max_length=250)
stage = models.ForeignKey(Stage,on_delete=models.CASCADE,related_name='tasks')
def __str__(self):
return self.task_name
class TaskSerializer(serializers.ModelSerializer)
class Meta:
model = Task
fields = '__all__'
这种情况下,serializer.data中的task的stage属性是对应的id值
PrimaryKeyRelatedField
class StageSerializer(serializers.ModelSerializer)
class Meta:
model = Stage
fields = '__all__'
这样是不会返回task相关信息的.
class StageSerializer(serializers.ModelSerializer)
tasks = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = Stage
fields = '__all__'
这样返回数据中的tasks就是一个id列表了.注意,字段名必须与related_name相同(如果没设置related_name,就是类名小写加_set.本例中也就是task_set)
class StageSerializer(serializers.ModelSerializer)
owned_tasks = serializers.PrimaryKeyRelatedField(source='tasks',many=True) #自定义关系来源
class Meta:
model = Stage
fields = '__all__'
class TaskSerializer(serializers.ModelSerializer)
flow = serializers.PrimaryKeyRelatedField(source='stage.flow',many=True) # 点语法来定义多个关系.
class Meta:
model = Task
fields = '__all__'
StringRelatedField
如果前端是想展示,那么给出id就不太合适了.可以先用万能的SerializerMethodField实现一版
class StageSerializer(serializers.ModelSerializer)
tasks = serializers.SerializerMethodField(many=True)
class Meta:
model = Stage
fields = '__all__'
def get_tasks(self,instance):
return [task.task_name for task in instance.tasks]
同样的,使用StringRelatedField也能实现
class StageSerializer(serializers.ModelSerializer)
tasks = serializers.StringRelatedField(many=True)
class Meta:
model = Stage
fields = '__all__'
注意StringRelatedField最终返回的是模型类的str方法的返回值.
使用StringRelatedField的好处.
曾经,我一直使用万能的SerializerMethodField.来序列化用户的用户名,返回值是user.nickname
后来产品说重名的员工很难分清楚,要改成user.nickname(user.username).于是我东一处西一处改了很多地方,还是有漏掉的.
再后来产品说,领导发话了,他不知道手下人的账户,要再加上部门信息.愤怒之后冷静下来的我深刻的懂得了封装的重要性.如果使用了StringRelatedField,那么永远都只要改一处(也就是user模型的Str方法.)就好了.