在序列化程序中使用@StaticMethods Django Rest Framework

时间:2018-04-09 04:50:34

标签: django django-rest-framework

我有两个使用相同功能的序列化程序。我想将它定义为静态方法并重用它。

文章序列化

class ArticleDetailSerializer(ModelSerializer):
    liked = SerializerMethodField()
    class Meta:
        model = Article
        fields = [
            'id',
            'self_liked',
            'title'
        ]

    def get_liked(self, obj):
        request = self.context.get('request')
        self_like_obj = Reaction.objects.filter(user=request.user.id, content_type=ContentType.objects.get(model='article'), object_id=obj.id)
        if self_like_obj.exists():
            self_like = Reaction.objects.get(user=request.user.id, content_type=ContentType.objects.get(model='article'), object_id=obj.id).react_type
        else:
            self_like = False
        return self_like

用于评论的序列化工具

class CommentSerializer(ModelSerializer):
        liked = SerializerMethodField()
        class Meta:
            model = Comment
            fields = [
                'id',
                'self_liked',
                'content'
            ]

        def get_liked(self, obj):
            request = self.context.get('request')
            self_like_obj = Reaction.objects.filter(user=request.user.id, content_type=ContentType.objects.get(model='comment'), object_id=obj.id)
            if self_like_obj.exists():
                self_like = Reaction.objects.get(user=request.user.id, content_type=ContentType.objects.get(model='comment'), object_id=obj.id).react_type
            else:
                self_like = False
            return self_like

如您所见,两个序列化程序使用一般函数:get_liked如何将其定义为静态方法以供重用?

3 个答案:

答案 0 :(得分:3)

由于 @neverwalkaloner 建议您只能在mixin类中实现一次方法,并将此类用作两个序列化程序的父级。请注意,get_likedArticleDetailSerializer序列化程序中的CommentSerializer方法不同。

ArticleDetailSerializer方法有ContentType.objects.get(model='article')行但CommentSerializerContentType.objects.get(model='comment'),这使得序列化程序中get_liked方法之间存在差异。

您可以使用 @neverwalkaloner 建议的相同mixin,而不是ContentType.objects.get(model='article')ContentType.objects.get(model='comment')行,您可以尝试使用ContentType.objects.get(model=self.Meta.model.__name__.lower())

我认为它应该是这样的:

class LikedMixin(object):

    def get_lowercased_model_name(self, obj):
        return self.Meta.model.__name__.lower()

    def get_liked(self, obj):
        request = self.context.get('request')
        model_name = self.get_lowercased_model_name()
        self_like_obj = Reaction.objects.filter(user=request.user.id, content_type=model_name, object_id=obj.id)
        if self_like_obj.exists():
            self_like = Reaction.objects.get(user=request.user.id, content_type=model_name, object_id=obj.id).react_type
        else:
            self_like = False
        return self_like

答案 1 :(得分:2)

您可以在mixin类中实现get_liked方法,并将此类用作两个序列化程序的父级,如下所示:

class LikesMixin:
    def get_liked(self, obj):
        request = self.context.get('request')
        self_like_obj = Reaction.objects.filter(user=request.user.id, content_type=ContentType.objects.get(model='comment'), object_id=obj.id)
        if self_like_obj.exists():
            self_like = Reaction.objects.get(user=request.user.id, content_type=ContentType.objects.get(model='comment'), object_id=obj.id).react_type
        else:
            self_like = False
        return self_like

class CommentSerializer(ModelSerializer, LikesMixin):
    liked = SerializerMethodField()
    class Meta:
        model = Comment
        fields = [
            'id',
            'self_liked',
            'content'
        ]

class ArticleDetailSerializer(ModelSerializer, LikesMixin):
    liked = SerializerMethodField()
    class Meta:
        model = Article
        fields = [
            'id',
            'self_liked',
            'title'
        ]

答案 2 :(得分:1)

这是何时使用mixin class的一个很好的例子。 mixin是一个新类,它包含要在其他类中使用的方法和类属性,如下所示:

class LikedMixin(object):
    liked = SerializerMethodField()

    def get_liked(self, obj):
        request = self.context.get('request')
        self_like_obj = Reaction.objects.filter(user=request.user.id, content_type=ContentType.objects.get(model='article'), object_id=obj.id)
        if self_like_obj.exists():
            self_like = Reaction.objects.get(user=request.user.id, content_type=ContentType.objects.get(model='article'), object_id=obj.id).react_type
        else:
            self_like = False
        return self_like

然后,您可以声明您的序列化程序继承您的mixin:

class ArticleDetailSerializer(LikedMixin, ModelSerializer):
    class Meta:
        model = Article
        fields = [
            'id',
            'self_liked',
            'title'
        ]

class CommentSerializer(LikedMixin, ModelSerializer):
    class Meta:
        model = Comment
        fields = [
            'id',
            'self_liked',
            'content'
        ]

熟悉method resolution order in Python的基础知识可能是一个好主意,以便在轨道上识别与多重继承相关的任何潜在问题。