Django ORM操作日志记录

Django ORM操作日志记录

*【摘要】*

此文章是django模型orm操作时的日志记录,覆盖的方法有save,delete,create,update,bulk_update,bulk_create

*【正文】*

*自定义********QuerySet及操作方法*

import copy
from django.db import models
from django.db.models.query import QuerySet
from celery_tasks.appone.tasks import operate_log_task
from django.db import (connections, transaction)
from django.db.models.functions import Cast
from django.db.models.expressions import Case, Expression, Value, When


def get_current_request():
    # 获取当前登录用户,可通过中间件+threadlocal+偏函数实现
    return 'xxx'


class MyQuerySet(QuerySet):

    def bulk_create(self, objs, batch_size=None, ignore_conflicts=False, is_log=False):
        super(MyQuerySet, self).bulk_create(objs, batch_size=None, ignore_conflicts=False)
        operate_user = get_current_request()
        if is_log:
            for obj in objs:
                operate_log_task.delay("log_created", sender=type(obj), new_obj=obj, operate_user=operate_user)

    def bulk_update(self, objs, fields, batch_size=None, is_log=False, **kwargs):
        """
        Update the given fields in each of the given objects in the database.
        """
        if batch_size is not None and batch_size < 0:
            raise ValueError('Batch size must be a positive integer.')
        if not fields:
            raise ValueError('Field names must be given to bulk_update().')
        objs = tuple(objs)
        if any(obj.pk is None for obj in objs):
            raise ValueError('All bulk_update() objects must have a primary key set.')
        fields = [self.model._meta.get_field(name) for name in fields]
        if any(not f.concrete or f.many_to_many for f in fields):
            raise ValueError('bulk_update() can only be used with concrete fields.')
        if any(f.primary_key for f in fields):
            raise ValueError('bulk_update() cannot be used with primary key fields.')
        if not objs:
            return
        # PK is used twice in the resulting update query, once in the filter
        # and once in the WHEN. Each field will also have one CAST.
        max_batch_size = connections[self.db].ops.bulk_batch_size(['pk', 'pk'] + fields, objs)
        batch_size = min(batch_size, max_batch_size) if batch_size else max_batch_size
        requires_casting = connections[self.db].features.requires_casted_case_in_updates
        batches = (objs[i:i + batch_size] for i in range(0, len(objs), batch_size))
        updates = []
        for batch_objs in batches:
            update_kwargs = {}
            for field in fields:
                when_statements = []
                for obj in batch_objs:
                    attr = getattr(obj, field.attname)
                    if not isinstance(attr, Expression):
                        attr = Value(attr, output_field=field)
                    when_statements.append(When(pk=obj.pk, then=attr))
                case_statement = Case(*when_statements, output_field=field)
                if requires_casting:
                    case_statement = Cast(case_statement, output_field=field)
                update_kwargs[field.attname] = case_statement
            updates.append(([obj.pk
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值