简体   繁体   English

如何在同一模型中使用两个不同的模型序列化器?

[英]How Can I Use Two Different Model Serializers With the Same Model?

I'm using django-rest-framework. 我正在使用django-rest-framework。 I have a model with a relation. 我有一个有关系的模型。 I would like to just display the count of related items when a user hits the /modelname/ URL, but show the full related set when a user hits a specific model instance at /modelname/1/ . 我只想在用户点击/modelname/ URL时显示相关项的计数,但是当用户点击/modelname/1/处的特定模型实例时显示完整的相关集。

I can almost get what I want. 几乎可以得到我想要的。

I have two serializers, like so: 我有两个序列化器,如下所示:

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')

If I use the short version, I get the count of revisions (it's a calculated field). 如果使用简短版本,则会得到修订计数(这是一个计算字段)。 If I use the long version, I get the full list of related items as "revisions". 如果使用长版本,则会获得相关项目的完整列表作为“修订”。

Short: 短:

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

Long: 长:

[{"id": 1, "title": "My Data Set", "revisions": ["Data Set v1", "Data Set v2"]}]

What I want to do is be able to switch between them based on query parameters (url). 我想做的是能够根据查询参数(URL)在它们之间切换。 I tried to set the serializer_class to the ShortDataSetSerializer when the ID was not present, but it overrode all cases, not just the non-ID case. 当ID不存在时,我尝试将serializer_class设置为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

Is there a way I can make this work? 有什么办法可以使我工作吗? I realize I may be approaching this in a totally ridiculous manner, but it seems like there should be an easy solution. 我意识到我可能会以一种完全荒谬的方式来解决这个问题,但是似乎应该有一个简单的解决方案。

The data example I gave rather abbreviated compared to the real data I'm working with. 与我正在使用的实际数据相比,我给出的数据示例相当简洁。 The end goal is to show a subset of fields in list view, and every field in the GET for a specific ID. 最终目标是在列表视图中显示字段的子集,并在GET中为特定ID显示每个字段。 This is a read-only API, so I don't need to worry about POST/PUT/DELETE. 这是一个只读API,因此我不必担心POST / PUT / DELETE。

You could do it by overriding the get_serializer_class method: 您可以通过重写get_serializer_class方法来实现:

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

I think one easy solution for this problem would be to use class based generic views instead of a viewset. 我认为解决此问题的一个简单方法是使用基于类的通用视图而不是视图集。

You can use a list create api view with serializer_class as ShortDataSetSerializer. 您可以使用带有serializer_class作为ShortDataSetSerializer的列表创建api视图。 So when you get the list of data it will have the count of revisions. 因此,当您获得数据列表时,它将具有修订计数。 Also if you want the post request to work on the same url you will then have to override the get_serializer_class method to set the serializer_class based on request type. 另外,如果您希望发布请求在相同的url上工作,则必须重写get_serializer_class方法以根据请求类型设置serializer_class。

For the retrieve view you can use the serializer_class as DataSetSerializer. 对于检索视图,可以将serializer_class用作DataSetSerializer。 It will have a list of revisions instead of count. 它将有一个修订列表,而不是计数。

Checkout generic views api guide on DRF docs website. 在DRF文档网站上签出通用视图api指南。

Also, you can override the list and retrieve methods on the viewset, but I would prefer to use class based views since DRF has a lot of additional functionalities attached to the request functions like get, put etc.(or list, detail) and it is better not to override them. 此外,您可以覆盖列表并在视图集上检索方法,但是我更喜欢使用基于类的视图,因为DRF在请求函数(如get,put等)(或列表,详细信息)上附加了许多附加功能,并且它最好不要覆盖它们。

Thank you, Benjamin. 谢谢你,本杰明。 That didn't do what quite I was looking for. 那没有做我一直在寻找的东西。 Ultimately what I had to do was this (with the same serializers as above): 最终,我要做的是(使用与上述相同的序列化器):

class DataSetViewSet(viewsets.ModelViewSet):
    model = DataSet

    def list(self, request):
        queryset = DataSet.objects.all()
        serializer = ShortDataSetSerializer(queryset, many=True)
        return Response(serializer.data)

    def detail(self, request, id=None):
        queryset = DataSet.objects.get(id=id)
        serializer = DataSetSerializer(queryset)
        return Response(serializer.data)

And in the urls.py: 并在urls.py中:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何嵌套两个具有相同模型的序列化器 - How to nest two serializers with same model 两个不同的深度学习框架如何使用同一模型? - how can two different deep learning frameworks use the same model? 如何访问序列化程序中 model 的选择并获得 json 视图 - How can I access choices of the model in the serializers and obtain a json view 如何在相同模型的 django 序列化程序中“分组” - How to "group by" in django serializers for same model 如何在 Django 中添加相同 model 的两个不同 integer 字段 - How can I add two different integer fields of the same model in Django 如何在使用同一模型的不同数据库之间迁移数据? - How can I migrate data between different databases that use the same model? 当嵌套序列化程序中有另一个模型(manytomany)时,我如何在 django 模型上发布,我想同时创建两者 - How do I post on a django model when it has another model (manytomany ) inside nested serializers, I want at the same time to create both 使用扩展的用户模型,如何在同一视图中创建具有两个模型形式的两个模型实例? - Using an extended usermodel, how can I create two model instances with two modelforms in the same view? 来自两个不同模型的同一模型中的两个外键 - Two foreign key in the same model from two different model 如何将两个不同模型的uuid和id放在同一个网址中? - How to put two different model's uuid and id in a same url?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM