1. 程式人生 > >django-orm進階操作

django-orm進階操作

進階操作

# 獲取個數
        #
        # 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等於112233的資料 # 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操作

進階操作 # 獲取個數 # # models.Tb1.objects.filter(name='seven').count() # 大於,小於 # # models

Django-ORM操作01

1.增刪改查 2.一般操作: models.UserInfo.objects.filter(id__gt=1) models.UserInfo.objects.filter(id__lt=1)

Django中的ORM操作

email 裏的 之間 value 保存 eight tor connector 做了 Django中是通過ORM來操作數據庫的,通過ORM可以很easy的實現與數據庫的交互。但是仍然有幾種操作是非常繞也特別容易混淆的。於是,針對這一塊,來一個分類總結吧。 對於ORM對數

Django - ORM -

django max bsp .html 接受 publish div postgresq prim 一、多表操作 創建模型 實例:我們來假定下面這些概念,字段和關系 作者模型:一個作者有姓名和年齡。 作者詳細模型:把作者的詳情放到詳情表,包含生日,手機號,家庭住址

django 基礎ORM 2

1.多表操作 新增記錄: 針對一對多 book_obj=Book.objects.create(title="python葵花寶典",price=100,publishDate="2012-12-12",publish_id=1)       &n

第10章:awk操作

模式 rpe .sh 定義變量 能夠 all 模式匹配 mon ble 第10章:awk進階操作      在第4章:查找與替換簡單的講解了awk的使用,本章介紹詳細講解awk的使用。awk是一個強大的文本分析工具,簡單的說awk就是把文件逐行的讀

第11章:sed操作

ssa str 插入 引號 ams 部分 情況 沒有 ims 第11章:sed進階操作 sed是一個很好的文件處理工具,本身是一個管道命令,主要是以行為單位進行處理,可以將數據行進行替換、刪除、新增、選取等特定工作,下面先了解一下sed的用法

python django -5

內容 search pic super dex this ava 搜索框 框架 高級知識點包括: 靜態文件處理 中間件 上傳圖片 Admin站點 分頁 使用jquery完成ajax 管理靜態文件 項目中的CSS、圖片、js都是靜態文件 配置靜態文件 在settin

Django Model

.get 用戶 opinion ngs 個數 mode migration 比較 xtra 回顧: 定義 models settings.py激活app才能使用models migrations:版本控制,當更改庫表結構時可以處理數據 增刪改查 常見Fi

【Vue實戰之路】一、Vue-cli全面詳解及操作

image 腳本 js基礎 這一 命令執行 bsp row 編譯 服務器 全面的Vue-cli學習,這一篇就夠了! 一、下載 使用vue-cli前,需先安裝node.js,node的安裝就不贅述,不過在此需要註意: 1. node版本需在4.x以上,首推6.x以上版本

Django-Ajax

load .post enc src sub ryu user memory word Ajax上傳文件 1、form表單上傳文件 文件和其他的數據類型不一樣,是一個二進制的形式 Form上傳文件的時候切記要加上:enctype="multipart/form-data"

Django基礎

讀取 編寫 編寫程序 pen hunk 文件路徑 settings 處理 oct 內容回顧: 1、Django請求生命周期 路由(URL) 視圖 (VIEW)  

Django篇】

mixins pan .html get temp emp eth log 16px 本章內容 Class View 登錄驗證   首頁get方法登錄驗證,方法一 from django.utils.decorators import metho

Python之路【第十七篇】:Django篇 】

HP aid 超時 args lan 內置 resp hang ive Model 到目前為止,當我們的程序涉及到數據庫相關操作時,我們一般都會這麽搞: 創建數據庫,設計表結構和字段 使用 MySQLdb 來連接數據庫,並編寫數據訪問層代碼 業務邏輯層去調用數據

Redis筆記整理(三):操作與高級部分

數據庫 NoSQL Redis [TOC] Redis筆記整理(三):進階操作與高級部分 Redis發布訂閱 Redis發布訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。 Redis客戶端可以訂閱任意數量的頻道。 下圖展示了頻道channel1,以

Django ORM那些相關操作

大小寫 closed base 項目 Nid 關聯對象 構造 大小 AD 一般操作 看專業的官網文檔,做專業的程序員! 必知必會13條 <1> all(): 查詢所有結果 <2> filter(**k

Git 操作(一)

topic 參考 origin hot parent ref selection 本地 vision 1. 獲取提交信息(commit) git show 1c002d(哈希值的前幾位): 獲取提交的信息; git show HEAD^: 顯示HEAD的上級(parent

Django ORM 多表操作

ins print 一個 npr auto 到你 聯系 asc pos 創建模型 實例:我們來假定下面這些概念,字段和關系 作者模型:一個作者有姓名和年齡。 作者詳細模型:把作者的詳情放到詳情表,包含生日,手機號,家庭住址等信息。作者詳情模型和作者模型之間是一對一的關系(o

Django ORM 一對多操作

主表 操作 length 成功 關聯 clas reat book 視圖 創建表 # models.py form django.db import models class Book(models.Model):  # 表名book,django會自動使用項目名+我

Django(ORM單表操作)

預設使用sqllite資料庫   建立資料庫 在app models中編寫建立資料庫類 from django.db import models class Book(models.Model):#表明book django 會自動使用專案名+我們自定義的表名 # 如果沒有自定