REST framework -- seralizer中添加额外字段的方法以及外键的处理
serializer中添加额外字段的方法:
#方法一: 修改model
class Animal(models.Model):
name = models.CharField(max_length=50, default='')
type = models.CharField(max_length=50, default='')
country = models.ForeignKey(Country, blank=True, null=True)
@property
def country_area(self):
return self.country.area
class AnimalSerializer(serializers.Serializer):
pk = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=50)
type = serializers.CharField(max_length=50)
country = serializers.PrimaryKeyRelatedField(read_only=True)
country_area = serializers.FloatField(required=False, source='country_area’)
#方法二: 不修改model 直接使用SerializerMethodField(method_name=None)字段
#SerializerMethodFiel是一个read-only字段
#当不指定其method_name时,默认为get_<field_name>
#如果使用ModelSerializer并指定字段时,要包含此时定义的字段
class AnimalSerializer(serializers.ModelSerializer):
country_area = serializers.SerializerMethodField()
class Meta:
model = Animal
fields = ('id', 'name', 'type','country','country_area')
def get_country_area(self, obj):
return obj.country.area
#方法三:可以在前端显示时多显示一个字段,post提交后端获取到值之后先从validated_data中去掉再进行接下来的处理
class ParentsSerializer(serializers.ModelSerializer):
kids_id = serializers.IntegerField(source='my_field')
def create(self, validated_data):
kids_id = validated_data.pop('my_field')
序列化时外键关系的处理:
#第一种:
class KidsSerializer(serializers.ModelSerializer):
class Meta:
model = Kids
fields = '__all__'
#访问时默认显示外键id ,创建时传id
#第二种:
class KidsSerializer(serializers.ModelSerializer):
class Meta:
model = Kids
fields = '__all__'
depth = 1
#访问时显示外键字段的所有信息,但是只读的,不可编辑,即新建时不能传值
#第三种:
class KidsSerializer(serializers.ModelSerializer):
grade = serializers.SlugRelatedField(queryset=Grade.objects.all(), slug_field='id')
class Meta:
model = Kids
fields = '__all__'
#访问时显示id/其他,新建时传id值/其他值
#序列化时反向关联的字段的处理
class GradeFinanceSerializer(serializers.Serializer):
id = serializers.IntegerField(required=True)
name = serializers.CharField(read_only=True)
class FinancePlanSerializer(serializers.ModelSerializer):
grades = GradeFinanceSerializer(many=True)
#访问时只显示定制的字段 新建时以列表形式传值
#字段类型在数据库中为枚举的字段显示问题: get_XXX_display
level = serializers.CharField(source='get_level_display')
#添加get传参的方法和过滤出想要显示的数据
def get_queryset(self):
name = self.request.query_params.get('name', '')
if name != '':
return Group.objects.filter(name__icontains=name)
else:
return Group.objects.all()