Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何对同一个模型使用两个不同的模型序列化程序?_Python_Json_Django_Rest_Django Rest Framework - Fatal编程技术网

Python 如何对同一个模型使用两个不同的模型序列化程序?

Python 如何对同一个模型使用两个不同的模型序列化程序?,python,json,django,rest,django-rest-framework,Python,Json,Django,Rest,Django Rest Framework,我正在使用django rest框架。我有一个有亲戚的模特。我只想在用户点击/modelname/URL时显示相关项的计数,但在用户点击/modelname/1/处的特定模型实例时显示完整的相关集 我几乎可以得到我想要的 我有两个序列化程序,如下所示: class DataSetSerializer(serializers.ModelSerializer): revisions = serializers.RelatedField(source='datasetrevision_set'

我正在使用django rest框架。我有一个有亲戚的模特。我只想在用户点击
/modelname/
URL时显示相关项的计数,但在用户点击
/modelname/1/
处的特定模型实例时显示完整的相关集

我几乎可以得到我想要的

我有两个序列化程序,如下所示:

class DataSetSerializer(serializers.ModelSerializer):
    revisions = serializers.RelatedField(source='datasetrevision_set', many=True)

    class Meta:
        model = DataSet
        fields = ('id', 'title', 'revisions')

class ShortDataSetSerializer(serializers.ModelSerializer):

    class Meta:
        model = DataSet
        fields = ('id', 'title', 'revisions')
如果我使用短版本,我会得到修订的数量(这是一个计算字段)。如果我使用长版本,我会得到相关项目的完整列表作为“修订”

简称:

[{"id": 1, "title": "My Data Set", "revisions": 0}]
长:

我想做的是能够根据查询参数(url)在它们之间切换。当ID不存在时,我尝试将serializer_类设置为ShortDataSetSerializer,但它覆盖了所有情况,而不仅仅是非ID情况

class DataSetViewSet(viewsets.ModelViewSet):
    serializer_class = DataSetSerializer
    model = DataSet

    def get_queryset(self):
       try:
           id = self.kwargs['id']
           queryset = DataSet.objects.filter(id=id)
       except KeyError:
           queryset = DataSet.objects.all()
           # We want to only list all of the revision data if we're viewing a
           # specific set, but this overrides for all cases, not just the one
           # we want.
           self.serializer_class = ShortDataSetSerializer
       return queryset
有没有办法让这一切顺利进行?我意识到我可能以一种完全荒谬的方式来处理这个问题,但似乎应该有一个简单的解决办法


与我正在使用的实际数据相比,我给出的数据示例相当简短。最终目标是在列表视图中显示字段的子集,并在GET中显示特定ID的每个字段。这是一个只读API,因此我不需要担心POST/PUT/DELETE。

您可以通过重写
GET\u serializer\u类
方法来实现:

class DataSetViewSet(viewsets.ModelViewSet):
    model = DataSet

    def get_queryset(self):
       queryset = DataSet.objects.all()
       if self.kwargs.get('id'):
          queryset = queryset.filter(pk=self.kwargs.get('id'))
       return queryset

    def get_serializer_class(self):
       return DataSetSerializer if 'id' in self.kwargs else ShortDataSetSerializer

您可以重写
get\u序列化程序类
方法:

class DataSetViewSet(viewsets.ModelViewSet):
    model = DataSet

    def get_queryset(self):
       queryset = DataSet.objects.all()
       if self.kwargs.get('id'):
          queryset = queryset.filter(pk=self.kwargs.get('id'))
       return queryset

    def get_serializer_class(self):
       return DataSetSerializer if 'id' in self.kwargs else ShortDataSetSerializer

谢谢你,本杰明。这并不是我想要的。最终我要做的是(使用与上面相同的序列化程序):

在URL.py中:

url(r'^sets/$', views.DataSetViewSet.as_view({'get': 'list'})),
url(r'^sets/(?P<id>\d+)/$', views.DataSetViewSet.as_view({'get': 'detail'})),
url(r'^sets/$,views.DataSetViewSet.as_视图({'get':'list'})),
url(r'^sets/(?P\d+/$),views.DataSetViewSet.as_view({'get':'detail'})),

谢谢你,本杰明。这并不是我想要的。最终我要做的是(使用与上面相同的序列化程序):

在URL.py中:

url(r'^sets/$', views.DataSetViewSet.as_view({'get': 'list'})),
url(r'^sets/(?P<id>\d+)/$', views.DataSetViewSet.as_view({'get': 'detail'})),
url(r'^set/$”,views.DataSetViewSet.as\u view({get':'list'})),
url(r'^sets/(?P\d+/$),views.DataSetViewSet.as_view({'get':'detail'})),

我认为解决这个问题的一个简单方法是使用基于类的通用视图,而不是视图集

您可以使用带有serializer_类的列表创建api视图作为ShortDataSetSerializer。因此,当您获得数据列表时,它将具有修订计数。此外,如果希望post请求在同一url上工作,则必须重写get\u serializer\u class方法,以根据请求类型设置serializer\u类

对于检索视图,可以将serializer_类用作DataSetSerializer。它将有一个修订列表,而不是计数

在DRF文档网站上查看通用视图api指南


此外,您可以覆盖viewset上的list和retrieve方法,但我更喜欢使用基于类的视图,因为DRF有许多附加功能附加到请求函数,如get、put等(或list、detail)最好不要覆盖它们。

我认为解决这个问题的一个简单方法是使用基于类的通用视图,而不是视图集

可以使用带有序列化器\u类作为ShortDataSetSerializer的list create api视图。因此,当您获得数据列表时,它将具有修订计数。此外,如果希望post请求在同一url上工作,则必须重写get\u serializer\u class方法,以根据请求类型设置serializer\u类

对于检索视图,可以将serializer_类用作DataSetSerializer。它将有一个修订列表,而不是计数

在DRF文档网站上查看通用视图api指南


此外,您可以覆盖viewset上的list和retrieve方法,但我更喜欢使用基于类的视图,因为DRF有许多附加功能附加到请求函数,如get、put等(或list、detail)最好不要覆盖它们。

简单但更冗余的答案是只使用两个视图集。您是否尝试覆盖
get\u serializer\u class
方法?简单但更冗余的答案是只使用两个视图集。您是否尝试覆盖
get\u serializer\u class
方法?ModelViewSet是一个GenericViewSet。这里最好的解决方案是重写
get\u serializer\u class
get\u serializer
,因为通过重写
list
detail
可以复制
ModelViewSet
中已经存在的功能(并且可以删除过滤器和权限后端等功能)。对于URL.py中的代码,可以使用DRF路由器(SimpleRouter,DefaultRouter)ModelViewSet是一个GenericViewSet。这里最好的解决方案是重写
get\u serializer\u class
get\u serializer
,因为通过重写
list
detail
可以复制
ModelViewSet
中已经存在的功能(并且可以删除过滤器和权限后端等功能)。对于URL.py中的代码,可以使用DRF路由器(SimpleRouter、DefaultRouter)