Django笔记(十一)实现对数据库的各种操作,比如分组,排序等

2021-11-15 16:15:09 浏览数 (1)

目录

  • 获取查询出来的个数
  • 大于小于
  • in 在列表里面
  • contains 包含某一个东西
  • range 范围
  • 排序
  • 分组 annotate
    • 聚合函数
    • 分组配合聚合函数
  • aggregate
    • 聚合函数
  • 不等于
  • F()
  • Q()
  • 分页limit , offset
  • 根据单个年,月,日,时分秒进行查询
  • extra 额外操作,实现字典码翻译
    • select
    • select_params
    • where 和 params
    • order_by 排序
    • tables 查询哪个表
  • Django里面执行原生SQL
  • reverse 倒叙
  • all() 和 value() 获取到的结果是不同类型
  • only() 仅仅取出这个里面写的字段
  • defer() 取出除了这个里面的其他字段
  • using() 指定去哪个数据库拿数据
  • values()获取每行数据为字典格式
  • values_list() 获取每行数据为元祖
  • bulk_create()批量创建数据
  • get_or_create()
  • update_or_create()
  • in_bulk()

获取查询出来的个数

代码语言:javascript复制
models.Tb1.objects.filter(name='seven').count()

大于小于

代码语言:javascript复制
        # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
        # models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
        # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

in 在列表里面

代码语言:javascript复制
        # in
        #
        # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

contains 包含某一个东西

代码语言:javascript复制
        # contains
        #
        # models.Tb1.objects.filter(name__contains="ven")
        # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
        # models.Tb1.objects.exclude(name__icontains="ven")

range 范围

代码语言:javascript复制
   # range
        #
        # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and

排序

默认从小到大,加减号,是从大到小

多个字段进行排序

代码语言:javascript复制
# models.Tb1.objects.filter(name='seven').order_by('id')    # asc
# models.Tb1.objects.filter(name='seven').order_by('-id')   # desc

分组 annotate

聚合函数

代码语言:javascript复制
from django.db.models import Count, Min, Max, Sum

分组配合聚合函数

我们想要以某一个字段进行分组,我们一般想到的MySQL语句是

代码语言:javascript复制
select   count(1)  as  count     
from  student     group   by    age

那么Django如果实现以上的功能,不仅仅以一个字段进行分组,而且还给查询出的字段起别名

以上生成的sql语句是

代码语言:javascript复制
SELECT `myfirst_article`.`category_id`, 
COUNT(`myfirst_article`.`id`)     AS    `c` 
FROM `myfirst_article`     GROUP BY 
`myfirst_article`.`category_id`     ORDER BY NULL

aggregate

聚合函数

整个表进行分组

代码语言:javascript复制
from django.db.models import Count, Min, Max, Sum
代码语言:javascript复制
   # 聚合函数,获取字典类型聚合结果
   from django.db.models import Count, Avg, Max, Min, Sum
   result = models.UserInfo.objects.aggregate(

k=Count('u_id', distinct=True), n=Count('nid')

)
   ===> {'k': 3, 'n': 4}

不等于

代码语言:javascript复制
    Article.objects.exclude(id=1)

F()

我们在做更新的时候,获取上一次的值 比如我们想要将一个字段的值加一,不需要每一次都拿出来加一之后再保存,可以这样写

代码语言:javascript复制
 # from django.db.models import F
 
    # Tb1.objects.update(num=F('num') 1)

Q()

用这个函数,实现多个条件的查询,且 或关系的查询

组合搜索的时候,就会使用这个

代码语言:javascript复制
    # 方式一:
    # Q(nid__gt=10)
    # Q(nid=8) | Q(nid__gt=10)
    # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')





    # 方式二:
    # con = Q()


    # q1 = Q()
    # q1.connector = 'OR'
    # q1.children.append(('id', 1))
    # q1.children.append(('id', 10))
    # q1.children.append(('id', 9))
q1 对象里面的3个数据是或者关系



    # q2 = Q()
    # q2.connector = 'OR'
    # q2.children.append(('c1', 1))
    # q2.children.append(('c1', 10))
    # q2.children.append(('c1', 9))
q2 对象里面的3个数据是或者关系

    # con.add(q1, 'AND')

    # con.add(q2, 'AND')
    #
    # models.Tb1.objects.filter(con)

使用

以上就这样写

分页limit , offset

代码语言:javascript复制
    # models.Tb1.objects.all()[10:20]

根据单个年,月,日,时分秒进行查询

代码语言:javascript复制
		# date
        #
        # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
        # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))



        # year
        #
        # Entry.objects.filter(pub_date__year=2005)
        # Entry.objects.filter(pub_date__year__gte=2005)



        # month
        #
        # Entry.objects.filter(pub_date__month=12)
        # Entry.objects.filter(pub_date__month__gte=6)



        # day
        #
        # Entry.objects.filter(pub_date__day=3)
        # Entry.objects.filter(pub_date__day__gte=3)



        # week_day
        #
        # Entry.objects.filter(pub_date__week_day=2)
        # Entry.objects.filter(pub_date__week_day__gte=2)



        # hour
        #
        # Event.objects.filter(timestamp__hour=23)
        # Event.objects.filter(time__hour=5)
        # Event.objects.filter(timestamp__hour__gte=12)



        # minute
        #
        # Event.objects.filter(timestamp__minute=29)
        # Event.objects.filter(time__minute=46)
        # Event.objects.filter(timestamp__minute__gte=29)



        # second
        #
        # Event.objects.filter(timestamp__second=31)
        # Event.objects.filter(time__second=2)
        # Event.objects.filter(timestamp__second__gte=31)

extra 额外操作,实现字典码翻译

我们要实现以上的功能

他的参数是什么,我们看源码

观察源码,有好多的参数,我们下面解释这些参数的值可以如何写

select

代码语言:javascript复制
    shutype = Article.objects.all().extra(
    select={'count':"select count(1) from myfirst_article"}
    )
    for item in shutype:
        print(item.count)

以上查询条件生成的sql语句是

代码语言:javascript复制
SELECT 


(select count(1) from myfirst_article ) AS `count`, 
`myfirst_article`.`id`, 
`myfirst_article`.`title`,
 `myfirst_article`.`content`,
  `myfirst_article`.`category_id` 


FROM `myfirst_article`

select_params

这个里面写的是具体的变量,就是我们的sql语句里面有些是变化的,我们可以用这个参数作为入参

代码语言:javascript复制
shutype = Article.objects.all().extra(

select={'count':"select count(1) from myfirst_article 
        where id>%s"},select_params=[1]
        )
    
for item in shutype:
        print(item.count)

以上查询条件生成的sql语句是

代码语言:javascript复制
SELECT 

0
(select count(1) from myfirst_article where id>1) AS `count`, 
`myfirst_article`.`id`,
 `myfirst_article`.`title`, 
 `myfirst_article`.`content`, 
 `myfirst_article`.`category_id`


 FROM `myfirst_article`

where 和 params

或者关联的查询条件

代码语言:javascript复制
shutype = Article.objects.all().extra(
          where=['id=%s or id=%s'], params=['1','2']
          )


for item in shutype:
    print(item.title)

也就是拼接where后面的条件 以上生成的sql语句是

代码语言:javascript复制
SELECT 

`myfirst_article`.`id`,
 `myfirst_article`.`title`, 
 `myfirst_article`.`content`, 
 `myfirst_article`.`category_id`


 FROM `myfirst_article` WHERE (id=1 or id=2)

and的查询条件

代码语言:javascript复制
    shutype = Article.objects.all().extra(
			where=['id=%s ',' id=%s'], params=['1','2']
		)


for item in shutype:
        print(item.title)

以上生成的sql语句是

代码语言:javascript复制
SELECT 

`myfirst_article`.`id`, 
`myfirst_article`.`title`, 
`myfirst_article`.`content`, 
`myfirst_article`.`category_id` 


FROM `myfirst_article` WHERE (id=1 ) AND ( id=2)

order_by 排序

代码语言:javascript复制
SELECT 

`myfirst_article`.`id`,
 `myfirst_article`.`title`, 
 `myfirst_article`.`content`,
  `myfirst_article`.`category_id`

 FROM    `myfirst_article` 
WHERE (id=1 ) AND ( id=2)

 ORDER BY `myfirst_article`.`id` DESC

tables 查询哪个表

代码语言:javascript复制
    shutype = Article.objects.all().extra(
    tables=['myfirst_category'])
    for item in shutype:
        print(item.title)

查询多个表

代码语言:javascript复制
SELECT 

`myfirst_article`.`id`, 
`myfirst_article`.`title`, 
`myfirst_article`.`content`, 
`myfirst_article`.`category_id` 

FROM `myfirst_article` , `myfirst_category`

Django里面执行原生SQL

有的查询比较复杂,用原生sql语句是比较的简单

代码语言:javascript复制
    #
    # from django.db import connection, connections
    # cursor = connection.cursor()    这个是默认的数据源

Django支持多个数据源,用以下的写法选择某一个数据源
     # cursor = connections['default'].cursor()
     
    # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
  
    # row = cursor.fetchone()

reverse 倒叙

代码语言:javascript复制
 def reverse(self):
    # 倒序
    models.UserInfo.objects.all().order_by('-nid').reverse()
    # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序

用这个前面必须有order_by()函数

all() 和 value() 获取到的结果是不同类型

all()

value()

only() 仅仅取出这个里面写的字段

仅仅取出这个里面写的字段

以上这样写法,查询出的还是对象

defer() 取出除了这个里面的其他字段

取出除了这个里面的其他字段

查询出的还是对象

using() 指定去哪个数据库拿数据

指定去哪个数据库拿数据

values()获取每行数据为字典格式

获取每行数据为字典格式

values_list() 获取每行数据为元祖

获取每行数据为元祖

bulk_create()批量创建数据

get_or_create()

代码语言:javascript复制
    # 如果存在,则获取,否则,创建
    # defaults 指定创建时,其他字段的值
    obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2})

update_or_create()

代码语言:javascript复制
    # 如果存在,则更新,否则,创建
    # defaults 指定创建时或更新时的其他字段
    obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})

in_bulk()

代码语言:javascript复制
   # 根据主键ID进行查找
   id_list = [11,21,31]
   UserInfo.objects.in_bulk(id_list)

0 人点赞