【问题标题】:How to change the way ModelViewSet presents the data?如何改变 ModelViewSet 呈现数据的方式?
【发布时间】:2023-01-29 22:32:24
【问题描述】:

我的 api 有两个序列化程序,可以为我提供有关公司办公地点的数据。

class CountryFilialsSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = CountryFilials
        fields = ['name']

class FilialsSerializer(serializers.HyperlinkedModelSerializer):
    country = CountryFilialsSerializer()
    class Meta:
        model = Filials
        fields = ['country', 'name', 'subdomain_name', 'address']

CountryFilialsSerializer 通过外键给我带来国家名称,FilialsSerializer 将此数据添加到其他子数据中。

目前使用它们的视图如下所示:

class FilialsViewSet(viewsets.ModelViewSet):
    queryset = Filials.objects.all()
    serializer_class = FilialsSerializer

它返回如下所示的响应:

"results": [
        {
            "country": {
                "name": "foo"
            },
            "name": "city1",
            "subdomain_name": "subdomain1",
            "address": "location1"
        },
        
        {
            "country": {
                "name": "foo"
            },
            "name": "city2",
            "subdomain_name": "subdomain2",
            "address": "location2"
        },

但我需要它来实际呈现这样的结果:

[
  {
    "country": "foo",
    "cities": [
      {
        "name": "city1",
        "subdomain_name": "subdomain1",
        "address": "location1"
      },
      {
        "name": "city2",
        "subdomain_name": "subdomain2",
        "address": "location2"
      },
    ]
  },
]

基本相同的数据,只是按国家/地区分组到列表中。

我想不出办法来做到这一点。正如我所意识到的,序列化程序一次只从基础接收一个条目,如果我覆盖它的 to_representation() 方法以包含输出的某些格式,我将无法访问多个位置并将它们按一个国家/地区分组。 我的下一个猜测是应该有类似的方法直接从视图中处理结果。 但是我在文档中找不到任何相关信息(或者我什至不知道该找什么)。 找到了一些有关操作和 update() 方法的信息,但无法了解如何将其用于我的目标。 你能建议点什么吗?我不知道在哪里以及如何将逻辑放入视图中,以便能够捕获它推入响应中的所有内容并重新组织它。

【问题讨论】:

    标签: python serialization django-rest-framework django-views


    【解决方案1】:

    您可以拥有这样的城市的国家/地区列表(这需要您更改视图以使用CountryFilialsViewset

    class FilialsSerializer(serializers.ModelSerializer):
        class Meta:
            model = Filials
            fields = ['name',]
    
    class CountryFilialsSerializer(serializers.ModelSerializer):
        filials = FilialsSerializer(many=True, read_only=True)
        class Meta:
            model = CountryFilials
            fields = ['name', 'filials']
    
    class CountryFilialsViewSet(viewsets.ModelViewSet):
        queryset = CountryFilials.objects.prefetch_related('filials')
        serializer_class = CountryFilialsSerializer
    

    或者,如果您需要覆盖 ModelViewSet,您可以这样做:

    class CountryFilialsViewSet(viewsets.ModelViewSet):
        queryset = CountryFilials.objects.prefetch_related('filials')
        serializer_class = CountryFilialsSerializer
    
        def list(self, request):
            response = [
                {'country': country.name, 'cities': list(country.filials.values('name').all())} for country in CountryFilials.objects.all()
            ]
            return Response(response)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多