# 假設下文中皆以此數據表為基礎
# models.py
Class Student(models.Model): """學生表""" name = models.CharField(max_length=200) sex= models.CharField(max_length=200) birth= models.DateField(blank = False)
1.Django中通常由objects(模型自帶的manager)與模型層models進行交互。
(1)students = Student.objects.filter(name__icontains = '行')
# 這里我們使用默認的管理器objects完成對學生的篩選。
2.每個模型都至少有一個manager,我們可以創建自定義的manager來定制數據庫的訪問。(1.添加額外的manager,2.修改manager返回的queryset)
(1)添加額外的manager
增加額外的manager是為模塊添加表級功能的首選辦法.(至於行級功能,也就是只作用於模型實例對象的函數,則通過自定義模型方法實現)
例如:為Student模型添加一個返回 gt_age_students()的方法,可以接收一個日期參數,返回生日大於該參數的學生。
# models.py
Class Student(models.Model): """學生表""" name = models.CharField(max_length=200) sex= models.CharField(max_length=200) birth= models.DateField(blank = False)
objects = StudentManager()
class StudentManager(models.Manager):
def gt_age_students(self,birth):
return self.filter(birgh__lte = birth)
1.創建一個StudentManager類繼承自django.db.models.Manager,創建的StudentManager管理器只有一個gt_age_students()方法,用於返回大於某生日大於該日期的學生。方法中第一個參數為self,這個self指代manager自身。
2.將StudentManager方法賦值給Student模型中的objects屬性,它將取代模型原有的manager(objects),將它命名為objects是為了與默認的manager保持一致。
>>> Students.objects.gt_age_students('2019/10/1') #這是我們自定義的manager中的查詢方法 <Student object(1)><Student object(2)>
>>> Studentss.objects.filter(birth__gt='2019/10/1') # 默認的查詢方法依然可用
<Student object(1)><Student object(2)>
這樣就可以將經常使用的查詢進行封裝,減少代碼的重復量。
(2)修改原有的manager
manager的基礎Queryset返回系統中的所有對象,例如Students.objects.all()返回Student數據表中的所有學生,而你可以通過覆蓋Manager.get_queryset()
方法來重寫manager的基礎Queryset.get_queryset()
應該按照你的需求返回一個Queryset.
例如,下面的模型有兩個manager,一個返回所有對象,一個僅僅返回名稱包含David的學生。
from django.db import models # 首先,定義一個Manager的子類 class DavidManager(models.Manager): def get_queryset(self): return super(DavidManager, self).get_queryset().filter(name__contains = ' David') # 然后,將它插入Student模型中
Class Student(models.Model): """學生表""" name = models.CharField(max_length=200) sex= models.CharField(max_length=200) birth= models.DateField(blank = False)
objects = models.Manager() # 默認的manager
david_objects = DavidManager() # 自定義的特殊manager
在這個示例模型中,Student.objects.all()
將返回數據庫中的所有學生,而Student.david_objects.all()
只返回名字包含David的學生.注意我們明確的將objects
設置為默認Manager的一個實例,因為如果我們不這樣做,那么david_objects將成為唯一一個可用的manager.
由於get_queryset()
返回一個Queryset對象,所以你可以使用filter()
,exclude()
和其他所有的Queryset方法.
如果你使用自定義的Manager對象,請注意,Django遇到的第一個Manager(以它在模型中被定義的位置為准)會有一個特殊狀態。 Django將會把第一個Manager 定義為默認Manager ,Django的許多部分(但是不包括admin應用)將會明確地為模型使用這個manager。 結論是,你應該小心地選擇你的默認manager。因為覆蓋get_queryset()
了,你可能接受到一個無用的返回對像,你必須避免這種情況.