0、數據庫配置
django默認支持sqlite,mysql, oracle,postgresql數據庫。Django連接數據庫默認編碼使用UTF8,使用中文不需要特別設置。
sqlite
django默認使用sqlite的數據庫,默認自帶sqlite的數據庫驅
引擎名稱:django.db.backends.sqlite3
mysql
引擎名稱:django.db.backends.mysql
mysql引擎配置:
'defaults': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'127.0.0.1',
'USER':'root',
'PASSWORD':'',
}
mysql引擎底層驅動的py3支持問題:
mysql驅動程序 MySQLdb(mysql python),Django默認使用改驅動,但改驅動在python3下存在兼容性問題。因此使用PyMySQL。 PyMySQL(純python的mysql驅動程序) mysql驅動python3解決方法 找到項目名文件下的__init__,在里面寫入: import pymysql pymysql.install_as_MySQLdb()
一、Model類定義
1、Model類創建
下面這個模型類將作為本篇博客的基礎模型,所有的實例都基於此。
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30, verbose_name="名稱") website = models.URLField() # book_set 反向關聯一對多字段的Book def __unicode__(self): return self.name class Author(models.Model): name = models.CharField(max_length=30) # authordetail 反向關聯一對一字段AuthorDetail表 # book_set 反向關聯一對多字段的Book def __unicode__(self): return self.name class AuthorDetail(models.Model): sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),)) author = models.OneToOneField(Author) # author_id隱藏字段,正向關聯一對一字段的Author對象的id class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher,null=True) # publisher_id隱藏字段,正向關聯一對多字段的Publisher對象的id price=models.DecimalField(max_digits=5,decimal_places=2,default=10) def __unicode__(self): return self.title

#coding:utf-8 from __future__ import unicode_literals from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30, verbose_name="名稱") website = models.URLField() def __unicode__(self): return self.name class Author(models.Model): name = models.CharField(max_length=30) def __unicode__(self): return self.name class AuthorDetail(models.Model): sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),)) author = models.OneToOneField(Author) class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author,through='Book2Author') publisher = models.ForeignKey(Publisher) price=models.DecimalField(max_digits=5,decimal_places=2,default=10) def __unicode__(self): return self.title class Book2Author(models.Model): book = models.ForeignKey(Book) author = models.ForeignKey(Author) groupname = models.CharField(max_length=100) #默認多對多關系Django自動為我們創建了一張中間表,僅提供3個字段,兩個關聯表的外鍵字段和一個id字段。 #這種使用自定義中間表的方式,使得我們可以自定義的為中間表添加額外的字段。當我們需要為多對多關系提供額外字段時,用此方式。
2、同步數據庫
模型表創建和更新的時候是要使用數據庫遷移命令,使模型類的改變同步到數據庫。
makemigrations #創建變更記錄
migrate #同步到數據庫
3、Model類(表)關系圖:

名詞說明:
正向查詢,從定義關系字段的類中去查詢關系對象的值或值的集合。舉個栗子:從AuthorDetail類中查詢關聯字段author對象的值。
反向查詢,從本類中查詢被關聯對象中的值或值的集合。舉個栗子:從Author對象中查詢被關聯字段AuthorDetail對象的值。
4、字段類型:

1、models.AutoField 自增列 = int(11) 如果沒有的話,默認會生成一個名稱為 id 的列,如果要顯示的自定義一個自增列,必須將給列設置為主鍵 primary_key=True。 2、models.CharField 字符串字段 必須 max_length 參數 3、models.BooleanField 布爾類型=tinyint(1) 不能為空,Blank=True 4、models.ComaSeparatedIntegerField 用逗號分割的數字=varchar 繼承CharField,所以必須 max_lenght 參數 5、models.DateField 日期類型 date 對於參數,auto_now = True 則每次更新都會更新這個時間;auto_now_add 則只是第一次創建添加,之后的更新不再改變。 6、models.DateTimeField 日期類型 datetime 同DateField的參數 7、models.Decimal 十進制小數類型 = decimal 必須指定整數位max_digits和小數位decimal_places 8、models.EmailField 字符串類型(正則表達式郵箱) =varchar 對字符串進行正則表達式 9、models.FloatField 浮點類型 = double 10、models.IntegerField 整形 11、models.BigIntegerField 長整形 integer_field_ranges = { 'SmallIntegerField': (-32768, 32767), 'IntegerField': (-2147483648, 2147483647), 'BigIntegerField': (-9223372036854775808, 9223372036854775807), 'PositiveSmallIntegerField': (0, 32767), 'PositiveIntegerField': (0, 2147483647), } 12、models.IPAddressField 字符串類型(ip4正則表達式) 13、models.GenericIPAddressField 字符串類型(ip4和ip6是可選的) 參數protocol可以是:both、ipv4、ipv6 驗證時,會根據設置報錯 14、models.NullBooleanField 允許為空的布爾類型 15、models.PositiveIntegerFiel 正Integer 16、models.PositiveSmallIntegerField 正smallInteger 17、models.SlugField 減號、下划線、字母、數字 18、models.SmallIntegerField 數字 數據庫中的字段有:tinyint、smallint、int、bigint 19、models.TextField 字符串=longtext 20、models.TimeField 時間 HH:MM[:ss[.uuuuuu]] 21、models.URLField 字符串,地址正則表達式 22、models.BinaryField 二進制 23、models.ImageField 圖片 24、models.FilePathField 文件
5、字段選項:

1、null=True 數據庫中字段是否可以為空 2、blank=True django的 Admin 中添加數據時是否可允許空值 3、primary_key = False 主鍵,對AutoField設置主鍵后,就會代替原來的自增 id 列 4、auto_now 和 auto_now_add auto_now 自動創建---無論添加或修改,都是當前操作的時間 auto_now_add 自動創建---永遠是創建時的時間 5、choices 配置可選項 GENDER_CHOICE = ( (u'M', u'Male'), (u'F', u'Female'), ) gender = models.CharField(max_length=2,choices = GENDER_CHOICE) 6、max_length 最大長度 7、default 默認值 8、verbose_name Admin中字段的顯示名稱 9、name|db_column 數據庫中的字段名稱 10、unique=True 不允許重復 11、db_index = True 數據庫索引 12、editable=True 在Admin里是否可編輯 13、error_messages=None 錯誤提示 14、auto_created=False 自動創建 15、help_text 在Admin中提示幫助信息 16、validators=[] 自定義數據格式驗證 17、upload-to 上傳文件路徑
6、Model類的Meta(元數據)選項:

abstract=False True就表示模型是抽象基類 db_table = 'music_album' 自定義數庫的表名稱前綴 get_latest_by = "datefield_name" 根據時間字段datefield_name排序,latest()和earliest()方法中使用的默認字段。 db_tablespace 當前模型所使用的數據庫表空間的名字。默認值是項目設置中的DEFAULT_TABLESPACE。如果后端並不支持表空間,這個選項可以忽略。 ordering = ['-fieldname'] 對象默認的順序,字段前面帶有'-'符號表示逆序,否則正序。排序會增加查詢額外開銷。 proxy = True 它作為另一個模型的子類,將會作為一個代理模型。 unique_together 設置聯合唯一。ManyToManyField不能包含在unique_together中。 index_together 設置聯合索引。 index_together = [ ["pub_date", "deadline"], ] 方便起見,處理單一字段的集合時index_together = ["pub_date", "deadline"] verbose_name 在Admin里,個易於理解的表名稱,為單數:verbose_name = "pizza" verbose_name_plural 在Admin里顯示的表名稱,為復數:verbose_name_plural = "stories",一般同verbose_name一同設置。
二、對象CURD操作
2.1 基礎對象CURD(無關聯字段)
1、增
方法一: author= Author(name="魯迅") author.save() 方法二: 創建對象並同時保存對象的快捷方法,存在關系字段時無法用此方法創建。 create(**kwargs) Author.objects.create(name=u"魯迅") 方法三: 批量創建 bulk_create(objs, batch_size=None) ret=Blog.objects.bulk_create([ Author(name="徐志摩"), Author(name="李白")]) 方法四: 存在就獲取,不存在就創建 get_or_create(defaults=None,**kwargs), defaults必須為一個字典,在創建時生效的默認值;**kwargs為查詢條件。 創建對象時,使用**kwargs和defaults共同作用,取交集,defaults優先。 updated_values={"name":u"美猴王"} a、存在就獲取,查詢到結果多余一個出錯MultipleObjectsReturned ret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values) ret:(<Author: 徐志摩>, False) b、不存在就創建 ret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values) ret:(<Author: 美猴王>, True) 方法五: 存在就更新,不存在就創建 update_or_create(defaults=None, **kwargs) a、存在就更新 updated_values={"name":u"猴王"} ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子") ret:(<Author: 猴王>, False) 根據給出的查詢條件name=u"猴子"查找對象,查詢到結果就使用defaults字典去更新對象。 b、不存在就創建 ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子1") ret:(<Author: 猴王>, True) defaults必須為一個字典,在創建時生效的默認值;**kwargs為查詢條件。 創建對象時,使用**kwargs和defaults共同作用,取交集,defaults優先。
2、刪
使用delete會查找出相關表中的有關聯的數據行一並刪除 方法一: Author.objects.filter(name="徐志摩").delete() (1, {u'otest.Book_authors': 0, u'otest.AuthorDetail': 0, u'otest.Author': 1}) 方法二: a9=Author.objects.get(name="魯迅") a9.delete()
3、改
方法一: update(**kwargs)返回更新的行數,批量修改 ret=Author.objects.filter(name='秋雨').update(name="陶淵明") 方法二: 單條修改 a7=Author.objects.get(name="清風") a7.name=u"宋清風" a7.save()
4、查
a、查詢結果非QuertSet
get(**kwargs) 在使用 get() 時,如果符合篩選條件的對象超過一個,就會拋出 MultipleObjectsReturned 異常。 在使用 get() 時,如果沒有找到符合篩選條件的對象,就會拋出 DoesNotExist 異常。 from django.core.exceptions import ObjectDoesNotExist try: e = Entry.objects.get(id=3) b = Blog.objects.get(id=1) except ObjectDoesNotExist: print("Either the entry or blog doesn't exist.") in_bulk(id_list) 接收一個主鍵值列表,然后根據每個主鍵值所其對應的對象,返回一個主鍵值與對象的映射字典。 Author.objects.in_bulk([1,2,3]) {1: <Author: 蒼松>, 2: <Author: 猴王>, 3: <Author: 宋清風>} first() 查詢第一條,一般使用前先排序,或者確定其只有一條數據。 last() 查詢最后一條,同上 count() 返回數據庫中匹配查詢(QuerySet)的對象數量。 count() 不會拋出任何異常。 exists() 如果 QuerySet 包含有數據,就返回 True 否則就返回 False。這可能是最快最簡單的查詢方法了。 latest(field_name=None) ,根據時間字段 field_name 得到最新的對象。 earliest(field_name=None), 根據時間字段 field_name 得到最老的對象。
#F使用查詢條件的值,進行數值計算 from django.db.models import F Book.objects.filter(id=1).update(price=F('price')+10)
b、查詢結果為QuerySet
常用方法:
1、filter(**kwargs) 過濾,返回一個新的QuerySet,包含與給定的查詢參數匹配的對象。 >>>q=Author.objects.filter(name=u"蒼松") >>> q [<Author: 蒼松>] 2、exclude(**kwargs) 反過濾,返回一個新的QuerySet,它包含不滿足給定的查找參數的對象。功能與filter相反。 3、values(*fields) 返回一個新的QuerySet,但迭代時返回字典而不是模型實例對象。 *fields表示需要取哪些字段,空表示取所有字段。 >>> q=Author.objects.values("id") >>> q [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 18}, {'id': 22}, {'id': 24}] 4、values_list(*fields, flat=False) 返回一個新的QuerySet,但迭代時返回元組而不是模型實例對象。 *fields表示需要取哪些字段,空表示取所有字段。flat=True表示返回的結果為單個值而不是元組,多個字段時不能使用flat。 >>> q=Author.objects.values_list("id") >>> q [(1,), (2,), (3,), (4,), (18,), (22,), (24,)] >>> q=Author.objects.values_list("id",flat=True) >>> q [1, 2, 3, 4, 18, 22, 24] 5、all() 返回當前 QuerySet所有對象。 6、select_related(*field) 返回一個QuerySet,使用JOIN語句連表查詢。它會在執行查詢時自動跟蹤外鍵關系,一次讀取所有外鍵關聯的字段,並盡可能地深入遍歷外鍵連接,以減少數據庫的查詢。但數據關系鏈復雜的查詢需要慎用。僅對外鍵生效。 7、prefetch_related(*field) prefetch_related()的解決方法是,分別查詢每個表,然后用Python處理他們之間的關系。外鍵和多對多都生效。 8、order_by(*fields) 排序,返回一個新的QuerySet,隱式的是升序排序,-name表示根據name降序 >>> q=Author.objects.order_by("name") >>> q [<Author: au>, <Author: 宋清風>, <Author: 猴王>, <Author: 美猴王>, <Author: 蒼松>, <Author: 趙清風>, <Author: 陶淵明>] >>> q=Author.objects.order_by("-name") >>> q [<Author: 陶淵明>, <Author: 趙清風>, <Author: 蒼松>, <Author: 美猴王>, <Author: 猴王>, <Author: 宋清風>, <Author: au>] 9、reverse() reverse()方法返回反向排序的QuerySet。 必須對一個已經排序過的queryset(也就是q.ordered=True)執行reverse()才有效果。 10、distinct([*fields]) 去重復。返回一個在SQL 查詢中使用SELECT DISTINCT 的新QuerySet。

1、dates(field, kind, order='ASC') field 是你的 model 中的 DateField 字段名稱。 kind 是 “year”, “month” 或 “day” 之一。 每個 datetime.date對象都會根據所給的 type 進行截減。 “year” 返回所有時間值中非重復的年分列表。 “month” 返回所有時間值中非重復的年/月列表。 “day” 返回所有時間值中非重復的年/月/日列表。 order, 默認是 ‘ASC’,只有兩個取值 ‘ASC’ 或 ‘DESC’。它決定結果如何排序。 2、datetimes(field, kind, order=’ASC’) 返回一個 DateTimeQuerySet,參數與dates類似,多了"hour", "minute" ,"second" 3、none() 返回一個 EmptyQuerySet,它是一個運行時只返回空列表的 QuerySet。它經常用在這種場合:你要返回一個空列表,但是調用者卻需要接收一個 QuerySet 對象。 4、defer(*fields) 將不想載入的字段的名稱傳給 defer() 方法,就可以做到延后載入。 在某些數據復雜的環境下,你的 model 可能包含非常多的字段,可能某些字段包含非常多的數據(比如,文檔字段),或者將其轉化為Python對象會消耗非常多的資源。在這種情況下,有時你可能並不需要這種字段的信息,那么你可以讓 Django 不讀取它們的數據。 5、only(*fields) only() 方法或多或少與 defer() 的作用相反。如果你在提取數據時希望某個字段不應該被延后載入,而應該立即載入,那么你就可以做使用 only()方法。 6、多數據庫切換using(alias) 單獨使用無意義,配合其他查詢集方法一起使用。 Author.objects.using('backup') 7、表鎖定select_for_update(nowait=False) 單獨使用無意義,配合其他查詢集方法一起使用。 返回queryset,並將需要更新的行鎖定,類似於SELECT … FOR UPDATE的操作。 entries = Entry.objects.select_for_update().filter(author=request.user) 所有匹配的entries都會被鎖定直到此次事務結束。
特別的:QuerySet可以使用切片限制查詢集。
切片后依舊獲得QuerySet,並且不會觸發數據庫查詢。 >>> a=Author.objects.all()[0:2] >>> type(a) <class 'django.db.models.query.QuerySet'> 設置步長值后,獲得到List類型值。觸發數據庫查詢 >>> a=Author.objects.all()[::2] >>> type(a) <type 'list'> 使用索引,數據對象,觸發數據庫查詢 >>> Author.objects.all()[0] #等價於Author.objects.all()[0:1].get()
<Author: 蒼松>
查看QuerySet的原始SQL語句
關於查看QuerySet的原始SQL語句,使用查詢集的query對象。 >>> q=Author.objects.all() >>> print q.query SELECT "otest_author"."id", "otest_author"."name" FROM "otest_author"
c、查詢條件(雙下划線)
所有使用查詢條件的查詢和查詢集過濾的方法(get,get_or_create,filter,exclude等)都可以使用雙下划線組合出更復雜的查詢條件。
另一種使用雙下划線的情況就是跨表條件查詢單情況,見下一節關聯字段中跨表查詢。
查詢條件格式 field__條件類型,例如a=Author.objects.get(id__exact=1) 默認為精確匹配 例如:Author.objects.get(id=1)等價於Author.objects.get(id__exact=1) 一、精確匹配 exact 精確匹配: Blog.objects.get(id__exact=1) iexact 忽略大小寫的精確匹配,Blog.objects.filter(name__iexact='blog7') 二、模糊匹配 (模糊匹配,僅PostgreSQL 和 MySQL支持. SQLite的LIKE 語句不支持大小寫敏感特性,因此模糊匹配對於 SQLite無法對大敏感) contains 大小寫敏感的內容包含測試:Blog.objects.filter(name__contains='blog7') icontains 大小寫不敏感的內容包含測試: startswith 大小寫敏感的內容開頭 Blog.objects.filter(name__startswith="blog") endswith 大小寫敏感的內容結尾 endswith. istartswith 大小寫不敏感的內容開頭 startswith. iendswith 大小寫不敏感的內容結尾 endswith. 三、正則匹配 regex 大小寫敏感的正則表達式匹配。 它要求數據庫支持正則表達式語法,而 SQLite 卻沒有內建正則表達式支持,因此 SQLite 的這個特性是由一個名為 REGEXP 的 Python 方法實現的,所以要用到 Python 的正則庫 re. Entry.objects.get(title__regex=r'^(An?|The) +') 等價於 SQL: SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'c'); -- Oracle SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite iregex 忽略大小寫的正則表達式匹配。 四、范圍匹配 gt 大於: Blog.objects.filter(id__gt=3) gte 大於等於. lt 小於. lte 小於等於. ne 不等於. in 位於給定列表中: Blog.objects.filter(id__in=[1,3,5]) range 范圍測試: Blog.objects.filter(name__range=('blog1','blog5')) 日期匹配: year 對 date/datetime 字段, 進行精確的 年 匹配:Polls.objects.filter(pub_date__year=2005). month day hour minute second 空值匹配 isnull True/False; 做 IF NULL/IF NOT NULL 查詢:Blog.objects.filter(name__isnull=True)
d、 復雜查詢條件,使用Q 對象進行復雜的查詢
filter() 等方法中的關鍵字參數查詢都是一起進行“AND” 的。 如果需要執行更復雜的查詢(例如OR 語句),你可以使用Q 對象。
Q對象有兩種使用方式,一種使用Tree模式。另一種是使用"|"和"&"符號進行與或操作。 Q構建搜索條件 from django.db.models import Q con = Q() q1 = Q() q1.connector = 'OR' q1.children.append(('id', 1)) q1.children.append(('id', 2)) #等價於Q(id=1) | Q(id=2) q2 = Q() q2.connector = 'AND' q2.children.append(('id', 1)) q2.children.append(('name__startswith', 'a')) #等價於Q(id=1) | Q(name__startswith='a') con.add(q1, 'AND') con.add(q2, 'AND') Q搜索可以和普通查詢參數一起使用,但查詢參數需要在最后。 Author.objects.filter(q1,id=26)
2.2關聯字段CURD操作(一對一,一對多,多對多表關系操作)
一對一和多對多的表關系的增刪改查 a1 = Author.objects.get(name="猴子") a2 = Author.objects.get(name="蒼松") a3 = Author.objects.get(name="魯迅") p1=Publisher.objects.get(name="機械出版社") p2=Publisher.objects.get(name="av") ==============正向關系操作=================================================== 增 b1=Book(title="紅樓夢",price=10) b1.publisher=p1或者b1.publisher_id=1 #一對多 b1.save() 先保存book對象之后才能添加多對多關系 b1.authors.add(a1,a2)或者b1.authors=[a1,a2] #多對多 b1.save() 刪 b1.publisher=None或者b1.publisher_id=None #一對多 b1.authors.remove(a1,a2) 實際上是刪除關系表otest_book_authors中的一條數據 #多對多 b1.authors.clear() 清空所有關系 #多對多 查詢
Book.objects.filter(publisher__name=u"機械出版社") #一對多,使用雙下划線
Book.objects.filter(authors__name=u"蒼松") #多對多,使用雙下划線
獲取字段值對象 b2.publisher #一對多,對象下面的字段值繼續使用.獲取。例如b2.publisher.name b1.authors.all() #多對多 ==============反向關系操作=================================================== 增 p1.book_set.add(b1) #一對多,會更新現有的關系。(一個對象只能有一個外鍵) a3.book_set.add(b1) #多對多 刪 p1.book_set.remove(b1) #一對多 a3.book_set.remove(b1) #多對多 a3.book_set.clear() #多對多,清空所有關系 獲取字段值對象 a2.book_set.all() #多對多 p1.book_set.all() #一對多 =============自定義中介模型方法=================================================== 中介模型add、create 、remove方法不可用。但是clear() 方法卻是可用的,它可以清空某個實例所有的多對多關系。
三、使用原始SQL語句
Django提供兩種方法使用原始SQL進行查詢:一種是使用Manager.raw()方法,進行原始查詢並返回模型實例;另一種直接執行自定義的SQL語句。
1、使用Manager.raw()方法
Manager.raw(raw_query, params=None, translations=None) raw_query SQL查詢語句。 params 查詢條件參數,是list或者dict translations 字段映射表,是一個dict。 Manager.raw()將查詢結果映射到類字段,默認情況下映射到同名字段。返回結果是一個RawQuerySet。
如果在其他的表中有一些Author數據,你可以很容易地把它們映射成Author實例。
手動指定字段映射字典。 方法一:使用AS,其他字段自動應設至Author表中的同名字段。 na=Author.objects.raw("select name AS newname, id from otest_author") >>> na[0] <Author_Deferred_name: 蒼松> . 方法二:使用translations name_map={"name":"newname} na=Author.objects.raw("select * from otest_author",translations=name_map) params參數防止SQL注入 方法一:使用list >>> na=Author.objects.raw("select * from otest_author where id =%s",[id]) >>> na[0] <Author: 蒼松> 方法二:使用dict 注意:SQLite后端不支持字典,你必須以列表的形式傳遞參數。 字典使用%(key)s占位符(key替換成字典中相應的key值) p_dict={"id":1} na=Author.objects.raw("select * from otest_author where id =%(id)s",p_dict)
2.直接執行自定義的SQL
有時Manager.raw()方法並不十分好用,你不需要將查詢結果映射成模型,或者你需要執行UPDATE、 INSERT以及DELETE查詢。
#單數據庫 from django.db import connection def my_custom_sql(self): cursor = connection.cursor() cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz]) cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz]) row = cursor.fetchone()
connection.close() return row #多數據庫 from django.db import connections cursor = connections['my_db_alias'].cursor() # Your code here... 默認情況下,Python DB API會返回不帶字段的結果,這意味着你得到的是一個列表,而不是一個字典。 def dictfetchall(cursor): "Returns all rows from a cursor as a dict" desc = cursor.description return [ dict(zip([col[0] for col in desc], row)) for row in cursor.fetchall() ] >>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2"); >>> cursor.fetchall() ((54360982L, None), (54360880L, None)) >>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2"); >>> dictfetchall(cursor) [{'parent_id': None, 'id': 54360982L}, {'parent_id': None, 'id': 54360880L}]
四、分組和聚合
Avg 平均值 Count(expression, distinct=False) 計算個數。如果distinct=True,Count將只計算唯一的值。默認值為False。 Max 最大值 Min 最小值 Sum 求和
方法一:使用annotate方法,先分組(group by)再聚合 from django.db.models import Count, Min, Max, Sum,Avg >>> Book.objects.values('publisher').annotate(counts_num=Count("*")) [{'publisher': 1, 'counts_num': 2}, {'publisher': 3, 'counts_num': 1}] >>> Book.objects.values('publisher').annotate(Avg("price")) [{'publisher': 1, 'price__avg': 12.5}, {'publisher': 3, 'price__avg': 11.0}] #得到分組的多個值列表 使用values('publisher')進行group by分組后,在使用聚合函數才有意義。 默認聚合名稱filedname__聚合函數名,作為聚合字段名。 方法二:使用aggregate方法,先過濾再聚合 Book.objects.filter(publisher_id=1).aggregate(Count("id")) {'id__count': 2} #得到單個值
參考文檔:
http://python.usyiyi.cn/django/index.html中文翻譯1.8.2版中文不好的同學可以看這個