是否可以在Serializer / ModelSerializer中对字段进行分组或修改JSON结构?
有一个Location
模型:
class Location(Model):
name_en = ...
name_fr = ...
...
如果我使用ModelSerializer
,则会得到对象字段的简单表示,如:
{'name_en':'England','name_fr':'Angleterre'}
我想在“名称”键下对某些字段进行分组,以便得到
{'names':{'name_en':'England','name_fr':'Angleterre'}}
我知道我可以创建自定义字段,但是我想知道是否有更直接的方法。我尝试过
Meta.fields = {'names':['name_en','name_fr']...}
不起作用
答案 0 :(得分:3)
我认为使用属性更好。这是整个示例。
class Location(models.Model):
name_en = models.CharField(max_length=50)
name_fr = models.CharField(max_length=50)
@property
def names(self):
lst = {field.name: getattr(self, field.name)
for field in self.__class__._meta.fields
if field.name.startswith('name_')}
return lst
在views
中:
class LocationViewSet(viewsets.ModelViewSet):
model = models.Location
serializer_class = serializers.LocationSerializer
queryset = models.Location.objects.all()
在serializers
中:
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = ('id', 'names')
我的虚假数据结果:
[{
"id": 1,
"names": {
"name_en": "England",
"name_fr": "Angleterre"}
}]
答案 1 :(得分:1)
尝试创建包装器序列化程序并将LocationSerializer放入其中
class LocationSerialzer(serializers.ModelSerialzer):
name_en = ...
name_fr = ...
...
class MySerializer(serializers.ModelSerializer):
name = LocationSerialzer()
...
使用上述方法,您可以应用自己的自定义内容,而不仅限于drf自定义字段。
答案 2 :(得分:0)
您也不能在模型上使用属性,而是像在此实现中那样在序列化程序上使用SerializerMethodField
。
与其他实现一样,我们在这里使用_meta.fields
来获取以name_
开头的所有字段,以便我们可以动态地获取所需的输出
class LocationSerializer(serializers.ModelSerializer):
names = serializers.SerializerMethodField()
def get_names(self, obj):
lst = {field.name: getattr(obj, field.name)
for field in obj.__class__._meta.fields
if field.name.startswith('name_')}
return lst
class Meta:
model = Location
fields = ('id', 'names')