天天看點

Django 之 ORM表結構單表多表 – ForeignKey多表 – ManyToManyField

文章目錄

  • 表結構
    • 字段類型
    • 參數限制
  • 單表
    • 表結構
    • 資料的操作
  • 多表 -- 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")
    
               

繼續閱讀