Django的自定義manager和模型方法


# 假設下文中皆以此數據表為基礎

 

# 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()了,你可能接受到一個無用的返回對像,你必須避免這種情況.

 


免責聲明!

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



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