# 假设下文中皆以此数据表为基础

 

# 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()了,你可能接受到一个无用的返回对像,你必须避免这种情况.