一對一Model ,有外鍵即設定關聯關系的一方為從表,從表查主表為正向查詢,反之。這裡護照為從表,人為主表。
class Passport(models.Model): # 護照(從表)
note = models.CharField(max_length=20)
person = models.OneToOneField(to="Person",on_delete=models.CASCADE,null=True) #關系屬性
class Meta:
db_table="t_passport"
class Person(models.Model): # 人(主表)
name = models.CharField(max_length=20)
age = models.IntegerField()
class Meta:
db_table="t_person"
注:不需要手動設定 person字段唯一,自動會設定為唯一
一對一 一個人一本護照
# 1.隻查 單方資料 (與單表資料查詢一緻)
# 隻查人的資訊
ps = Person.objects.filter(name='Tom').values() # 自己查自己
print(ps)
# 隻查 護照的資訊
p1 = Passport.objects.all().values()
print(p1)
ps = Person.objects.filter(passport='1').values()
print(ps)
# 2.通過一方查另一方資料 (先擷取一方資料,再通過它查詢另一方)
# 查詢 名字為tom的護照資訊
p1 = Person.objects.get(name='Tom')
print(p1.passport.note) #反向查詢 基于對象 類名小寫
# 查詢護照為美國的人的資訊
ps = Passport.objects.get(note='美國')
print(ps.per_id, ps.per.name,ps.per.age) #正向查詢 基于對象 直接調用外鍵
# 3.通過一方 查另一方 (查詢條件是對方)
# 查詢名字為tom的護照資訊
p1 = Passport.objects.filter(per__name='Tom').values() #正向查詢 基于字段 外鍵__字段
print(p1)
# 查詢護照為美國的人的資訊
p1 = Person.objects.filter(passport__note='美國').values() #反向查詢 基于字段 類小寫__字段
print(p1)
print(Person.objects.filter(passport__note='美國')) # QuerySet集合對象
# 4.保留雙方資料 ()
# 查詢名字為Tom的人資訊 和 護照的資訊
p1 = Person.objects.filter(name='Tom').values('name','age','passport__note') #反向查詢 基于字段 類小寫__字段
print(p1)
p1 = Passport.objects.filter(per__name='Tom').values('note','per__name','per__age','per_id') #正向查詢 基于字段 外鍵__字段
print(p1)
一對一查詢總結:
正向查詢時,基于對象,對象.直接調用外鍵;基于字段 外鍵__字段
反向查詢時,基于對象,對象.類名小寫;基于字段 類小寫__字段
感覺從表和主表查起來差不多。
一對多Model 貨物為從表,種類為主表
class Category(models.Model): #種類(主表)
title = models.CharField(max_length=20)
note = models.CharField(max_length=20)
class Meta:
db_table="t_category"
class Goods(models.Model): #貨物(從表)
title = models.CharField(max_length=20,unique=True)
price = models.FloatField()
cate = models.ForeignKey(to=Category,on_delete=models.CASCADE) #關系屬性 主表删除後,從表中使用主表中資料的也會跟随一起删除
class Meta:
db_table = "t_goods"
# 1對多關系 Category(1):沒有關系屬性 Goods(*):其中有關系屬性cate
# 一對多 查詢 category主表 goods從表
# 1.隻查詢一方資料
# 隻查 主表
c1 = Category.objects.filter(name='服裝').values()
print(c1)
g1 = Goods.objects.filter(price=5000).values()
print(g1)
# 2.通過一方查詢另一方 (先查詢到一方資料,再通過它查詢另一方)
# 查詢服裝類别為男裝的 商品名稱
c1 = Category.objects.get(name='服裝')
print(c1.goods_set) # 查詢也是一個集合 #反向查詢 基于對象 對象.表名_set
print(c1.goods_set.all()) # 查詢也是一個集合
# 查詢 商品沙發所屬的類别
g1 = Goods.objects.get(title='沙發')
print(g1.cate.name, g1.cate.note) #正向查詢 基于對象 對象.外鍵.字段
# 3.通過一方查詢另一方(查詢條件是另一方)
# 查詢 床 商品的 類别資訊
c1 = Category.objects.filter(goods__title='床').values() #反向查詢 基于字段 表名__字段
print(c1)
# 查詢分類為 家居 類别的 商品資訊
g1 = Goods.objects.filter(cate__name='家居').values() #正向查詢 基于字段 外鍵__字段
print(g1)
# 4.保留雙方資料
# 查詢商品名稱為 電視 的分類資訊 和 商品資訊
c1 = Category.objects.filter(goods__title='電視').values('name','note','goods__title','goods__price') #反向查詢 基于字段 表名__字段
print(c1)
# 查詢商品價格大于5000的商品的分類資訊
c1 = Category.objects.filter(goods__price__gt=5000) #反向查詢 基于字段 表名__字段
print(c1)
print(set(c1))
#注意在進行聯合查詢時,可能會由重複資料出現,解決:
list(set(Category.objects.filter(goods__price__gt=200)))
一對多總結:
正向查詢時,基于對象,對象.外鍵.字段;基于字段,外鍵__字段
反向查詢時,基于對象,對象.表名_set;基于字段,表名__字段
多對多Model
class Student(models.Model): #學生(主表)
name = models.CharField(max_length=20)
age = models.IntegerField()
class Meta:
db_table="t_student"
class Course(models.Model): #課程(從表)
title = models.CharField(max_length=30)
expire = models.SmallIntegerField()
stu = models.ManyToManyField(to=Student) #關系屬性
class Meta:
db_table="t_course"
# 多對多關系 Course:有對方關系屬性students, Student:沒有對方關系屬性
# 1.隻查詢一方
# 查詢學生 linda 學生資訊
s1 = Student.objects.filter(name='Linda').values()
print(s1)
# 查詢mysql課程資訊
c1 = Course.objects.filter(title__icontains='MYSQL').values()
print(c1)
# 2.查詢一方,通過它查詢另一方
# 查詢 學習mysql的學生資訊
c1 = Course.objects.get(title='DJANGO')
print(c1.stu.all()) #正向查詢 基于對象 對象.外鍵
# 查詢 學生 linda 課程資訊
s1 = Student.objects.get(name='Linda')
print(s1.course_set.all()) #反向查詢 基于對象 對象.表名_set
print(s1.course_set.values())
# 3.通過一方 查詢 另一方 (查詢條件為對方)
# 查詢 學生 linda 課程資訊
c1 = Course.objects.filter(stu__name='Linda').values() #正向查詢 基于字段 外鍵__字段
print(c1)
# 查詢 學習mysql的學生資訊
s1 = Student.objects.filter(course__title='PYTHON').values() #反向查詢 基于字段 表名__字段
print(s1)
# 4.保留雙方資料
# 查詢學習django的學生資訊 和 課程資訊
s1 = Student.objects.filter(course__title='DJANGO').values('name','age','course__title','course__expire') #反向查詢 基于字段 表名__字段
print(s1)
# 查詢jack學習的課程資訊 和 學生資訊
c1 = Course.objects.filter(stu__name='Jack').values('title','expire','stu__age','stu__name') #正向查詢 基于字段 外鍵__字段
print(c1)
#關聯查詢
Student.objects.filter(course__title__contains="h") #标題中含有"h"的課程中的學生 #反向查詢 基于字段 表名__字段
Course.objects.filter(stu__name="zzz") #姓名為zzz的學生參加的課程 #正向查詢 基于字段 外鍵__字段
Course.objects.filter(stu__age__gt=18) #年齡大于18的學生參加的課程 #正向查詢 基于字段 外鍵__字段
坑:不能查具體某個字段
多對多總結:
正向查詢時,基于對象,對象.外鍵;基于字段,外鍵__字段
反向查詢時,基于對象,對象.表名_set;基于字段,表名__字段
最後3個總結寫在一起比較:
一對一查詢總結:
正向查詢時,基于對象,對象.直接調用外鍵;基于字段 外鍵__字段
反向查詢時,基于對象,對象.類名小寫;基于字段 類小寫__字段
一對多總結:
正向查詢時,基于對象,對象.外鍵.字段;基于字段,外鍵__字段
反向查詢時,基于對象,對象.表名_set;基于字段,表名__字段
多對多總結:
正向查詢時,基于對象,對象.外鍵;基于字段,外鍵__字段
反向查詢時,基于對象,對象.表名_set;基于字段,表名__字段
最後總結,
基于對象的情況下,正向查詢時基本一緻,直接調用外鍵就好;反向查詢時一對多和多對多,需要對象.表名_set調用。
基于字段的情況下,正向查詢時,外鍵__字段;反向查詢時,表名__字段。一對一可能為類名小寫__字段。