我有两个使用相同功能的序列化程序。我想将它定义为静态方法并重用它。
文章序列化
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
如何将其定义为静态方法以供重用?
答案 0 :(得分:3)
由于 @neverwalkaloner 建议您只能在mixin类中实现一次方法,并将此类用作两个序列化程序的父级。请注意,get_liked
和ArticleDetailSerializer
序列化程序中的CommentSerializer
方法不同。
ArticleDetailSerializer
方法有ContentType.objects.get(model='article')
行但CommentSerializer
有ContentType.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的基础知识可能是一个好主意,以便在轨道上识别与多重继承相关的任何潜在问题。