DRF框架下如何实现每次接口请求时Module模型view_count字段自增1
错误原因
- 你使用的
ListAPIView是列表类视图,用于返回多个Module实例集合,本身不提供get_object()方法(该方法属于单实例查询视图如RetrieveAPIView),且代码中self.get_object没有加调用括号,拿到的是方法对象而非模型实例,调用属性直接报错。 obj.save(view_count="view_count")写法完全错误,save()方法没有直接传入字段键值对的用法,且你传入了字符串类型值给数值类型的view_count字段,会触发字段类型校验错误。- 直接读取
view_count值+1再保存的方式存在并发问题,多请求同时更新时会出现计数不准的情况。
正确实现方案
根据你的业务场景二选一即可:
场景1:请求单个Module详情时,对应实例的view_count自增
将视图改为继承RetrieveAPIView(用于单实例查询),代码如下:
from django.db.models import F from rest_framework import generics class ModuleView(generics.RetrieveAPIView): queryset = Module.objects.all() serializer_class = ModuleSerializer def get(self, request, *args, **kwargs): # 原子自增,避免并发计数错误 self.get_queryset().filter(pk=self.kwargs['pk']).update(view_count=F('view_count') + 1) return super().get(request, *args, **kwargs)
路由配置需要传入主键参数,示例:path('modules/<int:pk>/', ModuleView.as_view(), name='module-detail')
备注:如果你的业务绑定了
Module模型的save信号需要触发,可以替换自增逻辑为:obj = self.get_object() obj.view_count += 1 obj.save(update_fields=['view_count']) # 仅更新指定字段,提升性能
场景2:请求Module列表时,所有返回的Module的view_count都自增
保留ListAPIView,修改get方法逻辑即可:
from django.db.models import F from rest_framework import generics class ModuleView(generics.ListAPIView): queryset = Module.objects.all() serializer_class = ModuleSerializer def get(self, request, *args, **kwargs): # 所有Module的访问量原子自增1 self.get_queryset().update(view_count=F('view_count') + 1) return super().get(request, *args, **kwargs)
如果你的业务逻辑有特殊判断,比如只需要给符合某个过滤条件的Module自增,修改filter()里的过滤条件即可。
内容的提问来源于stack exchange,提问作者surya raj
相关产品推荐
相关产品推荐

