Django ORM用到三個(gè)類:Manager、QuerySet、Model。Manager定義表級(jí)方法(表級(jí)方法就是影響一條或多條記錄的方法),我們可以以models.Manager為父類,定義自己的manager,增加表級(jí)方法;QuerySet:Manager類的一些方法會(huì)返回QuerySet實(shí)例,QuerySet是一個(gè)可遍歷結(jié)構(gòu),包含一個(gè)或多個(gè)元素,每個(gè)元素都是一個(gè)Model 實(shí)例,它里面的方法也是表級(jí)方法,前面說了,Django給我們提供了增加表級(jí)方法的途徑,那就是自定義manager類,而不是自定義QuerySet類,一般的我們沒有自定義QuerySet類的必要;django.db.models模塊中的Model類,我們定義表的model時(shí),就是繼承它,它的功能很強(qiáng)大,通過自定義model的instance可以獲取外鍵實(shí)體等,它的方法都是記錄級(jí)方法(都是實(shí)例方法,貌似無類方法),不要在里面定義類方法,比如計(jì)算記錄的總數(shù),查看所有記錄,這些應(yīng)該放在自定義的manager類中。以Django1.6為基礎(chǔ)。
每個(gè)Model都有一個(gè)默認(rèn)的manager實(shí)例,名為objects,QuerySet有兩種來源:通過manager的方法得到、通過QuerySet的方法得到。mananger的方法和QuerySet的方法大部分同名,同意思,如filter(),update()等,但也有些不同,如manager有create()、get_or_create(),而QuerySet有delete()等,看源碼就可以很容易的清楚Manager類與Queryset類的關(guān)系,Manager類的絕大部分方法是基于Queryset的。一個(gè)QuerySet包含一個(gè)或多個(gè)model instance。QuerySet類似于Python中的list,list的一些方法QuerySet也有,比如切片,遍歷。
>>> from userex.models import UserEx
>>> type(UserEx.objects)
<class ‘django.db.models.manager.Manager’>
>>> a = UserEx.objects.all()
>>> type(a)
<class ‘django.db.models.query.QuerySet’>
QuerySet是延遲獲取的,只有當(dāng)用到這個(gè)QuerySet時(shí),才會(huì)查詢數(shù)據(jù)庫(kù)求值。另外,查詢到的QuerySet又是緩存的,當(dāng)再次使用同一個(gè)QuerySet時(shí),并不會(huì)再查詢數(shù)據(jù)庫(kù),而是直接從緩存獲取(不過,有一些特殊情況)。一般而言,當(dāng)對(duì)一個(gè)沒有求值的QuerySet進(jìn)行的運(yùn)算,返回的是QuerySet、ValuesQuerySet、ValuesListQuerySet、Model實(shí)例時(shí),一般不會(huì)立即查詢數(shù)據(jù)庫(kù);反之,當(dāng)返回的不是這些類型時(shí),會(huì)查詢數(shù)據(jù)庫(kù)。下面介紹幾種(并非全部)對(duì)QuerySet求值的場(chǎng)景。
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __unicode__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
def __unicode__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __unicode__(self):
return self.headline
我們以上面的models為例。
a = Entry.objects.all()
for e in a:
PRint (e.headline)
當(dāng)遍歷一開始時(shí),先從數(shù)據(jù)庫(kù)執(zhí)行查詢select * from Entry得到a,然后再遍歷a。注意:這里只是查詢Entry表,返回的a的每條記錄只包含Entry表的字段值,不管Entry的model中是否有onetoone、onetomany、manytomany字段,都不會(huì)關(guān)聯(lián)查詢。這遵循的是數(shù)據(jù)庫(kù)最少讀寫原則。我們修改一下代碼,如下,遍歷一開始也是先執(zhí)行查詢得到a,但當(dāng)執(zhí)行print (e.blog.name)時(shí),還需要再次查詢數(shù)據(jù)庫(kù)獲取blog實(shí)體。
from django.db import connection
l = connection.queries #l是一個(gè)列表,記錄SQL語句
a = Entry.objects.all()
for e in a:
print (e.blog.name)
len(l)
遍歷時(shí),每次都要查詢數(shù)據(jù)庫(kù),l長(zhǎng)度每次增1,Django提供了方法可以在查詢時(shí)返回關(guān)聯(lián)表實(shí)體,如果是onetoone或onetomany,那用select_related,不過對(duì)于onetomany,只能在主表(定義onetomany關(guān)系的那個(gè)表)的manager中使用select_related方法,即通過select_related獲取的關(guān)聯(lián)對(duì)象是model instance,而不能是QuerySet,如下,e.blog就是model instance。對(duì)于onetomany的反向和manytomany,要用prefetch_related,它返回的是多條關(guān)聯(lián)記錄,是QuerySet。
a = Entry.objects.select_related('blog')
for e in a:
print (e.blog.name)
len(l)
可以看到從開始到結(jié)束,l的長(zhǎng)度只增加1。另外,通過查詢connection.queries[-1]可以看到Sql語句用了join。
切片不會(huì)立即執(zhí)行,除非顯示指定了步長(zhǎng),如a= Entry.objects.all()[0:10:2],步長(zhǎng)為2。
序列化QuerySet很少用
和str()功能相似,將對(duì)象轉(zhuǎn)為字符串,很少用。
計(jì)算QuerySet元素的數(shù)量,并不推薦使用len(),除非QuerySet是求過值的(即evaluated),否則,用QuerySet.count()獲取元素?cái)?shù)量,這個(gè)效率要高。
將QuerySet轉(zhuǎn)為list
if Entry.objects.filter(headline="Test"):
print("There is at least one Entry with the headline Test")
同樣不建議這種方法判斷是否為空,而應(yīng)該使用QuerySet.exists(),查詢效率高
數(shù)據(jù)庫(kù)的常用操作就四種:增、刪、改、查,QuerySet的方法涉及刪、改、查。后面還會(huì)講model對(duì)象的方法,model方法主要是增、刪、改、還有調(diào)用model實(shí)例的字段。
原型:delete()
返回:None
相當(dāng)于delete-from-where, delete-from-join-where。先filter,然后對(duì)得到的QuerySet執(zhí)行delete()方法就行了,它會(huì)同時(shí)刪除關(guān)聯(lián)它的那些記錄,比如我刪除記錄表1中的A記錄,表2中的B記錄中有A的外鍵,那同時(shí)也會(huì)刪除B記錄,那ManyToMany關(guān)系呢?對(duì)于ManyToMany,刪除其中一方的記錄時(shí),會(huì)同時(shí)刪除中間表的記錄,即刪除雙方的關(guān)聯(lián)關(guān)系。由于有些數(shù)據(jù)庫(kù),如Sqlite不支持delete與limit連用,所以在這些數(shù)據(jù)庫(kù)對(duì)QuerySet的切片執(zhí)行delete()會(huì)出錯(cuò)。如
>>> a = UserEx.objects.filter(is_active=False)
>>> b = a[:3]
>>> b.delete() #執(zhí)行時(shí)會(huì)報(bào)錯(cuò)
解決:UserEx.objects.filter(pk__in=b).delete()
in后面可以是一個(gè)QuerySet,見 https://docs.djangoproject.com/en/1.6/ref/models/querysets/#in
批量修改,返回修改的記錄數(shù)。不過update()中的鍵值對(duì)的鍵只能是主表中的字段,不能是關(guān)聯(lián)表字段,如下
Entry.objects.update(blog__name='foo') #錯(cuò)誤,無法修改關(guān)聯(lián)表字段,只能修改Entry表的字段
Entry.objects.filter(blog__name='foo').update(comments_on=False) #正確
最好的方法是先filter,查詢出QuerySet,然后再執(zhí)行QuerySet.update()。
由于有些數(shù)據(jù)庫(kù),不支持update與limit連用,所以在這些數(shù)據(jù)庫(kù)對(duì)QuerySet的切片執(zhí)行update()會(huì)出錯(cuò)。
相當(dāng)于select-from-where,select-from-join-where,很多網(wǎng)站讀數(shù)據(jù)庫(kù)操作最多。可以看到,filter()的參數(shù)是變個(gè)數(shù)的鍵值對(duì),而不會(huì)出現(xiàn)>,<,!=等符號(hào),這些符號(hào)分別用__gt,__lt,~Q或exclude(),不過對(duì)于!=,建議使用Q查詢,更不容易出錯(cuò)。可以使用雙下劃線對(duì)OneToOne、OneToMany、ManyToMany進(jìn)行關(guān)聯(lián)查詢和反向關(guān)聯(lián)查詢,而且方法都是一樣的,如:
>>> Entry.objects.filter(blog__name='Beatles Blog') #限定外鍵表的字段
#下面是反向連接,不過要注意,這里不是entry_set,entry_set是Blog instance的一個(gè)屬性,代表某個(gè)Blog object
#的關(guān)聯(lián)的所有entry,而QuerySet的方法中反向連接是直接用model的小寫,不要把兩者搞混。It works backwards,
#too. To refer to a “reverse” relationship, just use the lowercase name of the model.
>>> Blog.objects.filter(entry__headline__contains='Lennon')
>>> Blog.objects.filter(entry__authors__name='Lennon') #ManyToMany關(guān)系,反向連接
>>> myblog = Blog.objects.get(id=1)
>>> Entry.objects.filter(blog=myblog) #正向連接。與下面一句等價(jià),既可以用實(shí)體,也可以用
#實(shí)體的主鍵,其實(shí)即使用實(shí)體,也是只用實(shí)體的主鍵而已。這兩種方式對(duì)OneToOne、
#OneToMany、ManyToMany的正向、反向連接都適用。
>>> Entry.objects.filter(blog=1) #我個(gè)人不建議這樣用,對(duì)于create(),不支持這種用法
>>> myentry = Entry.objects.get(id=1)
>>> Blog.objects.filter(entry=myentry) #ManyToMany反向連接。與下面兩種方法等價(jià)
>>> Blog.objects.filter(entry=1)
>>> Blog.objects.filter(entry_id=1) #適用于OneToOne和OneToMany的正向連接
OneToOne的關(guān)系也是這樣關(guān)聯(lián)查詢,可以看到,Django對(duì)OneToOne、OneToMany、ManyToMany關(guān)聯(lián)查詢及其反向關(guān)聯(lián)查詢提供了相同的方式,真是牛逼啊。對(duì)于OneToOne、OneToMany的主表,也可以使用下面的方式
Entry.objects.filter(blog_id=1),因?yàn)閎log_id是數(shù)據(jù)庫(kù)表Entry的一個(gè)字段, 這條語句與Entry.objects.filter(blog=blog1)生成的SQL是完全相同的。
與filter類似的還有exclude(**kwargs)方法,這個(gè)方法是剔除,相當(dāng)于select-from-where not。可以使用雙下劃線對(duì)OneToOne、OneToMany、ManyToMany進(jìn)行關(guān)聯(lián)查詢和反向關(guān)聯(lián)查詢,方法與filter()中的使用方法相同。
>>> Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
轉(zhuǎn)為SQL為
SELECT *
FROM Entry
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
在SQL中,很多關(guān)鍵詞在刪、改、查時(shí)都是可以用的,如order by、 like、in、join、union、and、or、not等等,我們以查詢?yōu)槔f一下django如何映射SQL的這些關(guān)鍵字的(查、刪、改中這些關(guān)鍵字的使用方法基本相同)。
前面提到的filter/exclude中的查詢參數(shù)值都是常量,如果我們想比較model的兩個(gè)字段怎么辦呢?Django也提供了方法,F(xiàn)類,F(xiàn)類實(shí)例化時(shí),參數(shù)也可以用雙下劃線,也可以邏輯運(yùn)算,如下
>>> from django.db.models import F
>>> Entry.objects.filter(n_comments__gt=F('n_pingbacks'))
>>> from datetime import timedelta
>>> Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3))
>>> Entry.objects.filter(authors__name=F('blog__name'))
如果有or等邏輯關(guān)系呢,那就用Q類,filter中的條件可以是Q對(duì)象與非Q查詢混和使用,但不建議這樣做,因?yàn)榛旌筒樵儠r(shí)Q對(duì)象要放前面,這樣就有難免忘記順序而出錯(cuò),所以如果使用Q對(duì)象,那就全部用Q對(duì)象。Q對(duì)象也很簡(jiǎn)單,就是把原來filter中的各個(gè)條件分別放在一個(gè)Q()即可,不過我們還可以使用或與非,分別對(duì)應(yīng)符號(hào)為”|”和”&”和”~”,而且這些邏輯操作返回的還是一個(gè)Q對(duì)象,另外,逗號(hào)是各組條件的基本連接符,也是與的關(guān)系,其實(shí)可以用&代替(在python manage.py shell測(cè)試過,&代替逗號(hào),執(zhí)行的SQL是一樣的),不過那樣的話可讀性會(huì)很差,這與我們直接寫SQL時(shí),各組條件and時(shí)用換行一樣,邏輯清晰。
from django.db.models import Q
>>> Poll.objects.get( Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
question__startswith='Who') #正確,但不要這樣混用
>>> Poll.objects.get( Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
Q(question__startswith='Who')) #推薦,全部是Q對(duì)象
>>> Poll.objects.get( (Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))&
Q(question__startswith='Who')) #與上面語句同意,&代替”,”,可讀性差
Q類中時(shí)應(yīng)該可以用F類,待測(cè)試。
函數(shù)原型annotate(*args, **kwargs)
返回QuerySet
往每個(gè)QuerySet的model instance中加入一個(gè)或多個(gè)字段,字段值只能是聚合函數(shù),因?yàn)槭褂胊nnotate時(shí),會(huì)用group by,所以只能用聚合函數(shù)。聚合函數(shù)可以像filter那樣關(guān)聯(lián)表,即在聚合函數(shù)中,Django對(duì)OneToOne、OneToMany、ManyToMany關(guān)聯(lián)查詢及其反向關(guān)聯(lián)提供了相同的方式,見下面例子。
>>> from django.contrib.auth.models import User
>>> from django.db.models import Count
#計(jì)算每個(gè)用戶的userjob數(shù)量,字段命名為ut_num,返回的QuerySet中的每個(gè)object都有
#這個(gè)字段。在UserJob中定義User為外鍵,在Job中定義與User是ManyToMany
>>> a = User.objects.filter(is_active=True, userjob__is_active=True). annotate(n=Count(‘userjob’)) #一對(duì)多反向連接
>>> b = User.objects.filter(is_active=True, job__is_active=True).annotate(n=Count(‘job__name’)) #多對(duì)多反向連接,User與Job是多對(duì)多
>>> len(a) #這里才會(huì)對(duì)a求值
>>> len(b) #這里才會(huì)對(duì)b求值
a對(duì)應(yīng)的SQL語句為(SQL中沒有為表起別名,u、ut是我加的):
select auth.user.*,Count(ut.id) as ut_num
from auth_user as u
left outer join job_userjob as ut on u.id = ut.user_id
where u.is_active=True and ut.is_active=True
group by u.*
b對(duì)應(yīng)的SQL語句為(SQL中沒有為表起別名,u、t、r是我加的):
select u.*,Count(t.name) as n
from auth_user as u
left outer join job_job_users as r on u.id=r.user_id
left outer join job_job as t on r.job_id=t.id
where t.is_active=True and u.is_active=True
group by u.*
函數(shù)原型 order_by(*fields)
返回QuerySet
正向的反向關(guān)聯(lián)表跟filter的方式一樣。如果直接用字段名,那就是升序asc排列;如果字段名前加-,就是降序desc
原型 distinct()
一般與values()、values_list()連用,這時(shí)它返回ValuesQuerySet、ValuesListQuerySet
這個(gè)類跟列表很相似,它的每個(gè)元素是一個(gè)字典。它沒有參數(shù)(其實(shí)是有參數(shù)的,不過,參數(shù)只在PostgreSQL上起作用)。使用方法為
>>> a=Author.objects.values_list(name).distinct()
>>> b=Author.objects.values_list(name,email).distinct()
對(duì)應(yīng)的SQL分別為
select distinct name
from Author
和
select distinct name,email
from Author
函數(shù)原型values(*field), values_list(*field)
返回ValuesQuerySet, ValuesListQuerySet
Author.objects.filter(**kwargs)對(duì)應(yīng)的SQL只返回主表(即Author表)的所有字段值,即使在查詢時(shí)關(guān)聯(lián)了其它表,關(guān)聯(lián)表的字段也不會(huì)返回,只有當(dāng)我們通過Author instance用關(guān)聯(lián)表時(shí),Django才會(huì)再次查詢數(shù)據(jù)庫(kù)獲取值。當(dāng)我們不用Author instance的方法,且只想返回幾個(gè)字段時(shí),就要用values(),它返回的是一個(gè)ValuesQuerySet對(duì)象,它類似于一個(gè)列表,不過,它的每個(gè)元素是字典。而values_list()跟values()相似,它返回的是一個(gè)ValuesListQuerySet,也類型于一個(gè)列表,不過它的元素不是字典,而是元組。一般的,當(dāng)我們不需要model instance的方法且返回多個(gè)字段時(shí),用values(*field),而返回單個(gè)字段時(shí)用values_list(‘field’,flat=True),這里flat=True是要求每個(gè)元素不是元組,而是單個(gè)值,見下面例子。而且我們可以返回關(guān)聯(lián)表的字段,用法跟filter中關(guān)聯(lián)表的方式完全相同。
>>> a = User.objects.values(‘id’,’username’,’userex__age’)
>>> type(a)
<class ‘django.db.models.query.ValuesQuerySet’>
>>> a
[{‘id’:0,’username’:u’test0’,’ userex__age’: 20},{‘id’:1,’username’:u’test1’,’userex__age’: 25},
{‘id’:2,’username’:u’test2’, ’ userex__age’: 28}]
>>> b= User.objects.values_list(’username’,flat=True)
>>> b
[u’test0’, u’test1’ ,u’test2’]
原型select_related(*filed)
返回QuerySet
它可以指定返回哪些關(guān)聯(lián)表model instance,這里的field跟filter()中的鍵一樣,可以用雙下劃線,但也有不同,You can refer to any ForeignKey or OneToOneField relation in the list of fields passed to select_related(),QuerySet中的元素中的OneToOne關(guān)聯(lián)及外鍵對(duì)應(yīng)的是都是關(guān)聯(lián)表的一條記錄,如my_entry=Entry.objects.get(id=1),my_entry.blog就是關(guān)聯(lián)表的一條記錄的對(duì)象。select_related()不能用于OneToMany的反向連接,和ManyToMany,這些都是model的一條記錄對(duì)應(yīng)關(guān)聯(lián)表中的多條記錄。前面提到了對(duì)于a = Author.objects.filter(**kwargs)這類語句,對(duì)應(yīng)的SQL只返回主表,即Author的所有字段,并不會(huì)返回關(guān)聯(lián)表字段值,只有當(dāng)我們使用關(guān)聯(lián)表時(shí)才會(huì)再查數(shù)據(jù)庫(kù)返回,但有些時(shí)候這樣做并不好。看下面兩段代碼,這兩段代碼在1.1中提到過。在代碼1中,在遍歷a前,先執(zhí)行a對(duì)應(yīng)的SQL,拿到數(shù)據(jù)后,然后再遍歷a,而遍歷過程中,每次都還要查詢數(shù)據(jù)庫(kù)獲取關(guān)聯(lián)表。代碼2中,當(dāng)遍歷開始前,先拿到Entry的QuerySet,并且也拿到這個(gè)QuerySet的每個(gè)object中的blog對(duì)象,這樣遍歷過程中,就不用再查詢數(shù)據(jù)庫(kù)了,這樣就減少了數(shù)據(jù)庫(kù)讀次數(shù)。
代碼1
a = Entry.objects.all()
for e in a:
print (e.blog.name)
代碼2
a = Entry.objects.select_related('blog')
for e in a:
print (e.blog.name)
函數(shù)原型prefetch_related(*field)
返回的是QuerySet
這里的field跟filter()中的鍵一樣,可以用雙下劃線。用于OneToMany的反向連接,及ManyToMany。其實(shí),prefetch_related()也能做select_related()的事情,但由于策略不同,可能相比select_related()要低效一些,所以建議還是各管各擅長(zhǎng)的。select_related是用select ……join來返回關(guān)聯(lián)的表字段,而prefetch_related是用多條SQL語句的形式查詢,一般,后一條語句用IN來調(diào)用上一句話返回的結(jié)果。
class Restaurant(models.Model):
pizzas = models.ManyToMany(Pizza, related_name='restaurants')
best_pizza = models.ForeignKey(Pizza, related_name='championed_by')
>>> Restaurant.objects.prefetch_related('pizzas__toppings')
>>> Restaurant.objects.select_related('best_pizza').prefetch_related('best_pizza__toppings')
先用select_related查到best_pizza對(duì)象,再用prefetch_related 從best_pizza查出toppings
函數(shù)原型:extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
基本上,查詢時(shí)用django提供的方法就夠用了,不過有時(shí)where子句中包含復(fù)雜的邏輯,這種情況下django提供的方法可能不容易做到,還好,django有extra(), extra()中直接寫一些SQL語句。不過,不同的數(shù)據(jù)庫(kù)用的SQL有些差異,所以盡可能不要用extra()。需要時(shí)再看使用方法吧。
參數(shù)為聚合函數(shù),最好用**kwargs的形式,每個(gè)參數(shù)起一個(gè)名字。
該函數(shù)與annotate()有何區(qū)別呢?annotate相當(dāng)于aggregate()和group by的結(jié)合,對(duì)每個(gè)group執(zhí)行aggregate()函數(shù)。而單獨(dú)的aggregate()并沒有g(shù)roup by。
>>> from django.db.models import Count
>>> q = Blog.objects.aggregate(Count('entry')) #這是用*args的形式,最好不要這樣用
>>> q = Blog.objects.aggregate(number_of_entries=Count('entry')) #這是用**kwargs的形式
{'number_of_entries': 16}
至此,我們總結(jié)了QuerySet方法返回的數(shù)據(jù)形式,主要有五種。第一種:返回QuerySet,每個(gè)object只包含主表字段;第二種:返回QuerySet,每個(gè)object除了包含主表所有字段,還包含某些關(guān)聯(lián)表的object,這種情況要用select_related()和prefetch_related(),可以是任意深度(即任意多個(gè)雙下劃線)的關(guān)聯(lián),通常一層關(guān)聯(lián)和二層關(guān)聯(lián)用的比較多;第三種:返回ValuesQuerySet, ValuesListQuerySet,它們的每個(gè)元素包含若干主表和關(guān)聯(lián)表的字段,不包含任何實(shí)體和關(guān)聯(lián)實(shí)例,這種情況要用values()和values_list();第四種:返回model instance;第五種:單個(gè)值,如aggregate()方法。
如果只是想知道一個(gè)QuerySet是否為空,而不想獲取QuerySet中的每個(gè)元素,那就用exists(),它要比len()、count()、和直接進(jìn)行if判斷效率高。如果只想知道一個(gè)QuerySet有多大,而不想獲取QuerySet中的每個(gè)元素,那就用count();如果已經(jīng)從數(shù)據(jù)庫(kù)獲取到了QuerySet,那就用len()
字段名加雙下劃線,除了它,還有icontains,即Case-insensitive contains,這個(gè)是大小寫不敏感的,這需要相應(yīng)數(shù)據(jù)庫(kù)的支持。有些數(shù)據(jù)庫(kù)需要設(shè)置
才能支持大小寫敏感。
字段名加雙下劃線
iterable是可迭代對(duì)象
字段名加雙下劃線
字段名加雙下劃線,range后面值是列表
Entry.objects.filter(pub_date__isnull=True)對(duì)應(yīng)的SQL為SELECT ... WHERE pub_date IS NULL;
QuerySet的索引只能是非負(fù)整數(shù),不支持負(fù)整數(shù),所以QuerySet[-1]錯(cuò)誤
a=Entry.objects.all()[5:10]
b=len(a)
執(zhí)行Entry.objects.all()[5:8],對(duì)于不同的數(shù)據(jù)庫(kù),SQL語句不同,Sqlite 的SQL語句為select * from tablename limit 3 offset 5; MySQL的SQL語句為select * from tablename limit 5,3
參考資料:
1、https://docs.djangoproject.com/en/1.6/ref/models/querysets/
2、https://docs.djangoproject.com/en/1.6/topics/db/queries/
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注