Django Rest Framework:如何修改输出结构?

时间:2018-12-27 23:32:34

标签: python django django-rest-framework

是否可以在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']...}

不起作用

3 个答案:

答案 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')