數據庫的操作(CRUD操作)
CRUD是指在做計算處理時的增加(創建),讀取查詢(讀),更新(更新)和刪除(刪除)
一、管理器對象
1.每個繼承自modelss.Model的模型類,都會有一個對象對象被同樣繼承下來。這個對象叫管理器對象2.數據庫的增刪改查可以通過模型的管理器實現
class Entry(models.Model): ... Entry.objects.create(...) # 是管理器對象
二、創建數據對象
Django使用一種直觀的方式把數據庫表中的數據表示成Python對象
創建數據中每一條記錄就是創建一個數據對象
1.Entry.objects.create(屬性1 =值1,屬性2 =值1,...)
成功:返回創建好的實體對象
失敗:拋出異常
2.創建Entry實體對象,並調用save()進行保存
obj = Entry(屬性=值,屬性=值) obj.屬性=值 obj.save() 無返回值,保存成功后,obj會被重新賦值

try: abook = Book.objects.create(title='Python', pub='清華大學出版社') print(abook) except: print('創建對象失敗')

try: abook = Book(title='Python', pub='清華大學出版社') abook.save() print(abook) except: print('創建對象失敗')

try: abook = Book() abook.title='Python' abook.pub='清華大學出版社' abook.save print(abook) except: print('創建對象失敗')
三、Django shell的使用
在Django的了提供交互式一個操作的項目叫Django Shell
它能夠在交互模式用項目工程的代碼執行相應的操作
利用Django Shell可以代替編寫查看的代碼來進行直接操作
在Django Shell下只能進行簡單的操作,不能運行遠程調式
啟動Django shell顯示IPython風格的交互界面如下:
$ python3 manage.py shell manage.py shell Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04) Type 'copyright', 'credits' or 'license' for more information IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: In [2]: from bookstore import models In [3]: models.Book.objects.create(title="Python") Out[3]: <Book: Book object> In [4]: book = models.Book.objects.create(title='C++') In [4]: print(book) Book object
四、查詢數據
數據庫的查詢需要使用管理器對象進行
通過Entry.objects管理器方法調用查詢接口
方法 |
用法 |
作用 |
返回值 |
all() |
Entry.objects.all() |
查詢Entry實體中所有的數據 |
QuerySet容器對象,內部存放Entry實例 |
values('列1','列2') |
Entry.objects.values(...) |
查詢部分列的數據並返回 從xxx中選擇列1,列2 |
QuerySet 返回查詢結果容器,容器內存字典,每個字典代表一條數據, 格式為:{'列1':值1,'列2':值2} |
values_list( '列1', '列2') |
Entry.objects.values_list(...) |
返回元組形式的查詢結果 |
QuerySet容器對象,內部存放 會將查詢出來的數據封裝到元組中,再封裝到查詢集合QuerySet的中 |
ORDER_BY |
Entry.objects.order_by( ' - 列', '列') |
與all()方法不同,它會用SQL語句的ORDER BY子句對查詢結果進行根據某個字段選擇性的進行排序 說明:默認是按照升序排序,降序排序則需要在列前增加 ' - ' 表示 |
|
filter(條件) |
Entry.objects.filter(屬性1=值1, 屬性2=值2) |
根據條件查詢多條記錄 |
QuerySet容器對象,內部存放Entry實例 |

#查找所有 from bookstore import models books = models.Book.objects.all() for book in books: print("書名", book.title, '出版社:', book.pub) ###################### #查詢返回指定列(字典表示) from bookstore import models books = models.Book.objects.values("title", "pub") for book in books: print("書名", book["title"], '出版社:', book['pub']) print("book=", book) ####################### #查詢返回指定列(元組表示) from bookstore import models books = models.Book.objects.values_list("title", "pub") for book in books: print("book=", book) # ('Python', '清華大學出版社')... ####################### #排序查詢 from bookstore import models books = models.Book.objects.order_by("price") for book in books: print("書名:", book.title, '價格:', book.price) ####################### #根據條件查詢多條記錄 # 1. 查詢書中出版社為"清華大學出版社"的圖書 from bookstore import models books = models.Book.objects.filter(pub="清華大學出版社") for book in books: print("書名:", book.title) #2. 查詢Author實體中id為1並且isActive為True的 authors=Author.objects.filter(id=1,isActive=True)
模型在類中定義def __str__(self):
方法可以將自定義默認為字符串
class Book(models.Model): title = ... def __str__(self): return "書名: %s, 出版社: %s, 定價: %s" % (self.title, self.pub, self.price)
五、字段查找
- 字段查詢是指如何指定SQL語句中 WHERE 子句的內容。
- 字段查詢需要通過QuerySet的filter(), exclude() and get()的關鍵字參數指定。
- 非等值條件的構建,需要使用字段查詢
# 查詢作者中年齡大於30 Author.objects.filter(age__gt = 30) # 對應 SELECT .... WHERE AGE > 35;
六、查詢謂詞
每一個查詢謂詞是一個獨立的查詢功能
1.__exact
: 等值匹配
2.__contains
: 包含指定值
3.__startswith
: 以 XXX 開始
4.__endswith
: 以 XXX 開始
5.__gt
: 大於指定值
6.__gte
: 大於等於
7.__lt
: 小於
8.__lte
: 小於等於
9.__in
: 查找數據是否在指定范圍內
10.__range
: 查找數據是否在指定的區間范圍內

#1.__exact : 等值匹配 books= models.Author.objects.filter(id__exact=1) # 等同於 select * from author where id = 1 --------------- #2.__contains : 包含指定值 books= models.Author.objects.filter(name__contains='w') # 等同於 select * from author where name like '%w%' -------------- #5.__gt : 大於指定值 books= models.Author.objects.filer(age__gt=50) # 等同於 select * from author where age > 50 -------------- #9.__in : 查找數據是否在指定范圍內 books= models.Author.objects.filter(country__in=['中國','日本','韓國']) # 等同於 select * from author where country in ('中國','日本','韓國') #10.__range: 查找數據是否在指定的區間范圍內 # 查找年齡在某一區間內的所有作者 books= models.Author.objects.filter(age__range=(35,50)) # 等同於 SELECT ... WHERE Author BETWEEN 35 and 50;
詳細內容參見: https://docs.djangoproject.com/en/1.11/ref/models/querysets/#field-lookups
不等條件篩選
語法: Entry.objects.exclude(條件)
作用:返回不包含此條件
的數據集
示例:查詢清華大學出版社,價格大於50以外的全部圖書
books = models.Book.objects.exclude(pub=清華大學出版社, price__lt=50) for book in books: print(book)
查詢指定的一條數據
語法:Entry.objects.get(條件)
作用:返回滿足條件的唯一一條數據
返回值:Entry 對象
說明:
- 該方法只能返回一條數據
- 查詢結果多余一條數據則拋出,Model.MultipleObjectsReturned異常
- 查詢結果如果沒有數據則拋出Model.DoesNotExist異常
from bookstore import models book = models.Book.object.get(id=1) print(book.title)
七、修改數據記錄
修改單個實體的某些字段值
查:通過 get() 得到要修改的實體對象
改:通過 對象.屬性 的方式修改數據
保存:通過 對象.save() 保存數據
from bookstore import models abook = models.Book.objects.get(id=10) abook.market_price = "10.5" abook.save()
通過 QuerySet 批量修改 對應的全部字段
直接調用QuerySet的update(屬性=值) 實現批量修改
# 將 id大於3的所有圖書價格定為0元 books = models.Book.objects.filter(id__gt=3) books.update(price=0) # 將所有書的零售價定為100元 books = Book.objects.all() books.update(market_price=100)
八、刪除記錄
刪除記錄是指刪除數據庫中的一條或多條記錄
刪除單個Entry對象或刪除一個查詢結果集(QuerySet)中的全部對象都是調用 delete()方法
1.刪除單個對象
步驟:
- 查找查詢結果對應的一個數據對象
- 調用這個數據對象的delete()方法實現刪除
try: auth = Author.objects.get(id=1) auth.delete() except: print(刪除失敗)
2.刪除查詢結果集
步驟
- 查找查詢結果集中滿足條件的全部QuerySet查詢集合對象
- 調用查詢集合對象的delete()方法實現刪除
# 刪除全部作者中,年齡大於65的全部信息 auths = Author.objects.filter(age__gt=65) auths.delete()
九、聚合查詢
聚合查詢是指對一個數據表中的一個字段的數據進行部分或全部進行統計查詢,查bookstore_book數據表中的全部書的平均價格,查詢所有書的總個數等,都要使用聚合查詢
1.不帶分組聚合
不帶分組的聚合查詢是指導將全部數據進行集中統計查詢
定義模塊: django.db.models
用法: from django.db.models import *
聚合函數:Sum, Avg, Count, Max, Min
語法:Entry.objects.aggregate(結果變量名=聚合函數('列'))
返回結果:
由結果變量名和值組成的字典
格式為:{"結果變量名": 值}
# 得到所有書的平均價格 from bookstore import models from django.db.models import Count result = models.Book.objects.aggregate(myAvg=Avg('price')) print("平均價格是:", result['myAvg']) print("result=", result) # {"myAvg": 58.2} # 得到數據表里有多少本書 from django.db.models import Count result = models.Book.objects.aggregate(mycnt=Count('title')) print("數據記錄總個數是:", result['mycnt']) print("result=", result) # {"mycnt": 10}
2.分組聚合
分組聚合是指通過計算查詢結果中每一個對象所關聯的對象集合,從而得出總計值(也可以是平均值或總和),即為查詢集的每一項生成聚合。
語法:QuerySet.annotate(結果變量名=聚合函數('列'))
用法步驟:
1.通過先用查詢結果Entry.object.value. 查找查詢要分組聚合的列
Entry.object.value('列1', '列2')
pub_set = models.Book.objects.values('pub') print(books)
# <QuerySet [{'pub': '清華大學出版社'}, {'pub': '清華大學出版社'}, {'pub_hou {'pub': '機械工業出版社'}, {'pub': '清華大學出版社'}]>
2.通過返回結果的 QuerySet.annotate 方法分組聚合得到分組結果
QuerySet.annotate(名=聚合函數('列'))
返回 QuerySet 結果集,內部存儲結果的字典
pub_count_set = pub_set.annotate(myCount=Count('pub')) print(pub_count_set)
# <QuerySet [{'pub': '清華大學出版社', 'myCount': 7}, {'pub': '機械工業出版社', 'myCount': 3}]>
查詢哪兒個出版社共出版多少本書
def test_annotate(request): - from django.db.models import Count from . import models # 得到所有出版社的查詢集合QuerySet pub_set = models.Book.objects.values('pub') # 根據出版社查詢分組,出版社和Count的分組聚合查詢集合 pub_count_set = pub_set.annotate(myCount=Count('pub')) # 返回查詢集合 for item in pub_count_set: print("出版社:", item['pub'], "圖書有:", item['myCount']) return HttpResponse('請查看服務器端控制台獲取結果')
十、F對象
一個F對象代表數據庫中某個字段的信息
F對象通常是對數據庫中的字段值在不加載到內存中的情況下直接在數據庫服務器端進行操作
F對象在數據包 django.db.models 中.使用時需要通過如下語句進行加載
from django.db.models import F
作用:
用於類屬性(字段)之間的比較。
當同時對數據庫中兩個字段的值進行比較獲取 QuerySet 數據集時,可以便用F對象
說明:
一個 F()對象代表了一個model的字段的值
使用它就可以直接參考model的field和執行數據庫操作而不用再把它們(model field)查詢出來放到python內存中。
語法:
from django.db.models import F
F('列名')
示例1:更新Book實例中所有的制場價漲10元
示例2:對數據庫中兩個字段的值進行比較,列出哪兒些書的零售價高於定價?

#示例1 models.Book.objects.all().update(market_price=F('market_price')+10) # 以下做法好於如下代碼 books = models.Book.objects.all() for book in books: book.update(market_price=book.marget_price+10) book.save() ------------------ #示例2 from django.db.models import F from bookstore import models books = models.Book.objects.filter(market_price__gt=F('price')) for book in books: print(book.title, '定價:', book.price, '現價:', book.market_price)
十一、Q對象
當在獲取查詢結果集 使用復雜的邏輯或 |
、 邏輯非 ~
等操作時可以借助於 Q對象進行操作
如: 想找出定價低於20元 或 清華大學出版社的全部書,可以寫成
models.Book.objects.filter(Q(price__lt=20)|Q(pub="清華大學出版社"))
Q對象在 數據包 django.db.models 中。需要先導入再使用
from django.db.models import F
作用:在條件中用來實現除 and(&) 以外的 or(|) 或 not(~) 操作
運算符:
& 與操作
| 或操作
〜 非操作
語法:
from django.db.models import Q
Q(條件1)|Q(條件2) # 條件1成立或條件2成立
Q(條件1)&Q(條件2) # 條件1和條件2同時成立
Q(條件1)&~Q(條件2) # 條件1成立且條件2不成立
from django.db.models import Q # 查找清華大學出版社的書或價格低於50的書 models.Book.objects.filter(Q(market_price__lt=50) | Q(pub_house='清華大學出版社')) # 查找不是機械工業出版社的書且價格低於50的書 models.Book.objects.filter(Q(market_price__lt=50) & ~Q(pub_house='機械工業出版社'))
十二、原生的數據庫操作方法
1.使用Entry.objects.raw()進行 數據庫查詢操作查詢
在django中,可以使用模型管理器的raw方法來執行select語句進行數據查詢
語法:Entry.objects.raw(sql語句)
用法:Entry.objects.raw('sql語句')
返回值:QuerySet 集合對象
示例:
books = models.Book.objects.raw('select * from bookstore_book') for book in books: print(book)
2.使用django中的游標cursor對數據庫進行 增刪改操作
在Django中可以使用 如UPDATE,DELETE等SQL語句對數據庫進行操作。
在DJaogo中使用上述非查詢語句必須使用游標進行操作
使用步驟:
1.導入cursor所在的包
Django中的游標cursor定義在 django.db.connection包中,使用前需要先導入
如:from django.db import connection
2.用創建cursor類的構造函數創建cursor對象,再使用cursor對象,為保證在出現異常時能釋放cursor資源,通常使用with語句進行創建操作
如:
from django.db import connection with connection.cursor() as cur: cur.execute('執行SQL語句')
示例
# 用SQL語句將id 為 10的 書的出版社改為 "XXX出版社" from django.db import connection with connection.cursor() as cur: cur.execute('update bookstore_book set pub_house="XXX出版社" where id=10;') with connection.cursor() as cur: # 刪除 id為1的一條記錄 cur.execute('delete from bookstore_book where id=10;')