真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

DjangoORM的示例分析

這篇文章給大家分享的是有關(guān)Django ORM的示例分析的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

我們提供的服務(wù)有:做網(wǎng)站、成都做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、敖漢ssl等。為1000+企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的敖漢網(wǎng)站制作公司

先來說下兩張表emp,dept。

emp表的數(shù)據(jù)如下:

Django ORM的示例分析

dept表的數(shù)據(jù)如下:

Django ORM的示例分析

然后我們就開始吧,有的同學(xué)說我的數(shù)據(jù)還沒有初始化,可以移步上一篇找到腳本。

對于QuerysetAPI的內(nèi)容,如果看文檔有非常多的解釋和介紹,很難抓到重點(diǎn),我就從我的認(rèn)知來梳理一下。

1. QuerySet 創(chuàng)建對象的方法

>>> from scott.models import emp

>>> from scott.models import dept

先得到所有的數(shù)據(jù)。

>>> emp.objects.all()

[ , , , , , , , , , , , , , , ]

>>> dept.objects.all()

[ , , , ]

第一種方法是使用create

>>> dept.objects.create( dname= 'DEV',loc= 'Beijing')

第二種是初始化另外一個對象,save完成

>>> newdept = dept( dname= 'TEST',loc= 'ShangHai')

>>> newdept.save()

第三種和第二種有些類似,可以對立面的屬性根據(jù)需求改變。

>>> #method 3

>>> newdept.dname

'TEST'

>>> newdept=dept()

>>> newdept.dname

u''

>>> newdept.dname= 'OPS'

>>> newdept.loc= 'Guangzhou'

>>> newdept.save()

第四種會做一個判斷,有點(diǎn)類似數(shù)據(jù)庫立面的create or replace,注意此處的返回是一個布爾值。

>>> dept.objects.get_or_create( dname= 'DBA',loc= 'Shenzhen')

( , True) 2.查詢語句根據(jù)主鍵查詢

>>> dept.objects.get( pk= 10)

得到top n的數(shù)據(jù)

>>> dept.objects.all()[: 5]

[ , , , , ]

使用get方法,返回的是一行

>>> dept.objects.get( dname= 'DBA')

使用filter的exact是精確匹配,和上面的方法是等價的。

>>> dept.objects.filter( dname__exact= 'DBA')

[]

忽略大小寫

>>> dept.objects.filter( dname__iexact= 'DBA')

[]

查詢內(nèi)容排除包含ACC的部門

>>> dept.objects.exclude( dname__contains= 'ACC')

[ , , , , , , ]

>>>

可以過濾和排除操作都使用

>>> dept.objects.filter( dname__contains= 'DB').exclude( dname= 'MBA')

[] 3.刪除這種方法是查到指定的數(shù)據(jù),然后直接刪除,還是有一些風(fēng)險點(diǎn)的。

>>> dept.objects.filter( dname__contains= 'DB').delete()

或者分批刪除

>>> dept.objects.all()

[ , , , , , , ]

>>> newdept=dept.objects.filter( dname__contains= 'DEV')

>>> newdept.delete()

全部刪除 ,先不操作

dept.objects.all().delete() 4.更新使用filter來過濾得到數(shù)據(jù),然后使用update來更新

>>> dept.objects.filter( dname__contains= 'TEST')

[]

>>> dept.objects.filter( dname__contains= 'TEST').update( dname= 'Test')

1L

>>>

>>> dept.objects.filter( dname__contains= 'Te')

[]

或者把初始化一個對象,更新這個對象

>>> newdept=dept.objects.get( dname= 'Test')

>>>

>>> newdept.dname

u'Test'

>>> dname= 'Test2'

>>> loc= 'Lanzhou'

>>> newdept.save()

5.迭代Queryset>>> newdept=dept.objects.all()

>>> for new in newdept:

... print(new.dname)

...

ACCOUNTING

RESEARCH

SALES

OPERATIONS

Test

OPS 6.鏈?zhǔn)讲樵儍蓚€filter來過濾

>>> dept.objects.filter( dname__contains= 'Test').filter( deptno= 42)

[]

先使用fileter過濾,然后使用exclude排除

>>> dept.objects.filter( dname__contains= 'Test').exclude( deptno= 4)

[] 7.top n的寫法得到前4行

>>> dept.objects.all()[: 4]

[ , , , ]

>>>

最后2行,有個技巧是用reverse()

>>> dept.objects.all().reverse()[: 2]

[ , ]

最后1行,下標(biāo)是從0開始

>>> dept.objects.all().reverse()[ 0]

>>> dept.objects.all().reverse()[ 1]

或者使用order_by反向排序

>>> dept.objects.all().order_by( '-deptno')[: 2]

[ , ]

有的同學(xué)可能疑惑order_by和reverse的性能差別。我們繼續(xù)往下看。

8.得到調(diào)用的SQL語句方法1:

>>> print str(dept.objects.all().order_by( '-deptno').distinct().query)

SELECT DISTINCT `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` ORDER BY `dept`.`deptno` DESC

>>>

>>> print str(dept.objects.all().reverse().distinct().query)

SELECT DISTINCT `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` ORDER BY `dept`.`deptno` DESC

可見兩者是等價的,所以我們就很容易理解reverse()和order_by的差別了,實現(xiàn)不同,但是結(jié)果相同。 方法2:使用query.__str__()來得到

>>> dept.objects.all().reverse().distinct().query. __str__()

u'SELECT DISTINCT `dept`.`deptno`, `dept`.`dname`, `dept`.`loc` FROM `dept` ORDER BY `dept`.`deptno` DESC'

方法3:在settings.py里面補(bǔ)充下面的內(nèi)容,然后在python shell模式下,可以看到調(diào)用的SQL

LOGGING = {

'version': 1,

'disable_existing_loggers': False,

'handlers': {

'console': {

'class': 'logging.StreamHandler',

} ,

} ,

'loggers': {

'django.db.backends': {

'handlers': [ 'console'] ,

'level': 'DEBUG' if DEBUG else 'INFO',

} ,

} ,

} 8.得到返回結(jié)果 values_list

可以使用values_list來實現(xiàn),比如返回dname和deptno列

>>> dept.objects.values_list( 'dname','deptno')

[( u'ACCOUNTING', 10L) , ( u'RESEARCH', 20L) , ( u'SALES', 30L) , ( u'OPERATIONS', 40L) , ( u'Test', 42L) , ( u'OPS', 43L)]

>>>

初始化一個對象,打印出結(jié)果

>>> newdept=dept.objects.values_list( 'dname','deptno')

>>> newdept

[( u'ACCOUNTING', 10L) , ( u'RESEARCH', 20L) , ( u'SALES', 30L) , ( u'OPERATIONS', 40L) , ( u'Test', 42L) , ( u'OPS', 43L)]

可以使用list方法

>>> list(newdept)

[( u'ACCOUNTING', 10L) , ( u'RESEARCH', 20L) , ( u'SALES', 30L) , ( u'OPERATIONS', 40L) , ( u'Test', 42L) , ( u'OPS', 43L)]

>>>

使用values_list的結(jié)果,格式和上面還是有一些差別的。

>>> dept.objects.values_list( 'dname',flat= True)

[ u'ACCOUNTING', u'RESEARCH', u'SALES', u'OPERATIONS', u'Test', u'OPS']

可以加入flat選項,只輸出指定的列

>>> print str(dept.objects.values_list( 'dname',flat= True).query)

SELECT `dept`.`dname` FROM `dept` ORDER BY `dept`.`deptno` ASC

9.得到返回結(jié)果 values

>>> dept.objects.values( 'dname')

[{ 'dname': u'ACCOUNTING'} , { 'dname': u'RESEARCH'} , { 'dname': u'SALES'} , { 'dname': u'OPERATIONS'} , { 'dname': u'Test'} , { 'dname': u'OPS'}]

>>>

>>> dept.objects.values_list( 'dname')

[( u'ACCOUNTING',) , ( u'RESEARCH',) , ( u'SALES',) , ( u'OPERATIONS',) , ( u'Test',) , ( u'OPS',)]

>>>

兩者返回的并不是真正的列表或字典,也是queryset 10.列的別名

可以使用extra來指定別名

>>> dept.objects.all().extra( select={ 'dname': 'Dname'})

[ , , , , , ]

>>>

如果不確定里面的參數(shù)代表的含義,可以得到解析的SQL來對比一下,就很清楚了。

>>> print str(dept.objects.all().extra( select={ 'dname': 'Dname'}).query)

SELECT (Dname) AS `dname` , `dept`.`deptno` , `dept`.dname , `dept`.`loc` FROM `dept` ORDER BY `dept`.`deptno` ASC

>>>

>>> print str(dept.objects.all().extra( select={ 'Dname': "dname"}).query)

SELECT (dname) AS `Dname` , `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` ORDER BY `dept`.`deptno` ASC

>>>

>>> print str(dept.objects.all().extra( select={ 'dname': 'Dname'}).defer( 'dname').query)

SELECT (Dname) AS `dname` , `dept`.`deptno` , `dept`.`loc` FROM `dept` ORDER BY `dept`.`deptno` ASC

11.聚合運(yùn)算

我們常見的是這種:

##計算個數(shù)

>>> print str(dept.objects.all().extra( select={ 'dname': 'Dname'}).defer( 'dname').count())

6

如果是做聚合運(yùn)算,就需要用到Count,Avg,Sum了。

##做聚合結(jié)算,需要導(dǎo)入Count,使用annotate

>>> from django.db.models import Count

>>> dept.objects.all().values( 'dname').annotate( count=Count( 'dname')).values( 'dname','count')

[{ 'dname': u'ACCOUNTING', 'count': 1} , { 'dname': u'RESEARCH', 'count': 1} , { 'dname': u'SALES', 'count': 1} , { 'dname': u'OPERATIONS', 'count': 1} , { 'dname': u'Test', 'count': 1} , { 'dname': u'OPS', 'count': 1}]

不過值得一提的是,里面的group by的部分是個硬骨頭,因為group by會默認(rèn)帶有主鍵列,對于一些特殊的場景,就會有些乏力了,比如這種SQL,在目前的實現(xiàn)中是不能直接支持的。

select deptno_id ,count(*) from emp group by deptno_id;

都會間接轉(zhuǎn)換為如下的方式,就有些尷尬了。

select deptno_id ,count(*) from emp group by empno;

如果手工強(qiáng)轉(zhuǎn),就會拋錯了。

>>> a=emp.objects.raw( 'select deptno_id,count(*) count from emp group by deptno_id')

>>> a[ 0]

( 0.000) select deptno_id ,count(*) count from emp group by deptno_id; args=()

Traceback (most recent call last):

File "", line 1, in

File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 1323, in __getitem__

return list(self)[k]

File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 1296, in __iter__

raise InvalidQuery( 'Raw query must include the primary key')

InvalidQuery: Raw query must include the primary key

12.Inner Join和聚合運(yùn)算

inner join,注意下面的deptno__dname的部分。

>>> emp.objects.values( 'deptno__dname').annotate( sum=Sum( 'deptno')).values( 'deptno','sum').query. __str__()

u'SELECT `emp`.`deptno_id`, SUM(`emp`.`deptno_id`) AS `sum` FROM `emp` INNER JOIN `dept` ON ( `emp`.`deptno_id` = `dept`.`deptno` ) GROUP BY `emp`.`empno` ORDER BY `emp`.`empno` ASC, `emp`.`ename` ASC'

12.select_related查詢

這種方式的一大好處就是會自動關(guān)聯(lián)查詢,調(diào)用一次會自動獲取相關(guān)的數(shù)據(jù)。

我們可以對比下它和通常方式的差別。

使用傳統(tǒng)的方式,如果需要關(guān)聯(lián)查詢,會在后臺反復(fù)調(diào)用關(guān)聯(lián)查詢。

>>> emp.objects.all()[: 10]

( 0.001) SELECT `emp`.`empno` , `emp`.`ename` , `emp`.`job` , `emp`.`mgr` , `emp`.`hiredate` , `emp`.`sal` , `emp`.`deptno_id` FROM `emp` ORDER BY `emp`.`empno` ASC , `emp`.`ename` ASC LIMIT 10; args=()

[ , , , , , , , , , ]

初始化對象,得到關(guān)聯(lián)數(shù)據(jù)的情況

>>> a=emp.objects.all()[: 10][ 0]

( 0.000) SELECT `emp`.`empno` , `emp`.`ename` , `emp`.`job` , `emp`.`mgr` , `emp`.`hiredate` , `emp`.`sal` , `emp`.`deptno_id` FROM `emp` ORDER BY `emp`.`empno` ASC , `emp`.`ename` ASC LIMIT 1; args=()

>>> a.ename

u'SMITH'

>>> a.deptno --可以看到又做了一次查詢

( 0.002) SELECT `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` WHERE `dept`.`deptno` = 20; args=( 20,)

而使用select_related就可以解決這個問題。

只查一次數(shù)據(jù)庫 select_related

>>> a=emp.objects.all().select_related( 'deptno')[: 4][ 0]

( 0.001) SELECT `emp`.`empno` , `emp`.`ename` , `emp`.`job` , `emp`.`mgr` , `emp`.`hiredate` , `emp`.`sal` , `emp`.`deptno_id` , `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `emp` INNER JOIN `dept` ON ( `emp`.`deptno_id` = `dept`.`deptno` ) ORDER BY `emp`.`empno` ASC , `emp`.`ename` ASC LIMIT 1; args=()

>>> a.ename

u'SMITH'

反復(fù)查看,都不會多次調(diào)用新的SQL

>>> a.deptno

>>> a.ename

u'SMITH'

>>> a.mgr

7902L

>>>

>>> a.deptno.dname --級聯(lián)查詢

u'RESEARCH'13.prefetched_related查詢對比prefetched related的好處

>>> a=emp.objects.all().filter( empno__in=( 7369,7521,7566))

>>> a

( 0.001) SELECT `emp`.`empno` , `emp`.`ename` , `emp`.`job` , `emp`.`mgr` , `emp`.`hiredate` , `emp`.`sal` , `emp`.`deptno_id` FROM `emp` WHERE `emp`.`empno` IN ( 7369, 7521, 7566) ORDER BY `emp`.`empno` ASC , `emp`.`ename` ASC LIMIT 21; args=( 7369, 7521, 7566)

[ , , ]

迭代

>>> for t in a:

... print t.ename ,t.deptno

...

SMITH 20 RESEARCH

( 0.000) SELECT `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` WHERE `dept`.`deptno` = 30; args=( 30,)

WARD 30 SALES

( 0.000) SELECT `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` WHERE `dept`.`deptno` = 20; args=( 20,)

JONES 20 RESEARCH

初始化對象,使用in的方式來過濾數(shù)據(jù)

>>> a=emp.objects.all().filter( empno__in=( 7369,7521,7566)).prefetch_related( 'deptno')

>>> a

( 0.001) SELECT `emp`.`empno` , `emp`.`ename` , `emp`.`job` , `emp`.`mgr` , `emp`.`hiredate` , `emp`.`sal` , `emp`.`deptno_id` FROM `emp` WHERE `emp`.`empno` IN ( 7369, 7521, 7566) ORDER BY `emp`.`empno` ASC , `emp`.`ename` ASC LIMIT 21; args=( 7369, 7521, 7566)

( 0.000) SELECT `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` WHERE `dept`.`deptno` IN ( 20, 30) ORDER BY `dept`.`deptno` ASC; args=( 20, 30)

[ , , ]

可以看到自始至終,都只有一次交互

>>> for t in a:

... print t.ename ,t.deptno

...

( 0.000) SELECT `emp`.`empno` , `emp`.`ename` , `emp`.`job` , `emp`.`mgr` , `emp`.`hiredate` , `emp`.`sal` , `emp`.`deptno_id` FROM `emp` WHERE `emp`.`empno` IN ( 7369, 7521, 7566) ORDER BY `emp`.`empno` ASC , `emp`.`ename` ASC; args=( 7369, 7521, 7566)

( 0.000) SELECT `dept`.`deptno` , `dept`.`dname` , `dept`.`loc` FROM `dept` WHERE `dept`.`deptno` IN ( 20, 30) ORDER BY `dept`.`deptno` ASC; args=( 20, 30)

SMITH 20 RESEARCH

WARD 30 SALES

JONES 20 RESEARCH

感謝各位的閱讀!關(guān)于“Django ORM的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!


本文題目:DjangoORM的示例分析
分享鏈接:http://weahome.cn/article/jspsig.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部