概述
Django對各種數據庫提供了很好的支持,Django為這些數據庫提供了統一的調用API,可以根據不同的業務需求選擇不同的數據庫。
- 模型、屬性、表、字段間的關系
一個模型類在數據庫中對應一張表,在模型類中定義的屬性,對應該模型對照表中的一個字段。
- **Object Relational Mapping(ORM)對象-關系-映射** 作用:根據對象的類型生成表結構,將對象、列表的操作轉換為sql語句,將sql語句查詢到的結果轉換為對象、列表,極大的減輕了開發人員的工作量,不需要面對因數據庫的變更而修改代碼。
定義模型
django會為表增加自動增長的主鍵列,每個模型只能有一個主鍵列,如果使用選項設置某屬性為主鍵列后,則django不會再生成默認的主鍵列。
由於django的查詢方式,不允許使用連續的下划線。
定義屬性時,需要字段類型,字段類型被定義在```django.db.models.fields```目錄下,為了方便使用,被導入到```django.db.models```中,定義模型時先導入```from django.db import models```,通過models.Field創建字段類型的對象,賦值給屬性。注意:對於重要數據都做邏輯刪除,不做物理刪除,實現方法是定義isDelete屬性,類型為BooleanField,默認值為False
字段類型
-
AutoField
:一個根據實際ID自動增長的IntegerField,通常不指定如果不指定,一個主鍵字段將自動添加到模型中。 -
CharField(max_length=字符長度)
:字符串,默認的表單樣式是TextInput。 -
TextField
:大文本字段,一般超過4000使用,默認的表單控件是Textarea。 -
IntegerField
:整數 -
DecimalField(max_digits=None, decimal_places=None)
:使用python的Decimal實例表示的十進制浮點數,DecimalField.max_digits
(位數總數),DecimalField.decimal_places
(小數點后的數字位數)。 -
FloatField
:用Python的float實例來表示的浮點數。 -
BooleanField
:true/false 字段,此字段的默認表單控制是CheckboxInput。 -
NullBooleanField
:支持null、true、false三種值。 -
DateField([auto_now=False, auto_now_add=False])
:使用Python的datetime.date實例表示的日期,DateField.auto_now
,每次保存對象時,自動設置該字段為當前時間,用於"最后一次修改"的時間戳,它總是使用當前日期,默認為false,DateField.auto_now_add
,當對象第一次被創建時自動設置當前時間,用於創建的時間戳,它總是使用當前日期,默認為false。
注意:auto_now_add, auto_now, and default 這些設置是相互排斥的,他們之間的任何組合將會發生錯誤的結果
-
TimeField
:使用Python的datetime.time實例表示的時間,參數同DateField。 -
DateTimeField
:使用Python的datetime.datetime實例表示的日期和時間,參數同DateField。 -
FileField
:一個上傳文件的字段。 -
ImageField
:繼承了FileField的所有屬性和方法,但對上傳的對象進行校驗,確保它是個有效的image。
字段參數
說明:通過字段選項,可以實現對字段的約束,在字段對象時通過關鍵字參數指定。
-
null
:如果為True,Django 將空值以NULL 存儲到數據庫中,默認值是 False。 -
blanke
:如果為True,則該字段允許為空白,默認值是 False。
注意:null是數據庫范疇的概念,blank是表單驗證證范疇的。
-
db_column
:字段的名稱,如果未指定,則使用屬性的名稱。 -
db_index
:若值為 True, 則在表中會為此字段創建索引。 -
default
:默認值。 -
primary_key
:若為 True, 則該字段會成為模型的主鍵字段。 -
unique
:如果為 True, 這個字段在表中必須有唯一值。 -
upload_to='article'
:圖片、文件字段的參數,表示文件上傳到某個文件夾。
模型間關系
-
一對一關系 : OneToOneField
class Student(models.Model):
name = models.CharField()
info = OneToOneField(B)
class StudentInfo(models.Model):
tel = models.CharField()
addr = models.CharField()
stu = Student()
meta = StudentInfo()
stu.info # 正向查詢-通過學生查詢信息
meta.student # 反向查詢,通過信息查詢學生
-
一對多關系 : ManyToManyField
class Student(models.Model):
name = models.CharField()
grade = ForeignKey(Grade)
class Grade(models.Model):
gname = models.CharField()
stu = Student()
grade = Grade()
stu.grade # 正向查詢,通過學生查詢班級名
grade.student_set # 反向查詢,通過班級名查詢學生
-
多對多關系 : ManyToManyField
class Student(models.Model):
name = models.CharField()
course = ManyToManyField(Course)
class Curse(models.Model):
cname = models.CharField()
stu = Student()
course = Course()
stu.course_set # 正向 查詢學生選修的課程
course.student_set # 反向 查詢選修課程的學生名
模型元選項
在模型類中定義Meta類,用於設置元信息
class A(models.Model):
pass
class Meta:
db_table = 'a' # 定義數據表名,推薦使用小寫字母,數據表名默認為項目名小寫_類名小寫
ordering = ['id'] # 對象的默認排序字段,獲取對象的列表時使用,'id'-升序,‘-id’降序
模型成員
-
類屬性
-
objects
:是Manager類型的一個對象,作用是與數據庫進行交互,當定義模型類是沒有指定管理器,則Django為模型創建一個名為objects的管理器。
自定義管理器
class Students(models.Model):
# 自定義模型管理器
# 當自定義模型管理器,objects就不存在了
stuObj = models.Manager()
當為模型指定模型管理器,Django就不在為模型類生成objects模型管理器。
- 自定義管理器Manager類
模型管理器是Django的模型進行與數據庫進行交互的接口,一個模型可以有多個模型管理器,作用是向管理器類中添加額外的方法,修改管理器返回的原始查詢集(重寫get_queryset()方法)。
class StudentsManager(models.Manager):
def get_queryset(self):
return super(StudentsManager,self).get_queryset().filter(isDelete=False) # 重寫get_queryset()方法對查詢集進行過濾
class Students(models.Model):
stuObj2 = StudentsManager()
- 創建對象的方法
(1).在模型類中增加一個類方法
class Students(models.Model):
#定義一個類方法創建對象
@classmethod
def createStudnet(cls, name, age, gender, contend, grade, lastT, createT, isD=False):
stu = cls(sname = name, sage = age, sgender = gender, scontend = contend, sgrade = grade, lastTime = lastT, createTime = createT, isDelete=isD)
return stu
# 調用
Students.createStudent()
(2). 在定義管理器中添加一個方法
class StudentsManager(models.Manager):
def get_queryset(self):
return super(StudentsManager,self).get_queryset().filter(isDelete=False)
def createStudnet(self, name, age, gender, contend, grade, lastT, createT, isD=False):
stu = self.model()
# print(type(grade))
stu.sname = name
stu.sage = age
stu.sgender = gender
stu.scontend = contend
stu.sgrade = grade
stu.lastTime = lastT
stu.createTime = createT
return stu
模型查詢
查詢集表示從數據庫獲取的對象集合,查詢集可以有多個過濾器,過濾器就是一個函數,基於所給的參數限制查詢集結果,創建查詢集不會帶來任何數據的訪問,直到調用數據時,才會訪問數據。
創建學生模型
class Student(models.Model):
s_name = models.CharField(max_length=10,unique=True) # 指定學生名唯一
s_age = models.IntegerField() # 學生姓名
s_gender = models.BooleanField(default=True) # 學生性別默認為True
isDelete = models.BooleanField(default=false) # 設置邏輯刪除字段
grade = models.ForeignKey(Grade) # 關聯班級
class Meta:
db_table = 'student' # 指定表名
ordering = ['id'] # 以id排序
def __str(self)__:
return self.s_name # 查詢集的返回顯示學生姓名
class StudentManager(models.Manager):
def get_queryset(self):
return super(StudentsManager,self).get_queryset().filter(isDelete=False) # 自定義模型管理器,重寫父類get_queryset()方法,過濾查詢集
創建班級模型
class Grade(models.Model):
g_name = models.CharField(max_length=10,unique=True) # 創建班級名指定唯一
class Meta:
db_table = 'grade'
ordering = ['id']
def __str(self)__:
return self.g_name
創建課程模型
class Course(models.Model):
c_name = models.CharField(max_length=10) # 課程名
start_date = models.DateField(auto_now_add) # 開課日期
end_date = models.DateField(auto_now_add) # 結束日期
stu = models.ManyToManyField(Student)
class Meta:
db_table = 'course'
ordering = ['start_date']
def __str(self)__:
return self.c_name
創建學生信息模型
class StudentInfo(models.Model):
phone = models.IntegerField() # 手機號
address = models.CharField(max_length=20) # 地址
stu = OneToOneField(Student)
class Meta:
db_table = 'studentinfo'
過濾器
Student.objects.all() # 返回查詢集中的所有數據
Student.objects.filter(pk=3) # 返回符合條件的數據
Student.objects.filter(s_age=20).filter(s_gender=True) # 滿足兩種條件的查詢方式一
Studen.objects.filter(s_age=20,s_gender=False) # 滿足兩種條件的查詢方式二
Studen.objects.exclude(s_name='tom') # 過濾掉符合條件的數據,查詢不滿足條件的其他數據
Studen.objects.order_by('s_age') # 以年齡排序,升序
Studen.objects.order_by('-s_age') # 以年齡排序,降序
Studen.objects.values() # 將所有對象及屬性返回
Studen.objects.values('s_name') # 返回所有對象的名字
-
返回單個數據
Studen.objects.get(pk=1) # 返回一個滿足條件的對象,如果沒有找到符合條件的對象,會引發"模型類.DoesNotExist"異常,如果找到多個對象,會引發"模型類.MultipleObjectsReturned"異常
Studen.objects.filter(s_gender=True).count() # 返回當前查詢集中的對象個數
Studen.objects.filter(s_gender=True).first() # 返回查詢集中的第一個對象
Studen.objects.filter(s_gender=True) # 返回查詢集中的最后一個對象
Studen.objects.filter(s_name='tom').exists() # 判斷查詢集中是否有數據,如果有數據返回True
-
限制查詢集
studentsList = Student.objects.all()[0:5] # 注意:下標不能是負數
查詢集的緩存:在新建的查詢集中,緩存首次為空,第一次對查詢集求值,會發生數據緩存,django會將查詢出來的數據做一個緩存,並返回查詢結構,以后的查詢直接使用查詢集的緩存。
字段查詢
比較運算符
Studen.objects.filter(s_name__contains='王') # 查詢名字包含王的學生,大小寫敏感
Studen.objects.filter(s_name__startswith='孫') # 查詢名字以開頭的學生,大小寫敏感
Studen.objects.filter(s_name__endswith='雨') # 查詢名字以結尾的學生,大小寫敏感
以上四個在前面加上i,就表示不區分大小寫iexact、icontains、istartswith、iendswith
StudenInfo.objects.filter(address isnull) # 查詢地址是空的學生信息
StudenInfo.objects.filter(address isnotnull) # 查詢地址不是空的學生信息
Studen.objects.filter(pk in (2,4,6)) # 查詢pk在(2,4,6)的學生
Studen.objects.filter(s_age__gt=20) # 查詢年齡大於20的學生
Studen.objects.filter(s_age__gte=20) # 查詢年齡大於等於20的學生
Studen.objects.filter(s_age__lt=30) # 查詢年齡小於30的學生
Studen.objects.filter(s_age__lte=30) # 查詢年齡小於等於30的學生
Course.objects.filter(start_date__year=2016) # 查詢開課課程在2016年的課程
Course.objects.filter(start_date__year=2016,start_date__month=10) # 查詢開課課程在2016年10月的課程
# year-month-day-week_day-hour-minute-second
跨關聯查詢
Studen.objects.filter(course__c_name__contains='程序設計') # 查詢課程中帶有程序設計的課程被選擇的學生
聚合函數
使用
aggregate()
函數返回聚合函數的值。使用哪個聚合函數就導入。from django.db.models import Max,Min,Sum,Avg,Count
maxAge = Student.objects.aggregate(Max('s_age'))
minAge = Studen.objects.aggregate(Min('s_age'))
sumAge = Studen.objects.aggregate(Sum('s_age'))
avgAge = Studen.objects.aggregate(Avg('s_age'))
countAge = Studen.objects.aggregate(Count('s_age'))
F對象
可以使用模型的A屬性與B屬性進行比較。
from django.db.models import F
Studen.objects.filter(pk__gte=F('s_age')) # 查詢學生中主鍵大於年齡的學生
Studen.objects.filter(pk__gt=F('s_age')+20) # 查詢學生中主鍵大於年齡加20的學生
Q對象
過濾器的方法中的關鍵字參數,條件為And模式
from django.db.models import Q對象
Studen.objects.filter(Q(pk__lt=5) | Q(s_age__gt=20)) # 查詢主鍵小於5或年齡大於20的學生
Studen.objects.filter(~Q(pk__lt=5)) # 取反,查主鍵大於5的學生。