• Django--数据库查询操作


    MySQL是几乎每一个项目都会使用的一个关系数据库,又因为它是开源免费的,所以很多企业都用它来作为自家后台的数据库。

    BAT这类大公司除外,它们的业务数据是以亿级别来讨论的,而MySQL的单表6000万条数据运行在64位操作系统中已经很吃力

    了,所以像BAT这类有钱,有需求的企业来说,用的数据库当然就是Oracle了。

    抛开Oracle不说,MySQL的优越性还是挺突出的,有面对大数据量的分表操作和比较强大的多表关联查询,索引优化查询速度

    等等。在中小型企业中还是很吃得开的。那么作为一个中小型的Django项目中,如何使用MySQL呢?本文的内容主要是介绍

    Django项目中如何通过ORM关系映射来操作MySQL数据库,内容比较基础,提供给初学者作为借鉴使用。

    关于什么是ORM关系映射,可以写一篇文章了,度娘上也有很多这类型的文章,我就不讨论了,这篇文章的主要内容还是关注

    在基础操作上。

    以下的案例一我自己曾经的一个项目,论坛网址为例来进行说明。

    首先我为我的网站建立了一个Author表,一个Article表,一个News表(实际上不止这些表),这里就以这些

    表为例进行说明。

    Author表和Aticle表我做了一个多对多的关联,News表相对独立。

    具体的表字段如下:

    Author(缩减版,为了降低学习难度)
    Id(用于索引)   Name    Phone    Password        
    
    Article表
    tid   Title   Content   Star(点赞数量)     Comment  
    
    News表
    Nid    Message  

    实际上以上这些表格的部分内容用非关系型数据库Mongodb来存更好,这里就不展开讨论了,以后有机会再谈谈

    自己的一些学习心得。

    一、数据库常用操作细节--增删查改

    (1)插入数据

    ORM有三种方法实现对数据库插入数据

    1.Django中可以直接通过Views(视图)在DB(数据库)中创建记录

    语法如下:
          Entry.objects.create(属性1=值,属性2=值)
    
          例如: Author.objects.create(id = 1, name=’Tom’, phone= '88888888888' , password = '123456')

    概念理解:什么是Entry?

    Entry的意思是实体,所有的数据库中的表都是通过实体来映射到程序中的。

    2. 创建一个实体对象用于进行数据库的操作,当向数据库中增加数据时,可以通过save()方法完成增加数据

    语法如下:
       obj= Entry(属性1=值,属性2=值)
       obj.save()
    
    例如:
       author = Author(id = 1, name=’Tom’, phone= '88888888888' , password = '123456')
       author.save()

    3. 通过字典创建实体对象,再调用save()

    例如:
      dic = {
          id = 1,
          name = ‘Tom’,
          phone = ‘88888888888’,
          password = '123456'
       }
          author = Author(**dic)
          author.save()

    (2)查询操作

    敲黑板,查询操作是数据库操作的重点内容,Django支持不少的查询操作,但是复杂点的关联操作,ORM就无法实现了?那怎么办?没有办法了吗?

    实现的方法是有的,用pymysql的原生语法去操作就可以了

    好了,言归正传,开始讲ORM的查询操作~~ 

    首先,要注意:所有的查询都要在Entry.objects的基础上完成

    1. 基本查询操作

     据说,Django已经查询语句的效率优化上已经达到最好,在ORM内部在B树的基础上做了一些修改。

          1)语法:all()

    用法:Entry.objects.all()     
    
    相当于原生SQL的  select * from     

    返回值:QuerySet(查询结果集),以字典的形式存储查询的结果,因此对结果取数据的时候可以使用python的字典方法

         

          2)语法:Entry.objects.all().values()

              查询所有记录的某一列的值

    例如:Author.objects.all().values()  
    
    相当于 select name from Author    

         3)语法: Entry.objects.all().values_list(‘列1’ , ’列2’)

    例如:Author.objects.all().values_list(‘name’,’age’ )
    
    相当于 select name,age from Author

      注意:一定是从查询结果集中进行筛选,即必须要有all()方法

         1.1版本可以直接用values(‘name’,’age’)  取多个列值

       

        4) 语法: Entry.objects.get()

          这条查询语句只能查找一条记录,也只能返回一条记录。如果查询返回多条记录会报错,即传入的参数一定要使得查询的记录只有一条,一般可以用id值

          如果不确定可以用try , except语句来捕捉错误

    例如:Author.objects.get(id=4)

         5) 语法: Entry.objects.exclude()

          作用:对给定条件取反

    1  例如:房屋租赁系统,不想查哪个地区的房源
    2    Entry.objects.exclude(id=3) 
    3    相当于 :select * from … where not id = 3;
    4 
    5 又例如:筛选id不是3,同时年龄不是35的客户 6 Entry.objects.exclude(id=3,age=35) 7 相当于 :select * from … where not (id = 3 and age=35);

        6) 语法: Entry.objects.order_by(‘列名1’ , ’ - 列名2’)

             对所有查询数据进行排序,可以多级排序(只需要多写几个列名就行)

             注意:默认是升序排序,需要降序的话,只需要在列名前加‘ - ’(减号)

       

        7)语法:Entry.objects.filter()

            根据自定义条件查询结果集。条件可以是一个,也可以是多个,多个的话,条件用’,’逗号隔开,其内部是使用AND来进行条件连接的。

           1. 使用Entry的属性来作为filter()的条件

       例如:Author.objects.filter(id=1)  
    相当于select
    * from author where id=1

           2. 使用Field Lookups (查询谓词,主要结合filter或者get一起用)

                    (1) __exact 等值判断(用得比较少)

                      语法:Entry.objects.get(id__exact=num)

            例如:Author.objects.get(id__exact=11)
    
            相当于select * from author where id=11

                    (2)__contains 模糊查询

           例如:Entry.objects.get(headline__contains = ‘Lennon’)
    
           相当于 select … where headline like  %Lennon%;     

                    (3)__in 范围查询

            例如:Entry.objects.get(id__in =[1,3,5])
    
            相当于 select  …. where  id  in [1,3,5]

                     (4)__gt  __lt   大于,小于查询

             例如:Entry.objects.get(id__gt=3)
    
             相当于  select  … where  id>3

                      (5) __startwith  以…开始  (注意与__contains区分)

             Entry.objects.get(headline__startwith = ‘Lennon’)
    
             相当于select … where headline like  Lennon%;

            3.子查询    

    例如:需求是获取比贾乃亮年龄要大的人
    
    inner = Author.objects.filter(name__exat=’贾乃亮’).values(‘age’)  #获取贾乃亮的年龄
    authors = Author.objects.filter(age__gt = inner)

    实际上是嵌套查询

    操作:

    获取结果集的内容,因为结果集是许多条记录(集合)组成的一个列表,所以可以用下标来索引每一条记录,再通过索引来获得具体的字段

    例如:name = authors[0][1]   
    第一天记录是贾乃亮相关的信息,信息下的第二个字段为姓名

    二、 F()操作和Q()操作

    1. F()操作

         在执行中获取某列的值,再进行增删改查。

         语法: F(‘列名’)

    例如: SQL语句中 update  author set age=age+10
    
    Django中写法:Author.object.all().update(age
    =F(‘age’)+10)

    注意:在用F()函数前需要导包(下面的Q()函数也一样)

        from  django.db.models  import F

        应用:一般用在累加操作

      

    2. Q()操作

    Author.objects.filter(id=1,age=35)  这种情况是id=1 and age=35,无法写or逻辑运算符

    可以使用以下的语法实现:

    Author.objects.filter(  Q(id_exact=1)|Q(age=35),name=’王’   )   #也可以用,逗号表示and

       and逻辑运算应用:登录系统的用户和密码验证

  • 相关阅读:
    vim 使用总结
    C语言中的条件编译
    getopt函数
    Linux 命令使用总结
    vim ctags cscope
    shell 定时处理
    shell 脚本中的标准输出
    ubuntu mail 命令发送邮件
    shell 编程中的特殊字符的处理
    system v 消息队列
  • 原文地址:https://www.cnblogs.com/thomson-fred/p/9785656.html
Copyright © 2020-2023  润新知