Django中的内置和自定义模型管理器
Django manager是一个作为接口的类,Django模型通过它与数据库交互。每个模型至少有一个管理器对象。它有很多的方法、属性,以方便与数据库的工作。事实上,许多初级的Django开发者不知道他们使用Manager类对象来提取或创建所需的模型对象/对象。Django在模型中提供的默认Manager对象是” objects “。
语法 :
要使用Django的默认管理器对象,你必须遵循以下语法
model_name.objects.method
这里的 “objects “是Django默认创建的管理器对象。
一个基本的例子:
假设我们有一个名为医院的模型类–
class Hospital(models.Model):
name = models.CharField(max_length=50)
city = models.CharField(max_length=30)
def __str__(self):
return self.name
但它还没有在数据库中创建任何对象。它只创建了一个带有医院对象结构的空表。为了在数据库中创建这些对象,我们需要使用默认的Django管理器对象(因为我们没有建立任何自定义的管理器)–
Hospital.objects.create(name='AIIMS',city ='Delhi')
创建 “方法创建了一个新的对象。它需要模型类所需要的字段值。在上面的代码行中,我们通过调用’create’方法创建了一个医院对象,该方法需要字段值作为参数。
给默认管理器起一个自定义的名字 :
有时需要给默认管理器一个自定义的名字。要做到这一点,你必须定义一个类属性或models.Manager()类型的字段。这里有一个例子 –
class Student(models.Model):
...
students = models.Manager() //now the default manager is named as students
此后,对学生数据库表的所有操作都必须使用 “学生 “管理器来完成。
Student.students.filter(...) // here students manager is used
任何使用 “对象 “作为该类的管理器的努力都会导致出现错误。
经理类的方法:
经理对象有许多内置的方法来简化对数据库的操作。这里描述了一些最常用的方法 –
all() | 返回一个包含迄今为止创建的所有对象的查询集。 |
---|---|
filter(**kwargs) |
返回一个包含与给定参数相匹配的对象列表的查询集。如果没有找到匹配的对象,它将返回一个空的查询集。 |
exclude(**kwargs) |
它的作用与filter()方法正好相反,即返回一个包含与给定参数不匹配的对象的查询集。 |
get(**kwargs) |
返回一个与给定参数匹配的单一对象。如果找到多个对象,它将抛出一个Model.MultipleObjectsReturned错误。如果get()没有找到任何对象,它会引发一个Model.DoesNotExist异常。 |
create(**kwargs) |
用给定的参数创建一个新的对象。 |
order_by(*fields) |
根据传入的参数设置先前返回的queryset的顺序。 |
代码:
下面这个例子使用了python shell 命令。
>>> h1 = Hospital.objects.create(name="Calcutta Medical",city="kolkata")
>>> h2 = Hospital.objects.create(name="dummy",city="Chennai") #creating objects using create() and save all these new objects into database
>>> h3 = Hospital.objects.create(name="TATA cancer Hospital",city="Mumbai")
>>> h4 = Hospital.objects.create(name="AIIMS Delhi",city="Delhi")
>>> h5 = Hospital.objects.create(name='NRS hospital",city="kolkata")
...
>>> Hospital.objects.filter(city='kolkata') # returns queryset of objects whose city attribute is 'kolkata'
<QuerySet [<Hospital: Calcutta Medical>, <Hospital: NRS hospital>]>
>>> Hospital.objects.get(city='Delhi')
<Hospital: AIIMS Delhi>
>>> Hospital.objects.get(city='kolkata') # raise error as there are multiple objects
这些是最流行的方法。然而,这种方法的数量是巨大的。你可以查看django文档以获得完整的参考。
创建自定义管理器 :
有时你可能希望django管理器以某种方式工作,而默认的管理器却没有。在这种情况下,你可以创建你自己的自定义管理器。这个过程很简单。你必须创建一个继承于Manager类的类。下面是一个例子
例子:
让我们来谈谈医院模型。 我们正在创建一个名为CustomManager的自定义管理器,它与默认的django管理器相似,除了一点。 当我们调用CustomManager对象的all()方法时,我们将不会得到所有的对象。相反,我们将得到所有那些城市=’加尔各答’的对象 –
class CustomManager(models.Manager):
'''first we get all objects from the database by
calling the get_queryset method of the inherited class
i.e. Manager class using super().get_queryset().
After that we are filtering objects having city attribute equal to kolkata
and return the filtered objects'''
get_queryset(self):
return super().get_queryset().filter(city= 'kolkata')
每个管理器类都有一个get_queryset方法。它被用来根据它的参数属性来获取对象的查询集。如果没有提供参数,它将返回所有的对象。在这个例子中,我们通过继承Manager类并只重写get_queryset方法来创建一个自定义的Django管理器。
所以我们已经定义了一个自定义管理器。
class Hospital(models.Model):
name = models.CharField(max_length=50)
city = models.CharField(max_length=30)
objects = models.Manager() # our default django manager
kolkata_hospitals = CustomManager() # creating our custom manager object
def __str__(self):
return self.name
医院模型有两个经理对象。现在,如果我们调用Hospital.objects.all(),我们得到所有的医院对象。但是当我们调用Hospital.kolkata_hospitals.all()时,我们将只得到那些城市为kolkata的对象。
注意,如果你在同一个模型中使用多个经理对象,那么你需要注意定义经理对象的顺序。第一个定义的经理对象将被视为默认经理对象。例如 – 在上面的例子中,”objects “是默认的管理器,因为它是最先定义的。Django在一些内部流程中使用默认管理器。所以,要小心选择你的默认管理器,否则你可能会得到一些意外的结果。如果你想让一个管理器成为默认管理器,而该管理器对象并没有被首先定义,那么你可以通过设置Meta类的default_manager_name等于该对象的名称来将其定义为默认管理器。
class Hospital(models.Models):
...
class Meta:
default_manager_name = 'kolkata_hospitals' # default manager is now kolkata_hospitals not objects
你可以用自定义管理器做任何你想做的事情。你可以定义一个新的方法来修改数据库中的一些数据,或者返回一些东西。不一定每个管理器方法都要返回一个查询集。事实上,你可以定义不返回任何东西的方法。
如果你想了解更多,请查看Django关于管理器的官方文档 – https://docs.djangoproject.com/en/3.0/topics/db/managers/