关于django的坑(一)

关于django orm 的坑:

  1. 关于设置数据库表自动更新

django的orm关于更新数据库的方法有update和save两种方法。想要表中自动更新需要一下几个条件:

  • 使用 DateTimeField 设置 auto_now_add 与 auto_now属性为True
  • 使用orm 模型的save方法,而不是update
update 更新回直接调用 sql(所以update比save快),而不会通过orm的model层,但 auto_now_add 与 auto_now 为 orm 层mode配置,不是数据库属性,所以造成update不会更新相应的时间段

      2. django 使用orm创建表数据,通过id执行相应celery任务,出现db记录不存在

    • 常用的解决办法:
    • ORM属于事物操作,在执行save方法之后,直接触发一步celery任务,数据记录没有存在需要对任务执行设置 countdown 延时执行,比如2s
    • 网上很多通过django模型信号 post_save(模型执行save后调用方法):
from django.db import models

@receiver(post_save, sender=AppTask) def post_save_db_task(sender, **kwargs): obj = kwargs['instance'] logger.info(f"{AppTask}任务创建成功,开始执行") celery_cb = obj.celery_task_cb print('callable(celery_cb) :', callable(celery_cb) ) # callable(celery_cb) and celery_cb(obj) # model新增操作 if kwargs['created']: # 参数里的created判断是新增还是更新模型 pass else: pass

post_save 数据django数据库ORM模型,在执行save保存后的后续操作,不属于事物,不属于数据库,仅为save之后执行的调用(y),与直接使用save为同样效果。确认是不可行

# 位于django.db.models.base  663-791 行
def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):
    """ 忽略 """
    self.save_base(using=using, force_insert=force_insert,
               force_update=force_update, update_fields=update_fields)
save.alters_data = True

def save_base(self, raw=False, force_insert=False,
              force_update=False, using=None, update_fields=None):
    """"""
    # Signal that the save is complete
    if not meta.auto_created:
        post_save.send(
            sender=origin, instance=self, created=(not updated),
            update_fields=update_fields, raw=raw, using=using,
        )
    •   确认可行的:通过事物操作
    •  1 from django.db import transaction
       2 
       3 class ApiUserScan(View):
       4     @classmethod
       5     def post(cls, request: WSGIRequest):
       6         # 添加扫描操作
       7         with transaction.atomic():
       8             """ 创建更新等操作 """
       9             transaction.on_commit(lambda: print("over"))
      10         return Resp.success(message="")

      创建事务,同时使用  transaction.on_commit(lambda: print("over"))手动提交,on_commit 作为提交保存到数据库后的回调,执行相应的操作,比如出发执行celery 异步任务,可确保新加入的数据已存在于数据库

原文地址:https://www.cnblogs.com/spaceapp/p/14187875.html