django drf 统一处理操作人和时间字段

场景

如果你的表结构有这些字段:创建人/创建时间/更新人/更新时间/删除人/删除时间,我们可以统一处理这些字段的更新和插入,而不需要额外显示操作。

代码

1.ActionViewSetMixin:

python 复制代码
import datetime
from rest_framework import status
from rest_framework.response import Response



class ActionViewSetMixin:

   def destroy_mixin(self, request):
       instance = self.get_object()
       data = {
           "deleted_by": request.user.username,
           "deleted_at": datetime.datetime.now(),
           "is_deleted": True,
       }
       serializer = self.get_serializer(instance, data=data, partial=True)
       serializer.is_valid(raise_exception=True)
       self.perform_update(serializer)

       if getattr(instance, "_prefetched_objects_cache", None):
           # If 'prefetch_related' has been applied to a queryset, we need to
           # forcibly invalidate the prefetch cache on the instance.
           instance._prefetched_objects_cache = {}

       return Response(serializer.data)

   def destroy(self, request, *args, **kwargs):
       return self.destroy_mixin(request)

   def update_mixin(self, request, serializer):
       serializer.is_valid(raise_exception=True)
       data = serializer.validated_data
       data["updated_by"] = request.user.username
       data["updated_at"] = datetime.datetime.now()
       partial = True
       instance = self.get_object()
       serializer = self.get_serializer(instance, data=data, partial=partial)
       serializer.is_valid(raise_exception=True)
       self.perform_update(serializer)

       if getattr(instance, "_prefetched_objects_cache", None):
           # If 'prefetch_related' has been applied to a queryset, we need to
           # forcibly invalidate the prefetch cache on the instance.
           instance._prefetched_objects_cache = {}

       return Response(serializer.data)

   def update(self, request, *args, **kwargs):
       serializer_class = kwargs.pop("serializer", self.get_serializer)
       return self.update_mixin(request, serializer_class(data=request.data))

   def create_mixin(self, request, *args, **kwargs):
       data = request.data.copy()
       data["created_by"] = request.user.username
       data["created_at"] = datetime.datetime.now()
       serializer_class = kwargs.pop("serializer", self.get_serializer)
       serializer = serializer_class(data=data)
       serializer.is_valid(raise_exception=True)
       self.perform_create(serializer)
       headers = self.get_success_headers(serializer.data)
       return Response(
           serializer.data, status=status.HTTP_201_CREATED, headers=headers
       )

   def create(self, request, *args, **kwargs):
       return self.create_mixin(request, *args, **kwargs)

2.APIModelViewSet继承ModelViewSet和ActionViewSetMixin:

python 复制代码
from rest_framework.viewsets import ModelViewSet

from common.drf.mixins import ActionViewSetMixin, ResponseMixin


class APIModelViewSet(ActionViewSetMixin, ResponseMixin, ModelViewSet):
   extra_permissions = []  # 不覆盖默认的权限
   action_extra_permission_mapping = {}

   def parse_page_params(self):
       if self.request.method == "GET":
           page = self.request.query_params.get("page", 1)
           page_size = self.request.query_params.get("page_size", 10)
       else:
           page = self.request.data.get("page", 1)
           page_size = self.request.data.get("page_size", 10)
       try:
           return int(page), int(page_size)
       except Exception as e:
           return 1, 10

   def get_permissions(self):
       permissions = super(APIModelViewSet, self).get_permissions()

       extra = [x() for x in self.extra_permissions]
       action = self.action_extra_permission_mapping.get(self.action, [])
       return permissions + extra + [p() for p in action]

   @classmethod
   def get_validated_params(cls, serializer, params):
       s = serializer(data=params)
       s.is_valid(raise_exception=True)
       return s.validated_data

3.视图类继承APIModelViewSet:

python 复制代码
class ScanRecordViewSet(APIModelViewSet):
   queryset = models.ScanRecord.exclude_deleted_objects.all()
   serializer_class = serializers.ScanRecordSerializer
   pagination_class = DataPageNumberPagination
   filter_backends = [CustomFilterBackend, SearchFilter]

   search_fields = ["status", "mode", 'risk']
   custom_query_fields = ["status", "mode", "risk"]
相关推荐
hyhrosewind26 分钟前
Python函数基础:说明文档(多行注释),函数嵌套调用,变量作用域(局部,全局,global关键字),综合案例
python·变量作用域·函数说明文档(多行注释)·函数嵌套调用·局部变量和全局变量·函数内修改全局变量·global关键字
一点.点1 小时前
李沐动手深度学习(pycharm中运行笔记)——04.数据预处理
pytorch·笔记·python·深度学习·pycharm·动手深度学习
一点.点1 小时前
李沐动手深度学习(pycharm中运行笔记)——07.自动求导
pytorch·笔记·python·深度学习·pycharm·动手深度学习
大霸王龙2 小时前
Python对比两张CAD图并标记差异的解决方案
python·opencv·计算机视觉
萧鼎3 小时前
PDFMathTranslate:让数学公式在PDF翻译中不再痛苦
python·pdf
@_猿来如此3 小时前
Django 实现电影推荐系统:从搭建到功能完善(附源码)
数据库·后端·python·django
Python×CATIA工业智造3 小时前
爬虫技术入门:基本原理、数据抓取与动态页面处理
爬虫·python·pycharm
fmdpenny3 小时前
用python写一个相机选型的简易程序
开发语言·python·数码相机
敲敲敲-敲代码4 小时前
【PyCharm- Python- ArcGIS】:安装一个和 ArcGIS 不冲突的独立 Python让PyCharm 使用 (解决全过程记录)
python·arcgis·pycharm
猿榜编程4 小时前
python基础-requests结合AI实现自动化数据抓取
开发语言·python·自动化