[TOC]
Django的manage工具提供了shell命令,已經幫助我們配置好當前工程的運行環境(如連接好數據庫等),我們會在自帶終端中執行測試python語句。
`manage.py` 所在目錄執行命令
```
python manage.py shell
```
這打開了一個交互式命令行。
導入模型類
```
from book.models import Book
from book.models import Role
```
導入date包處理時間
```
from datetime import date
```
## 增
增加數據有兩種方式
### 1.save
創建模型類對象,再使用 `save` 保存到數據庫中
新增書籍 “西游記”
```
book = Book(
b_title="西游記",
b_pub_date=date(1988,1,1),
b_read=20,
b_comment=10,
is_delete=False)
>>> book.save()
```
### 2.create
直接保存到數據庫中
“西游記”書籍新增角色 “孫悟空”
```
Role.objects.create(
r_name="孫悟空",
r_gender="1",
r_describe="猴哥",
r_book_id=book.id)
```
## 查
### 1.基本查詢
**get** 查詢單一結果,如果不存在會拋出模型類.DoesNotExist異常,返回一個模型類對象。
**all** 查詢多個結果,返回一個查詢集。
**count** 查詢結果數量。
#### get
get 查詢單一結果,如果不存在會拋出模型類.DoesNotExist異常。
查詢編號為5的書籍
```python
>>> Book.objects.get(pk=5)
<Book: Book object>
```
objects 是模型管理器,會在后邊有具體的講解。
pk代表primary key的縮寫,也就是任何model中都有的主鍵,當id也是主鍵的時候,我們可以認為pk和id是完全一樣的。但是當model的主鍵不是id的時候,兩者就有了區別。
輸出出來的 `<Book: Book object>` 無法看出是不是我們寫進去的數據,為了讓顯示更人性化,我們給數據庫模型添加一個 `_str__` 方法。
```python
class Book(models.Model):
...
def __str__(self):
return self.b_title
class Role(models.Model):
...
def __str__(self):
return self.r_name
```
重啟shell,重新導入模型類
```python
>>> Book.objects.get(id=5)
<Book: 西游記>
```
#### all
all 查詢多個結果。
查詢所有書
```python
>>> Book.objects.all()
<QuerySet [<Book: 射雕英雄傳>, <Book: 天龍八部>, <Book: 笑傲江湖>, <Book: 雪山飛狐>, <Book: 西游記>]>
```
#### count
count 查詢結果數量。
獲得書籍數量
```python
>>> Book.objects.count()
5
```
### 2.過濾查詢
過濾查詢實現sql語句中的 `where` 功能,包括:
**filter** 過濾出多個結果,返回一個查詢集
**exclude** 排除掉符合條件剩下的結果,返回一個查詢集
**get** 過濾單一結果
過濾查詢語法:
```
模型類名.objects.查詢方式(過濾條件)
```
過濾條件語法:
```
字段名稱__條件運算符=值
```
條件運算符:
```
exact:相等。
contains:包含。
startswith:指定值開頭
endswith:指定值結尾
isnull:是否為null。
in:是否包含在范圍內。
gt: 大于 (greater then)
gte: 大于等于 (greater then equal)
lt: 小于 (less then)
lte: 小于等于 (less then equal)
year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算。
```
#### 相等
exact:表示相等
查詢書名等于“西游記”的書
```python
>>> Book.objects.filter(b_title__exact="西游記")
<QuerySet [<Book: 西游記>]>
```
#### 包含(模糊查詢)
contains:包含
書名包含“八”字的書
```python
>>> Book.objects.filter(b_title__contains="八")
<QuerySet [<Book: 天龍八部>]>
```
#### 開頭
書名“笑”開頭的數
```python
>>> Book.objects.filter(b_title__startswith="笑")
<QuerySet [<Book: 笑傲江湖>]>
```
#### 結尾
```python
>>> Book.objects.filter(b_title__endswith="狐")
<QuerySet [<Book: 雪山飛狐>]>
```
#### 空
isnull:是否為null
書名不為空
```python
>>> Book.objects.filter(b_title__isnull=False)
<QuerySet [<Book: 射雕英雄傳>, <Book: 天龍八部>, <Book: 笑傲江湖>, <Book: 雪山飛狐>, <Book: 西游記>]>
```
#### 包含(范圍)
in:是否包含在范圍內
編號 1,2,3的書
```python
>>> Book.objects.filter(pk__in=[1, 2, 3])
<QuerySet [<Book: 射雕英雄傳>, <Book: 天龍八部>, <Book: 笑傲江湖>]>
```
#### 大于小于
```
gt: 大于 (greater then)
gte: 大于等于 (greater then equal)
lt: 小于 (less then)
lte: 小于等于 (less then equal)
```
編號大于3的書
```python
>>> Book.objects.filter(pk__gt=3)
<QuerySet [<Book: 雪山飛狐>, <Book: 西游記>]>
```
#### 時間
year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算。
1995年的書
```python
>>> Book.objects.filter(b_pub_date__year="1995")
<QuerySet [<Book: 笑傲江湖>]>
```
### 3. F對象
F()是代表模型字段的值,可以用來修改字段或者比較字段。
導入F對象
```python
from django.db.models import F
```
F對象使用
```python
F(字段名)
```
閱讀量大于評論量
```python
>>> Book.objects.filter(b_read__gt=F('b_comment'))
<QuerySet [<Book: 雪山飛狐>, <Book: 西游記>]>
```
閱讀量大于評論量兩倍
```python
>>> Book.objects.filter(b_read__gt=F('b_comment')*2)
<QuerySet [<Book: 雪山飛狐>]>
```
### 4. Q對象
隨著程序的復雜,查詢條件也會越來越復雜,類似前邊的查詢語句也會變得越來越長。
例如查詢閱讀量大于20且評論數大于30的書,需要這樣
```python
>>> book = Book.objects.filter(b_read__gt=20)
>>> book.filter(b_comment__gt=30)
<QuerySet [<Book: 天龍八部>]>
```
或者這樣
```python
>>> Book.objects.filter(b_read__gt=20).filter(b_comment__gt=30)
<QuerySet [<Book: 天龍八部>]>
```
但是這樣的語句是相當繁雜且不利于閱讀的。
**Q()對象就是為了將這些條件組合起來。**
Q對象可以使用 `&` `|` `~` 連接,`&` 表示邏輯與, `|` 表示邏輯或,`~` 表示非。
類似sql語句中where部分的 `and` `or` `not` 關鍵字。
導入Q對象
```python
from django.db.models import Q
```
使用Q對象實現查詢閱讀量大于20且評論數大于30的書
```python
>>> Book.objects.filter(Q(b_read__gt=20)&Q(b_comment__gt=30))
<QuerySet [<Book: 天龍八部>]>
```
### 5. 聚合函數
使用aggregate()過濾器調用聚合函數。聚合函數包括:Avg 平均,Count 數量,Max 最大,Min 最小,Sum 求和。
需要從 `django.db.models` 中導入,例如
```python
from django.db.models import Sum
```
查詢最多閱讀數
```python
>>> Book.objects.aggregate(Max('b_read'))
{'b_read__max': 58}
```
聚合函數查詢結果是一個字典類型
```
{'字段名__聚合類小寫': 查詢結果}
```
### 6. 排序
使用 `order_by` 對查詢結果排序,返回一個查詢集。
按閱讀量排序
```python
>>> Book.objects.all().order_by('b_read') # 升序排序
<QuerySet [<Book: 射雕英雄傳>, <Book: 笑傲江湖>, <Book: 西游記>, <Book: 天龍八部>, <Book: 雪山飛狐>]>
>>> Book.objects.all().order_by('-b_read') # 降序排序
<QuerySet [<Book: 雪山飛狐>, <Book: 天龍八部>, <Book: 笑傲江湖>, <Book: 西游記>, <Book: 射雕英雄傳>]>
```
### 7. 關聯查詢
#### 一查多
語法
```
一方查詢對象.多方模型類名小寫__set
```
查詢“天龍八部”所有的角色
```python
>>> book = Book.objects.get(b_title__exact="天龍八部")
>>> book.role_set.all()
<QuerySet [<Role: 喬峰>, <Role: 段譽>, <Role: 虛竹>, <Role: 王語嫣>]>
```
#### 多查一
語法
```
多方查詢對象.多方有對應關系的字段名
```
查詢“段譽”所在書名
```python
>>> role = Role.objects.get(r_name__exact="段譽")
>>> role.r_book
<Book: 天龍八部>
```
### 8. 關聯+過濾查詢
#### 根據多方條件查一方
語法格式
```
多方模型類名小寫__多方字段名__條件運算符=值
```
查詢編號為1角色所在書籍
```python
>>> Book.objects.filter(role__id__exact=1)
<QuerySet [<Book: 射雕英雄傳>]>
```
查詢角色名字帶“黃”字的書籍
```python
>>> Book.objects.filter(role__r_name__contains="黃")
<QuerySet [<Book: 射雕英雄傳>, <Book: 射雕英雄傳>]>
```
當查詢條件為等于的時候可以省略條件運算符
查詢編號為1角色所在書籍可以這樣寫
```python
>>> Book.objects.get(role__id=1)
<Book: 射雕英雄傳>
```
#### 根據一方條件查多方
語法格式
```
多方有對應關系的字段名__一方字段名__查詢條件=值
```
查詢“雪山飛狐所有角色”
```python
>>> Role.objects.filter(r_book__b_title__exact="雪山飛狐")
<QuerySet [<Role: 胡斐>, <Role: 苗若蘭>, <Role: 程靈素>, <Role: 袁紫衣>]>
```
查詢閱讀量大于30的書籍角色
```python
>>> Role.objects.filter(r_book__b_read__gt=30)
<QuerySet [<Role: 喬峰>, <Role: 段譽>, <Role: 虛竹>, <Role: 王語嫣>, <Role: 胡斐>, <Role: 苗若蘭>, <Role: 程靈素>, <Role: 袁紫衣>]>
```
當查詢條件是等于的時候可以省略條件運算符
查詢“雪山飛狐所有角色”可以這樣寫
```
>>> Role.objects.filter(r_book__b_title="雪山飛狐")
<QuerySet [<Role: 胡斐>, <Role: 苗若蘭>, <Role: 程靈素>, <Role: 袁紫衣>]>
```
## 刪
刪除數據使用查詢結果對象的 `delete` 方法
語法格式
```
查詢結果對象.delete()
```
刪除閱讀量小于20的書
```
>>> Book.objects.filter(b_read__lt=20).delete()
(6, {'book.Role': 5, 'book.Book': 1})
```
一般刪除數據只使用邏輯刪除,即修改 `is_delete` 字段為 `True`
## 改
修改數據有兩種方式
### 1. save
獲得 **單個模型類** 對象,修改數據后使用save保存
```
>>> role = Role.objects.get(id__exact=18)
>>> role.r_name = "齊天大圣"
>>> role.save()
```
### 2. update
獲得 **查詢集** 對象,使用 `update` 方法修改數據,修改后會返回被影響數據條數
修改 `id` 大于15的角色名字為 “不知名人士”
```
>>> Role.objects.filter(id__gt=15).update(r_name="不知名人士")
4
```
- 1.介紹
- 2.工程搭建
- 2.1.環境配置
- 2.2.創建工程
- 2.3.創建子應用
- 2.3.1.pycharm打開項目
- 2.4.創建視圖
- 3.基本配置
- 3.1.settings基本配置項
- 3.2.路由配置
- 4.請求響應
- 4.1.request
- 4.2.response
- 4.3.cookie
- 4.4.session
- 5.類視圖中間件
- 5.1.類視圖
- 5.2中間件
- 6.數據庫
- 6.1.數據庫配置
- 6.2定義模型類
- 6.3數據庫遷移
- 6.4數據庫操作
- 6.5查詢集
- 6.6模型管理器
- 7.模板表單
- 7.1使用模板
- 7.2模板標簽
- 7.3表單
- 8.后臺管理
- 8.1Admin
- 8.2自定義模型類樣式
- 8.3列表頁