Python 如何对同一个模型使用两个不同的模型序列化程序?
我正在使用django rest框架。我有一个有亲戚的模特。我只想在用户点击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'
/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)