Rob*_*jic 12 python django django-rest-framework
我想在序列化程序中添加一个字段,其中包含特定于发出当前请求的用户的信息(我不想为此创建单独的端点).这是我做的方式:
视图集:
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
filter_class = ArticleFilterSet
def prefetch_likes(self, ids):
self.current_user_likes = dict([(like.article_id, like.pk) for like in Like.objects.filter(user=self.request.user, article_id__in=ids)])
def get_object(self, queryset=None):
article = super(ArticleViewSet, self).get_object(queryset)
self.prefetch_likes([article.pk])
return article
def paginate_queryset(self, queryset, page_size=None):
page = super(ArticleViewSet, self).paginate_queryset(queryset, page_size)
if page is None:
return None
ids = [article.pk for article in page.object_list]
self.prefetch_likes(ids)
return page
Run Code Online (Sandbox Code Playgroud)
序列化器:
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
def to_native(self, obj):
ret = super(ArticleSerializer, self).to_native(obj)
if obj:
view = self.context['view']
ret['has_liked'] = False
if hasattr(view, 'current_user_liked'):
ret['has_liked'] = obj.pk in view.current_user_liked
return ret
Run Code Online (Sandbox Code Playgroud)
是否有更好的地方注入喜欢的文章的预取,或更好的方式来做到这一般?
小智 26
你可以做到 SerializerMethodField
示例:
class PostSerializer(serializers.ModelSerializer):
fav = serializers.SerializerMethodField('likedByUser')
def likedByUser(self, obj):
request = self.context.get('request', None)
if request is not None:
try:
liked=Favorite.objects.filter(user=request.user, post=obj.id).count()
return liked == 1
except Favorite.DoesNotExist:
return False
return "error"
class Meta:
model = Post
Run Code Online (Sandbox Code Playgroud)
然后你应该从这个视图调用序列化器:
class PostView(APIVIEW):
def get(self,request):
serializers = PostSerializer(PostObjects,context={'request':request})
Run Code Online (Sandbox Code Playgroud)
我倾向于尝试尽可能多地将这个放在Like模型对象上,然后在自定义序列化器字段中将其余部分打包.
在序列化程序字段中,您可以访问它们从父序列化程序继承request的context参数.
所以你可能会这样做:
class LikedByUserField(Field):
def to_native(self, article):
request = self.context.get('request', None)
return Like.user_likes_article(request.user, article)
Run Code Online (Sandbox Code Playgroud)
然后,user_likes_article类方法可以封装您的预取(和缓存)逻辑.
我希望有所帮助.
| 归档时间: |
|
| 查看次数: |
9381 次 |
| 最近记录: |