Py学习  »  Django

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

Milano • 4 年前 • 667 次点击  

是否有方法对序列化程序/模型序列化程序中的字段进行分组或修改JSON结构?

有一个 Location 型号:

class Location(Model):
    name_en = ...
    name_fr = ...
    ...

如果我用 ModelSerializer 对象字段的简单表示如下:

{'name_en':'England','name_fr':'Angleterre'}

我想在“names”键下分组一些字段

{'names':{'name_en':'England','name_fr':'Angleterre'}}

我知道我可以创建自定义字段,但我想知道是否有更直接的方法。我试过了

Meta.fields = {'names':['name_en','name_fr']...}

这不管用

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50529
 
667 次点击  
文章 [ 3 ]  |  最新文章 4 年前
edilio
Reply   •   1 楼
edilio    5 年前

您也不能在模型上使用属性,而是使用 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')
Haidar Zeineddine
Reply   •   2 楼
Haidar Zeineddine    5 年前

尝试创建包装序列化程序并将LocationSerializer放在其中

class LocationSerialzer(serializers.ModelSerialzer):
   name_en = ...
   name_fr = ...
   ...


class MySerializer(serializers.ModelSerializer):
   name = LocationSerialzer()
   ...

使用上述方法,您可以应用自己的自定义项,而不限于drf自定义字段。

edilio
Reply   •   3 楼
edilio    5 年前

我认为最好是使用一处房产。这就是整个例子。

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"}
}]