天天看點

django的orm架構(進階篇)

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: 書一>]> 1 2 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處理他們之間的關系。 1 2 3 4 5 6 執行個體代碼如下: 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')     #映射中排除某列資料 1 2 3 4 5 執行個體代碼如下: 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: 書三(第)>}

轉載于:https://www.cnblogs.com/zhangtq/p/10536797.html