事务本身是应用到了Python中的装饰器部分的知识
装饰器的功能
- 将被装饰的函数当作参数传递给与装饰器对应的函数(名称相同的函数),并返回包装后的被装饰的函数
- 被修饰器修饰的函数具有相同特定的功能
二阶装饰器
def a(func): def _wrapper(*args,**kwargs): content = func(*args,**kwargs) return '<b>%s</b>'%content return _wrapper @a def b(): return 'hello world' b() '<b>hello world</b>'
三阶装饰器
def a(bold=True): def _wrapper(func): def __wrapper(*args,**kwargs): content = func(*args,**kwargs) if bold: return '<b>%s</b>'%content else: return '<i>%s</i>'%content return __wrapper return _wrapper @a(bold=False) def b(): return 'hello world' b() '<i>hello world</i>'
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models # Create your models here. class Clazz(models.Model): cno = models.AutoField(primary_key=True) cname = models.CharField(max_length=30) class Meta: db_table = 't_cls' def __unicode__(self): return u'Clazz:%s,%s' % (self.cno, self.cname) class Stu(models.Model): sno = models.AutoField(primary_key=True) sname = models.CharField(max_length=30) score = models.PositiveIntegerField(max_length=3) created = models.DateField(auto_now_add=True) clazz = models.ForeignKey(Clazz, on_delete=models.CASCADE) from django.db.transaction import atomic # 原子性 @atomic def save(self, force_insert=False, force_update=False, using=None, update_fields=None): try: self.clazz = Clazz.objects.get(cname=self.clazz.cname) except Clazz.DoesNotExist: self.clazz = Clazz.objects.create(cname=self.clazz.cname) # 制造异常 1 / 0 models.Model.save(self, force_insert, force_update, using, update_fields) def __unicode__(self): return u'Stu:%s,%s' % (self.sname, self.score)
加了原子性注解,Python console进行测试,数据库中t_cls表中是不会加数据的
from trans.models import * stu = Stu(sname='javaxl',score=88,clazz=Clazz(cname='python')) stu.save() Traceback (most recent call last): File "<input>", line 1, in <module> File "E:\workspace\pyCharmProject\test5\venv\lib\site-packages\django\utils\decorators.py", line 185, in inner return func(*args, **kwargs) File "E:\workspace\pyCharmProject\test5\trans\models.py", line 38, in save 1 / 0 ZeroDivisionError: integer division or modulo by zero
若是将@atomic注释掉,那么数据库中t_cls表中是会加数据的(同样执行上述操作)
惰性查询
1. 延迟查询
2. 默认查询前21条数据
3. 什么时候需要数据进行查询
将1/0注释掉,先准备点数据
from trans.models import * stu = Stu(sname='javaxl',score=88,clazz=Clazz(cname='java')) stu.save() stu = Stu(sname='晓码阁',score=88,clazz=Clazz(cname='T224')) stu.save() stu = Stu(sname='小李飞刀',score=88,clazz=Clazz(cname='T224')) stu.save()
默认查询前21条数据、延迟查询、什么时候需要数据进行查询
def showsql(): from django.db import connection print connection.queries[-1]['sql'] showsql() INSERT INTO "trans_stu" ("sname", "score", "created", "clazz_id") VALUES ('小李飞刀', 88, '2019-08-16', 4) Stu.objects.filter(sname='晓码阁') <QuerySet [<Stu: Stu:晓码阁,88>]> showsql() SELECT "trans_stu"."sno", "trans_stu"."sname", "trans_stu"."score", "trans_stu"."created", "trans_stu"."clazz_id" FROM "trans_stu" WHERE "trans_stu"."sname" = '晓码阁' LIMIT 21 stus = Stu.objects.all() showsql() SELECT "trans_stu"."sno", "trans_stu"."sname", "trans_stu"."score", "trans_stu"."created", "trans_stu"."clazz_id" FROM "trans_stu" WHERE "trans_stu"."sname" = '晓码阁' LIMIT 21 for s in stus: print s Stu:javaxl,88 Stu:晓码阁,88 Stu:小李飞刀,88 showsql() SELECT "trans_stu"."sno", "trans_stu"."sname", "trans_stu"."score", "trans_stu"."created", "trans_stu"."clazz_id" FROM "trans_stu"
从上面Python console中的打印来看,
Stu.objects.filter(sname='晓码阁'):证明了默认查询21条数据,提升了性能
stus = Stu.objects.all():证明了延迟加载,因为showsql()还是上次执行的sql
for s in stus::进一步证明了延迟加载
over......
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有