文章目錄
- 表結構
-
- 單表
-
- 多表 -- ForeignKey
-
- 多表 -- ManyToManyField
-
表結構
字段類型
字段 | 備注 |
AutoField | 自增列, 必須填入 primary_key=True, 如果沒有該列, 會自動建立一個名為 id 的列 |
IntegerField | 10 位内數字 |
CharField | 字元串類型, 必須填如 manx_length 參數限制長度 |
DateField | YYYY-MM-DD, 相當于 datetime.date() |
DateTimeField | YYYY-MM-DD HH:MM:[:ss:[.uuuuuu]], 相當于 datetime.datetime() |
參數限制
參數 | 注釋 |
null | 是否允許為空 |
unique | 是否唯一 |
db_index | 設定為索引 |
default | 設定預設值 |
auto_now_add=True | 記錄建立時間 |
auto_now=True | 記錄變更時間 |
單表
表結構
class Person(models.Model):
id = models.AutoField(primary_key=True) # id, 自增, 且為主鍵
name = models.CharField(max_length=16, null=False) # 姓名, 最大長度為 16, 不允許為空
age = models.IntegerField(null=True, blank=True) # 年齡, 資料庫允許為空, admin 系統允許為空
phone = models.CharField(max_length=11, unique=True) # 電話, 唯一字段, 最大長度為 11 位
資料的操作
增
- 單獨增
# 單獨添加新的資料行
models.Publisher.objects.create(name="Gury", age=19, phone="1231231234")
- 批量增
# 先建立一個生成表達式
p_list = [ models.Publisher(name="xx-{}".format(i)) for i in range(100) ]
# 使用 bulk_create 方法批量建立
models.Publisher.objects.bulk_create(p_list)
查
- 基礎查詢
# 查詢所有資料
models.Person.objects.all() # 傳回 QuerySet<[obj, obj, ..]>
# 查詢滿足條件的
models.Person.objects.filter(id=1) # 傳回 QuerySet< [obj, obj, ..]>
models.Person.objects.get(id=1) # 傳回 obj, 謹慎使用!!
# 對結果進行字段篩選
models.Person.objects.all().values("name", "phone") # 傳回 QuerySet< [{dic}, {dic}, ..]>, 結果需要使用["key"]取值
models.Person.objects.all().values_list("name", "phone") # 傳回 QuerySet< [(tuple), (tuple), ..]>, 結果需要使用[index]取值
# 查詢不滿足條件的
models.Person.objects.exclude(id=1) # 傳回 QuerySet< [obj, obj, ..]>
# 查詢結果排序
models.Person.objects.all().order_by("id") # 傳回 QuerySet< [obj, obj, ..]>,
models.Person.objects.all().order_by("id").reverse() # 将 order_by 的結果反序
# 資料條數
models.Person.objects.all().count() # 傳回 int
# 取頭/尾資料
models.Person.objects.all().first() # 傳回 object
models.Person.objects.all().last()
# 判斷是否存在
models.Person.objects.filter(id=1).exists() # 傳回 Bool
# 去重
distinct() # 常用于跨表查詢去重, mysql 不支援按照字段去重
- 進階查詢(雙下劃線用法)
# 數字比較
models.Person.objects.filter(id__gt=1) # __gt 大于
models.Person.objects.filter(id__lt=2) # __lt 小于
models.Person.objects.filter(id__gte=1) # __gte 大于等于
models.Person.objects.filter(id__lte=2) # __lte 小于等于
# 數字包含
models.Person.objects.filter(id__in=[1,3]) # id 在清單中
models.Person.objects.exclude(id__in=[1,2]) # id 不在清單中
# 字元串包含
models.Person.objects.filter(name__contains="t") # 包含字母 t 的
models.Person.objects.filter(name__icontains="T") # 忽略大小寫包含
# 範圍内
models.Person.objects.filter(id__range=[1,4]) # id 為 1 到 4 的
# 開頭, 結尾
models.Person.objects.filter(name__startswith="T") # 以 "T" 開頭
models.Person.objects.filter(name__endswith="m") # 以 "m" 結尾
# 日期格式年月日為特定值
models.Person.objects.filter(birthday__year=2018) # __year, __month, __day
改
# 先查詢, 拿到需要修改的對象, 再做操作
obj = models.Person.objects.get(id=1)
# 若資料為單獨的, 可直接給屬性指派
obj.name = "new_name"
# 若資料為清單, 使用 set() 重新設定值
obj.books.set([1, 2, 3]) # obj.屬性.set([])
# 為清單資料添加值
obj.books.add(4) # obj.屬性.add()
# 送出給資料庫
obj.save()
删
# 先查詢, 再使用 delete() 删除
models.Publisher.objects.get(id=1).delete()
多表 – ForeignKey
表結構
"""
一個 Leader 上司多個 Staff
leader -- 基礎表 -- "一"
staff -- 外鍵表 -- "多"
"""
class Leader(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
def __str__(self):
return self.name
class Staff(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
leader = models.ForeignKey(to=Leader, on_delete=models.CASCADE)
def __str__(self):
return self.name
查詢
- 基于 obj , 外鍵表查基礎表
# 1. 查詢外鍵表, 拿到 obj
obj = models.Staff.objects.get(id=1)
# 2. obj.基礎表.查詢字段, 拿到唯一的結果
r = obj.leader.name
- 基于 obj, 基礎表查外鍵表(外鍵表_set 的使用)
# 1. 查詢基礎表, 拿到 obj
obj = models.Leader.objects.get(id=1)
# 2. obj.外鍵表_set.all(), 拿到 qs
qs = obj.staff_set.all()
# 3. qs.values_list("查詢字段")
r = qs.values_list("name")
- 基于 QuerySet, 外鍵表查基礎表
# 1. 查詢外鍵表, 拿到 qs
qs = models.Staff.objects.filter(id=1)
# 2. qs.values_list("基礎表__查詢字段")
r = qs.values_list("leader__name")
- 基于 QuerySet, 基礎表查外鍵表(用法與基于 QuerySet, 外鍵表查基礎表相同)
# 1. 查基礎表, 拿到 qs
qs = models.Leader.objects.filter(id=1)
# 2. qs.values_list("外鍵表__查詢字段")
r = qs.values_list("staff__name")
多表 – ManyToManyField
表結構
class Leader(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
def __str__(self):
return self.name
class Staff(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
# related_name, 基于 qs, 基礎表查外鍵表時使用
leader = models.ManyToManyField(to=Leader, related_name="yuangong")
def __str__(self):
return self.name
查詢
- 基于 obj, 外鍵表查基礎表
# 1. 查詢外鍵表, 拿到 obj
obj = models.Staff.objects.first()
# 2. obj.基礎表.all(), 拿到 qs
qs = obj.leader.all()
# 3. qs.values_list("查詢字段")
r = qs.values_list("name")
- 基于 obj, 基礎表查詢外鍵表(用法與基于 obj, 外鍵表查基礎表相同)
# 1. 查詢基礎表, 拿到 obj
obj = models.Leader.objects.first()
# 2. obj.基礎表.all(), 拿到 qs
qs = obj.staff.all()
# 3. qs.values_list("查詢字段")
r = qs.values_list("name")
- 基于 QuerySet, 外鍵表查基礎表(通過 to 參數)
# 1. 查詢外鍵表, 拿到 qs
qs = models.Staff.objects.filter(id=1)
# 2. qs.values_list("基礎表__字段")
r = qs.values_list("leader__name")
- 基于 QuerySet, 基礎表查外鍵表(通過 related_name 參數)
# 1. 查詢基礎表, 拿到 qs
qs = models.Leader.objects.filter(id=1)
# 2. qs.values_list("related_name__字段")
r = qs.values_list("yuangong__name")