• 四、模型层(三)


    一、原生查询
    #### 方式1
    #### 包含主键
    ```
    for d in Stu.objects.raw('select * from t_stu'):
        print d
       
    Stu:zhangsan,88
    Stu:lisi,90
    Stu:wangwu,99
    Stu:zhangjie,66
    Stu:xiena,89

    ```
    #### 不包含主键
    ```
    for d in Stu.objects.raw('select sname,score from t_stu'):
        print d
       
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "C:Python27libsite-packagesdjangodbmodelsquery.py", line 1245, in __iter__
        raise InvalidQuery('Raw query must include the primary key')
    InvalidQuery: Raw query must include the primary key

    ```

     

    #### 方式2
    #### 包含主键
    ```
    from student.models import *
    from django.db import connection
    cursor = connection .cursor()
    cursor.execute('select * from t_stu')
    5L
    datas = cursor.fetchall()
    print datas
    ((1L, u'zhangsan', 88L, datetime.date(2018, 4, 7), 1L), (2L, u'lisi', 90L, datetime.date(2018, 4, 7), 2L), (3L, u'wangwu', 99L, datetime.date(2018, 4, 7), 3L), (4L, u'zhangjie', 66L, datetime.date(2018, 4, 7), 1L), (5L, u'xiena', 89L, datetime.date(2018, 4, 7), 3L))
    for d in datas:
        print d
    (1L, u'zhangsan', 88L, datetime.date(2018, 4, 7), 1L)
    (2L, u'lisi', 90L, datetime.date(2018, 4, 7), 2L)
    (3L, u'wangwu', 99L, datetime.date(2018, 4, 7), 3L)
    (4L, u'zhangjie', 66L, datetime.date(2018, 4, 7), 1L)
    (5L, u'xiena', 89L, datetime.date(2018, 4, 7), 3L)
    cursor.close()

    ```

    #### 不包含主键
    ```
    from student.models import *
    from django.db import connection
    cursor= connection.cursor()
    cursor.execute('select sname,score from t_stu')
    5L
    ds = cursor.fetchall()
    print ds
    ((u'zhangsan', 88L), (u'lisi', 90L), (u'wangwu', 99L), (u'zhangjie', 66L), (u'xiena', 89L))
    cursor.close()
    ```
    #### 获取一条记录
    ```
    from student.models import *
    from django.db import connection
    cursor= connection.cursor()
    cursor.execute('select * from t_stu where sno=1')
    1L
    cursor.fetchone()
    (1L, u'zhangsan', 88L, datetime.date(2018, 4, 7), 1L)
    cursor.close()
    ```

    #### 封装函数实现原生查询
    ```
    def test(sql):
        with connection.cursor() as c:
            c.execute(sql)
            print [d for d in c.fetchall()]

    ```
     
    #### MySQL外连接
    - SQL92:select * from ltable,rtable where ltable.column=rtable.column(+)
    - SQL99: select * from ltable left join rtable on (ltable.column=rtable.column)
    二、Q、F查询
    #### Q查询
    #### 查看底层SQL
    ```
    def showsql():
        from django.db import connection
        print connection.queries[-1]['sql']
    ```
    ```
    #条件与操作
    from student.models import *
    from django.db.models import Q,F
    Stu.objects.filter(Q(sno=1)&Q(sname='zhangsan'))
    <QuerySet [<Stu: Stu:zhangsan,88>]>
       
    showsql()
    SELECT `t_stu`.`sno`, `t_stu`.`sname`, `t_stu`.`score`, `t_stu`.`created`, `t_stu`.`clazz_id` FROM `t_stu` WHERE (`t_stu`.`sno` = 1 AND `t_stu`.`sname` = 'zhangsan') LIMIT 21
     
     
    Stu.objects.get(Q(sno=1)&Q(sname='zhangsan'))
    <Stu: Stu:zhangsan,88>
    showsql()
    SELECT `t_stu`.`sno`, `t_stu`.`sname`, `t_stu`.`score`, `t_stu`.`created`, `t_stu`.`clazz_id` FROM `t_stu` WHERE (`t_stu`.`sno` = 1 AND `t_stu`.`sname` = 'zhangsan')
    ```
     
    ```
    #条件或操作
    Stu.objects.filter(Q(created__gte='2017-12-12')|Q(sno=1))
    <QuerySet [<Stu: Stu:zhangsan,88>, <Stu: Stu:lisi,90>, <Stu: Stu:wangwu,99>, <Stu: Stu:zhangjie,66>, <Stu: Stu:xiena,89>]>
    showsql()
    SELECT `t_stu`.`sno`, `t_stu`.`sname`, `t_stu`.`score`, `t_stu`.`created`, `t_stu`.`clazz_id` FROM `t_stu` WHERE (`t_stu`.`created` >= '2017-12-12' OR `t_stu`.`sno` = 1) LIMIT 21
     
    ```

    ```
    #条件非操作
    Stu.objects.filter(~Q(sname='zhangsan'))
    <QuerySet [<Stu: Stu:lisi,90>, <Stu: Stu:wangwu,99>, <Stu: Stu:zhangjie,66>, <Stu: Stu:xiena,89>]>
    showsql()
    SELECT `t_stu`.`sno`, `t_stu`.`sname`, `t_stu`.`score`, `t_stu`.`created`, `t_stu`.`clazz_id` FROM `t_stu` WHERE NOT (`t_stu`.`sname` = 'zhangsan') LIMIT 21
     
    Stu.objects.filter(~Q(sname='zhangsan',sno=1))
    <QuerySet [<Stu: Stu:lisi,90>, <Stu: Stu:wangwu,99>, <Stu: Stu:zhangjie,66>, <Stu: Stu:xiena,89>]>
    showsql()
    SELECT `t_stu`.`sno`, `t_stu`.`sname`, `t_stu`.`score`, `t_stu`.`created`, `t_stu`.`clazz_id` FROM `t_stu` WHERE NOT (`t_stu`.`sno` = 1 AND `t_stu`.`sname` = 'zhangsan') LIMIT 21
    ```

    #### F查询
    ```
    #学号大于3的学生成绩加10分
    Stu.objects.filter(Q(sno__gt=3)).update(score=F('score')+10)
    2L
    showsql()
    UPDATE `t_stu` SET `score` = (`t_stu`.`score` + 10) WHERE `t_stu`.`sno` > 3
     
    #学号大于3的学生入学日期提前2天
    import datetime
    Stu.objects.filter(Q(sno__gt=3)).update(created=F('created')+datetime.timedelta(days=-2))
    2L
    showsql()
    UPDATE `t_stu` SET `created` = (`t_stu`.`created` + INTERVAL '172800.000000' SECOND_MICROSECOND) WHERE `t_stu`.`sno` > 3
     
    ```
    三、装饰器模式
    #### 装饰器的功能
    - 将被装饰的函数当作参数传递给与装饰器对应的函数(名称相同的函数),并返回包装后的被装饰的函数
    - 被修饰器修饰的函数具有相同特定的功能
        
    #### 二阶装饰器
    ```
    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>'

    ```
     
     四、事务处理
    #### Django中的事务处理
    - Django中的事务是自动提交模式
    ```
    # -*- 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)

        class Meta:
            db_table='t_stu'
        def __unicode__(self):
            return u'Stu:%s,%s'%(self.sname,self.score)
     
     
     

    ```
    #### 测试结果
    ```
    #两张表中都没有插入新数据
    from student.models import *
    stu = Stu(sname='xiaowang',score=88,clazz=Clazz(cname='Oracle'))
    stu.save()
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "C:Python27libsite-packagesdjangoutilsdecorators.py", line 185, in inner
        return func(*args, **kwargs)
      File "D:pythoncodesdjango_20180402demodemo3studentmodels.py", line 34, in save
        1/0
    ZeroDivisionError: integer division or modulo by zero

    ```
  • 相关阅读:
    常用git命令
    复制文件
    实现斗地主洗牌、发牌、看牌
    线程池实现多线程
    git无法提交问题
    Js中处理日期加减天数
    form详解
    node.js中exports与module.exports的区别
    css的direction属性
    webstorm基础使用
  • 原文地址:https://www.cnblogs.com/dangjingwei/p/12827032.html
走看看 - 开发者的网上家园