博客信息

Python Django 模型层(事务、懒加载、缓存)

发布时间:『 2019-08-17 04:27』  博客类别:Python  阅读(687)

事务本身是应用到了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>'




小李飞刀_Python




# -*- 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......


关键字:     Python       Django       懒加载       事务  

备案号:湘ICP备19000029号

Copyright © 2018-2019 javaxl晓码阁 版权所有