使用場景
一對一:在某表中創建一行數據時,有一個單選的下拉框(下拉框中的內容被用過一次就消失了)。//兩個表的數據一一對應例如:原有含10列數據的一張表保存相關信息,經過一段時間之后,10列無法滿足需求,需要為原來的表再添加5列數據。一對多:當一張表中創建一行數據時,有一個單選的下拉框(可以被重復選擇)。//表1的數據可以在表2里面重復出現例如:創建用戶信息時候,需要選擇一個用戶類型【普通用戶】【金牌用戶】【鉑金用戶】等。多對多:在某表中創建一行數據是,有一個可以多選的下拉框。//表1和表2都可以在各自的表項里重復出現例如:創建用戶信息,需要為用戶指定多個愛好。
Customer模型:
class Customer(models.Model):
name = models.CharField(max_length=32)
qq = models.CharField(max_length=64,unique=True)
weixin = models.CharField(max_length=64,blank=True,null=True)
age = models.PositiveSmallIntegerField(blank=True,null=True)
referral_from = models.ForeignKey("Customer",related_name="my_referrals",
blank=True,null=True,verbose_name="轉介紹",on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True) #auto_now_add自動增加
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "客戶信息表"
verbose_name = "客戶信息表"
----------------------------------------------------------
Enrollment模型:
class Enrollment(models.Model):
"""學員報名信息"""
customer = models.ForeignKey("Customer",on_delete=models.CASCADE,related_name='entries')
class_grade = models.ForeignKey("ClassList",on_delete=models.CASCADE)
enrollment_date = models.DateField()
def __str__(self):
#return self.customer
class Meta:
unique_together = ("customer","class_grade")
---------------------------------------------------------------------------
FollowUpRecord模型
class FollowUpRecord(models.Model):
customer = models.ForeignKey("Customer",on_delete=models.CASCADE)
content = models.TextField(max_length=1024)
def __str__(self):
return "%s" % self.customer
----------------------------------------------------------------------------
ClassList模型:
class ClassList(models.Model):
semester = models.PositiveSmallIntegerField(verbose_name="學期")
class_type_choices = ((0,'脫產'),(1,'周末'),(2,'網絡'))
start_date = models.DateField()
end_date = models.DateField()
-----------------------------------------------------------------------------------------------------------
一、單表查詢
增
models.Tb1.objects.create(c1='xx', c2='oo')
增加一條數據,可以接受字典類型數據 **kwargs
obj = models.Tb1(c1='xx', c2='oo') obj.save()
查
models.Tb1.objects.get(id=123)
獲取個數
models.Tb1.objects.filter(name='seven').count()
大於,小於
models.Tb1.objects.filter(id__gt=1) # 獲取id大於1的值
models.Tb1.objects.filter(id__gte=1) # 獲取id大於等於1的值
models.Tb1.objects.filter(id__lt=10) # 獲取id小於10的值
models.Tb1.objects.filter(id__lte=10) # 獲取id小於10的值
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 獲取id大於1 且 小於10的值
in
models.Tb1.objects.filter(id__in=[11, 22, 33]) # 獲取id等於11、22、33的數據
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
isnull
Entry.objects.filter(pub_date__isnull=True)
contains
models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小寫不敏感
models.Tb1.objects.exclude(name__icontains="ven")
range
models.Tb1.objects.filter(id__range=[1, 2]) # 范圍bettwen and
其他類似
startswith,istartswith, endswith, iendswith,
order by
models.Tb1.objects.filter(name='seven').order_by('id') # asc
models.Tb1.objects.filter(name='seven').order_by('-id') # desc
group by--annotate
from django.db.models import Count, Min, Max, Sum
models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
limit 、offset
models.Tb1.objects.all()[10:20]
regex正則匹配,iregex 不區分大小寫
Entry.objects.get(title__regex=r'^(An?|The) +')
Entry.objects.get(title__iregex=r'^(an?|the) +')
date
Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
year
Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__year__gte=2005)
month
Entry.objects.filter(pub_date__month=12)
Entry.objects.filter(pub_date__month__gte=6)
day
Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__day__gte=3)
week_day
Entry.objects.filter(pub_date__week_day=2)
Entry.objects.filter(pub_date__week_day__gte=2)
hour
Event.objects.filter(timestamp__hour=23)
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12)
minute
Event.objects.filter(timestamp__minute=29)
Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29)
second
Event.objects.filter(timestamp__second=31)
Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31)
三、一對多 使用ForeignKey查詢
約束 節省硬盤 但是多表查詢會降低速度,大型程序反而不使用外鍵,而是用單表(約束的時候,通過代碼判斷)
正向查詢
關系模型Enrollment包含關聯模型Customer的ForeignKey, 模型Enrollment的實例可以通過關聯字段訪問Customer實例:
查:
>>> e = Enrollment.objects.get(id=2) #注意:此處不能用e =Enrollment.objects.filter(id=2)
>>> e.customer # 通過上查詢到的e對象,關聯字段( e.customer )訪問到Customer實例
改
e.customer並調用save方法存入數據庫
>>> e.customer= some_customer
>>> e.save()
如果ForeignKey 字段有null=True 設置(即它允許NULL值),可以分配None來刪除對應的關聯性
>>> e.customer= null
>>> e.save()
反向查詢
已經得到模型Customer的實例,需要查詢該以該實例為外鍵的相關模型(如FollowUpRecord和Enrollment),可以使用查詢集API取出相應的實例。
related_name的相關模型:FollowUpRecord
>>> customer = models.ForeignKey("Customer",on_delete=models.CASCADE)
反查找使用 模型類名小寫_set.all() ,方法如下:
>>> c = Customer.objects.get(id=1)
>>> c.followuprecord_set.all()
related_name的相關模型:FollowUpRecord
customer = models.ForeignKey("Customer",on_delete=models.CASCADE,related_name='entries')
反查找不能使用 模型類名小寫_set.all(),需要使用related_name的值,方法如下:
>>> c = Customer.objects.get(id=1)
>>> c.entries.all()
三、多對多 ManyToMany
class UserGroup(models.Model):
caption = models.CharField(max_length=64)
user_info = models.ManyToManyField('UserInfo')
def __unicode__(self):
return self.caption
user_info_obj = models.UserInfo.objects.get(name='alisa')
user_info_objs = models.UserInfo.objects.all()
group_obj = models.UserGroup.objects.get(caption='CEO')
group_objs = models.UserGroup.objects.all()
# 添加數據
#group_obj.user_info.add(user_info_obj)
group_obj.user_info.add(*user_info_objs)
#例:1,2,3分別代表user_info.的主鍵id
group_obj.user_info.add(1,2,3)
group_obj.user_info.add([1,2,3])
# 刪除數據
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)
#例:1,2,3分別代表user_info.的主鍵id
group_obj.user_info.remove(1,2,3)
group_obj.user_info.remove([1,2,3])
# 反向添加數據
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)
# 反向刪除數據
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)
# 獲取數據
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)
#反向 獲取數據
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CEO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')
