django-orm进阶操作
2018-01-29 17:49
591 查看
进阶操作
高级操作
QuerySet高级操作
在QuerySet的基础上继续执行子语句
extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
select-select_params
select占位符
where-params
and关系
举个例子:
select_related实现表之间进行一对一和多对一优化
实例代码如下:
以上代码中第一种查询方式会查询数据库六次,第二种方式会查询数据库次数为1次
prefetch_related实现表之间进行一对多和多对多优化
只能正向查询~且不能跨表
实例代码如下:
defer
实例代码如下:
a = models.Author.objects.all().defer(“name”).values()
虽然在查询中排除name字段,但是在循环中如果要输出关于name的信息,那么依然会继续查询输出name
only
示例代码如下:
raw执行原生SQL
执行原生SQL
为原生SQL设置参数
dates
示例代码如下:
datetimes
bulk_create
参数为一次性插入的个数
get_or_create
# 如果存在,则获取,否则,创建
# defaults 指定创建时,其他字段的值
update_or_create
如果存在,则更新,否则,创建
defaults 指定创建时或更新时的其他字段
in_bulk
# 根据主键ID进行查找
id_list = [11,21,31]
models.DDD.objects.in_bulk(id_list)
高级操作
QuerySet高级操作
进阶操作
# 获取个数 # # models.Tb1.objects.filter(name='seven').count() # 大于,小于 # # 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 # # models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据 # models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in # isnull # Entry.objects.filter(pub_date__isnull=True) # contains # # models.Tb1.objects.filter(name__contains="ven") # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 # models.Tb1.objects.exclude(name__icontains="ven") # range # # models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and # 其他类似 # # startswith,istartswith, endswith, iendswith, # order by # # models.Tb1.objects.filter(name='seven').order_by('id') # asc # models.Tb1.objects.filter(name='seven').order_by('-id') # desc # group by # # from django.db.models import Count, Min, Max, Sum # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num')) # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id" # limit 、offset # # models.Tb1.objects.all()[10:20] # regex正则匹配,iregex 不区分大小写 # # Entry.objects.get(title__regex=r'^(An?|The) +') # Entry.objects.get(title__iregex=r'^(an?|the) +') # 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在QuerySet的基础上继续执行子语句
extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
select-select_params
tmp = models.Book.objects.all().extra(select={"n":"select count(1) from app05_book"}) for i in tmp: print(i.title, i.n) 书一 6 书二 6 书三(第) 6 书四(第) 6 书五(第) 6 书六(第) 6
select占位符
tmp = models.Book.objects.all().extra(select={"n":"select count(1) from app05_book WHERE id>%s"},select_params=[3,]) for i in tmp: print(i.title, i.n) 书一 3 书二 3 书三(第) 3 书四(第) 3 书五(第) 3 书六(第) 3
where-params
models.Book.objects.extra(where=["title=%s"],params=["书一"]) <QuerySet [<Book: 书一>]>
models.Book.objects.extra(where=["title='书一' or title='书二'"]) <QuerySet [<Book: 书一>, <Book: 书二>]>
and关系
models.Book.objects.extra(where=["title='书一'","id=2"]) <QuerySet []>
举个例子:
models.UserInfo.objects.extra( select={'newid':'select count(1) from app01_usertype where id>%s'}, select_params=[1,], where = ['age>%s'], params=[18,], order_by=['-age'], tables=['app01_usertype'] ) """ select app01_userinfo.id, (select count(1) from app01_usertype where id>1) as newid from app01_userinfo,app01_usertype where app01_userinfo.age > 18 order by app01_userinfo.age desc """ # 执行原生SQL # 更高灵活度的方式执行原生SQL语句 # from django.db import connection, connections # cursor = connection.cursor() # cursor = connections['default'].cursor() # cursor.execute("""SELECT * from auth_user where id = %s""", [1]) # row = cursor.fetchone()
QuerySet高级操作
去重def distinct(self, *field_names) models.Book.objects.values("title").distinct() <QuerySet [{'title': '书一'}, {'title': '书三(第)'}, {'title': '书四(第)'}, {'title': '书五(第)'}, {'title': '书六(第)'}]>
select_related实现表之间进行一对一和多对一优化
def select_related(self, *fields) 性能相关:表之间进行join连表操作,一次性获取关联的数据。 总结: 1. select_related主要针一对一和多对一关系进行优化。 2. select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。
实例代码如下:
tmp = models.Book.objects.all() for i in tmp: print(i.publisher.name) 沙河出版社 沙河出版社 三里屯 五道口 国贸 五道口 a2 = models.Book.objects.all().select_related("publisher") for i in a2: print(i.publisher.name) 沙河出版社 沙河出版社 五道口 五道口 三里屯 国贸
以上代码中第一种查询方式会查询数据库六次,第二种方式会查询数据库次数为1次
prefetch_related实现表之间进行一对多和多对多优化
只能正向查询~且不能跨表
def prefetch_related(self, *lookups) 性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。 总结: 1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。 2. prefetch_related()的优化方式是分别查询每个表,然后用Python处理他们之间的关系。
实例代码如下:
tmp = models.Author.objects.all().prefetch_related("books") for i in tmp: print(i.books.all()) <QuerySet [<Book: 书一>, <Book: 书一>]> <QuerySet [<Book: 书一>, <Book: 书三(第)>]> <QuerySet [<Book: 书一>]> <QuerySet []>
defer
def defer(self, *fields): models.UserInfo.objects.defer('username','id') 或 models.UserInfo.objects.filter(...).defer('username','id') #映射中排除某列数据
实例代码如下:
a = models.Author.objects.all().defer("name") for i in a: print(i) 小一 小二 小三 小四 a = models.Author.objects.all().defer("name").values() for i in a: print(i) {'id': 1, 'name': '小一', 'author_detail_id': 1} {'id': 2, 'name': '小二', 'author_detail_id': 2} {'id': 3, 'name': '小三', 'author_detail_id': 3} {'id': 4, 'name': '小四', 'author_detail_id': 4}
a = models.Author.objects.all().defer(“name”).values()
虽然在查询中排除name字段,但是在循环中如果要输出关于name的信息,那么依然会继续查询输出name
only
def only(self, *fields): #仅取某个表中的数据 models.UserInfo.objects.only('username','id') 或 models.UserInfo.objects.filter(...).only('username','id')
示例代码如下:
a = models.Author.objects.only("name") for i in a: print(i) 小一 小二 小三 小四
raw执行原生SQL
执行原生SQL
tmp = models.Author.objects.raw("select * from app05_author") for i in tmp: print(i.name) 小一 小二 小三 小四
为原生SQL设置参数
a = models.Book.objects.raw("select id from app05_book WHERE id>%s",params=[3,]) for i in a: print(i) 书四(第) 书五(第) 书六(第)
dates
def dates(self, field_name, kind, order='ASC'): # 根据时间进行某一部分进行去重查找并截取指定内容 # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日) # order只能是:"ASC" "DESC" # 并获取转换后的时间 - year : 年-01-01 - month: 年-月-01 - day : 年-月-日 models.DatePlus.objects.dates('ctime','day','DESC')
示例代码如下:
models.Book.objects.all().dates("publish_day","year","DESC") <QuerySet [datetime.date(2018, 1, 1), datetime.date(2017, 1, 1)]> models.Book.objects.all().dates("publish_day","month","DESC") <QuerySet [datetime.date(2018, 4, 1), datetime.date(2018, 1, 1), datetime.date(2017, 1, 1)]> models.Book.objects.all().dates("publish_day","day","DESC") <QuerySet [datetime.date(2018, 4, 12), datetime.date(2018, 1, 29), datetime.date(2018, 1, 25), datetime.date(2018, 1, 19), datetime.date(2018, 1, 11), datetime.date(2017, 1, 18)]>
datetimes
def datetimes(self, field_name, kind, order='ASC', tzinfo=None): # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间 # kind只能是 "year", "month", "day", "hour", "minute", "second" # order只能是:"ASC" "DESC" # tzinfo时区对象 models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC) models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai')) """ pip3 install pytz import pytz pytz.all_timezones pytz.timezone(‘Asia/Shanghai’) """
bulk_create
参数为一次性插入的个数
objs = [models.Publisher(name="aaa",addr="aaa"),models.Publisher(name="bbb",addr="bbb")] models.Publisher.objects.bulk_create(objs,2) [<Publisher: aaa>, <Publisher: bbb>]
get_or_create
# 如果存在,则获取,否则,创建
# defaults 指定创建时,其他字段的值
models.Publisher.objects.get_or_create(name="沙河出版社") (<Publisher: 沙河出版社>, False) models.Publisher.objects.get_or_create(name="沙河出版社1") (<Publisher: 沙河出版社1>, True) models.Publisher.objects.get_or_create(name="沙河出版1",addr="sss") (<Publisher: 沙河出版1>, True) models.Publisher.objects.get_or_create(name="沙河版1",defaults={"addr":"sdfsdsf"}) (<Publisher: 沙河版1>, True)
update_or_create
如果存在,则更新,否则,创建
defaults 指定创建时或更新时的其他字段
obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})
in_bulk
# 根据主键ID进行查找
id_list = [11,21,31]
models.DDD.objects.in_bulk(id_list)
from app05 import models models.Book.objects.in_bulk([1,2,3]) (0.000) SELECT @@SQL_AUTO_IS_NULL; args=None (0.001) SELECT VERSION(); args=None (0.002) SELECT `app05_book`.`id`, `app05_book`.`title`, `app05_book`.`price`, `app05_book`.`publish_day`, `app05_book`.`publisher_id` FROM `app05_book` WHERE `app05_book`.`id` IN (1, 2, 3); args=(1, 2, 3) {1: <Book: 书一>, 2: <Book: 书一>, 3: <Book: 书三(第)>}
相关文章推荐
- Django(六)、ORM操作进阶
- Django中的ORM进阶操作
- python3开发进阶-Django框架中的ORM的常用操作的补充(F查询和Q查询,事务)
- Django进阶Model篇—数据库操作(ORM)
- Django进阶(二) 数据库的ORM操作之多对多
- python3开发进阶-Django框架中的ORM的常用(增,删,改,查)操作
- Django-ORM进阶操作02
- Django进阶Model篇004 - ORM常用操作
- Django进阶(一) 数据库的ORM操作之一对多
- Django-ORM进阶操作01
- 【原创】Django-ORM进阶
- Django视图之ORM连表操作一
- Django(三) ORM 数据库操作
- 13.Django之数据库models&orm连表操作补充以及其他知识点补充(二)
- Django视图之ORM数据库查询操作API
- Django入门4: ORM 数据库操作
- Django Orm 前端中跨表操作
- Django视图之ORM数据库查询操作API的实例
- Python/Django(CBV/FBV/ORM操作)
- Django基于ORM操作数据库的方法详解