Django休息框架,在同一个ModelViewSet中使用不同的序列化程序 [英] Django rest framework, use different serializers in the same ModelViewSet

查看:1730
本文介绍了Django休息框架,在同一个ModelViewSet中使用不同的序列化程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提供两个不同的序列化器,但是可以从 ModelViewSet 的所有设施中受益:

I would like to provide two different serializers and yet be able to benefit from all the facilities of ModelViewSet:


  • 当查看对象列表时,我希望每个对象具有一个重定向到其详细信息的url,并且使用 _ _ unicode _ _ 目标模型;示例:
  • When viewing a list of objects, I would like each object to have an url which redirects to its details and every other relation appear using _ _ unicode _ _ of the target model; example:
[
    {
        "membri": [
            "emilio", 
            "michele", 
            "luisa", 
            "ivan", 
            "saverio"
        ],
        "creatore": "emilio", 
        "url": "http://127.0.0.1:8000/database/gruppi/2/", 
        "nome": "universitari", 
        "descrizione": "unitn!", 
        "accesso": "CHI"
    }
]  


  • 查看对象的详细信息时,我想使用默认的 HyperlinkedModelSerializer ,例如:

  • When viewing the details of an object, I would like to use the default HyperlinkedModelSerializer, example:

    {
        "url": "http://127.0.0.1:8000/database/gruppi/2/", 
        "nome": "universitari", 
        "descrizione": "unitn!", 
        "creatore": "http://127.0.0.1:8000/database/utenti/3/", 
        "accesso": "CHI", 
        "membri": [
            "http://127.0.0.1:8000/database/utenti/3/", 
            "http://127.0.0.1:8000/database/utenti/4/", 
            "http://127.0.0.1:8000/database/utenti/5/", 
            "http://127.0.0.1:8000/database/utenti/6/", 
            "http://127.0.0.1:8000/database/utenti/7/"
        ]
    }

  • 我按照以下方式设法完成所有这些工作:

    I managed to make all this work as I wish in the following way:

    serializers.py

    # serializer to use when showing a list
    class ListaGruppi(serializers.HyperlinkedModelSerializer):
        membri = serializers.RelatedField(many = True)
        creatore = serializers.RelatedField(many = False)
    
        class Meta:
            model = models.Gruppi
    
    # serializer to use when showing the details
    class DettaglioGruppi(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = models.Gruppi
    

    views.py

    class DualSerializerViewSet(viewsets.ModelViewSet):
        """
        ViewSet providing different serializers for list and detail views.
    
        Use list_serializer and detail_serializer to provide them
        """
        def list(self, *args, **kwargs):
            self.serializer_class = self.list_serializer
            return viewsets.ModelViewSet.list(self, *args, **kwargs)
    
        def retrieve(self, *args, **kwargs):
            self.serializer_class = self.detail_serializer
            return viewsets.ModelViewSet.retrieve(self, *args, **kwargs)
    
    class GruppiViewSet(DualSerializerViewSet):
        model = models.Gruppi
        list_serializer = serializers.ListaGruppi
        detail_serializer = serializers.DettaglioGruppi
    
        # etc.
    

    基本上,我检测到用户正在请求列表视图或详细视图并更改 serializer_class 以满足我的需要,但我对此代码并不满意,看起来像一个肮脏的黑客,最重要的是,如果两个用户在同一时间请求一个列表和一个细节怎么办?

    Basically I detect when the user is requesting a list view or a detailed view and change serializer_class to suit my needs. I am not really satisfied with this code though, it looks like a dirty hack and, most importantly, what if two users request a list and a detail at the same moment?

    有没有更好的方法来实现这个使用 ModelViewSets 或者我必须使用 GenericAPIView

    Is there a better way to achieve this using ModelViewSets or do I have to fall back using GenericAPIView?

    编辑:

    以下是如何使用一个定制基础 ModelViewSet

    class MultiSerializerViewSet(viewsets.ModelViewSet):
        serializers = { 
            'default': None,
        }
    
        def get_serializer_class(self):
                return self.serializers.get(self.action,
                            self.serializers['default'])
    
    class GruppiViewSet(MultiSerializerViewSet):
        model = models.Gruppi
    
        serializers = {
            'list':    serializers.ListaGruppi,
            'detail':  serializers.DettaglioGruppi,
            # etc.
        }
    


    推荐答案

    覆盖您的 get_serializer_class 方法。您的模型mixins中使用此方法来检索正确的Serializer类。

    Override your get_serializer_class method. This method is used in your model mixins to retrieve the proper Serializer class.

    请注意,还有一个 get_serializer 方法返回正确的实例 Serializer

    Note that there is also a get_serializer method which returns an instance of the correct Serializer

    class DualSerializerViewSet(viewsets.ModelViewSet):
        def get_serializer_class(self):
            if self.action == 'list':
                return serializers.ListaGruppi
            if self.action == 'retrieve':
                return serializers.DettaglioGruppi
            return serializers.Default # I dont' know what you want for create/destroy/update.                
    

    这篇关于Django休息框架,在同一个ModelViewSet中使用不同的序列化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆