Django模型Model的定義



概述


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的學生。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM