社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

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

Milano • 5 年前 • 1300 次点击  

是否有方法对序列化程序/模型序列化程序中的字段进行分组或修改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
 
1300 次点击  
文章 [ 3 ]  |  最新文章 5 年前
edilio
Reply   •   1 楼
edilio    6 年前

您也不能在模型上使用属性,而是使用 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    6 年前

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

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


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

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

edilio
Reply   •   3 楼
edilio    6 年前

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

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