📜  Django 中的内置和自定义模型管理器

📅  最后修改于: 2022-05-13 01:54:21.236000             🧑  作者: Mango

Django 中的内置和自定义模型管理器

Django 管理器是一个类,它充当 Django 模型与数据库交互的接口。每个模型至少有一个管理器对象。它有很多方法和属性来简化数据库的工作。事实上,许多初级 Django 开发人员并不知道他们使用 Manager 类对象来提取或创建所需的模型对象。 Django 在模型中提供的默认 Manager 对象是“对象”。

句法 :

要使用 Django 默认管理器对象,您必须遵循以下语法 –

model_name.objects.method

这里的“对象”是 Django 默认创建的管理器对象。

一个基本示例:



假设我们有一个名为Hospital的模型类——

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' 方法创建一个新对象。它采用模型类想要的字段值。在上面的代码行中,我们通过调用将字段值作为参数的“create”方法创建了一个医院对象。

默认管理器提供自定义名称

有时需要为默认管理器提供自定义名称。为此,您必须定义一个类属性或类型为 models.Manager() 的字段。这是一个例子——

class Student(models.Model):
    ...
    students = models.Manager() //now the default manager is named as students

之后,所有对student数据库表的操作都必须使用“students”管理器来完成——

Student.students.filter(...) // here students manager is used

使用“对象”作为此类的管理器的任何努力都将导致错误。

Manager 类的方法:



管理器对象有许多内置方法来简化对数据库的操作。这里描述了一些最流行的方法——

all()returns a query set containing all objects created so far 
filter(**kwargs)returns a query set containing a list of objects that match with the given arguments. If no matched object is found, it returns an empty query set. 
exclude(**kwargs)it does exactly the opposite of filter() method i.e. returns a queryset containing objects that does not match with given arguments.
get(**kwargs)returns a single object that match with given argument. If multiple objects found it will throw an Model.MultipleObjectsReturned  error. If get() doesn’t find any object, it raises a Model.DoesNotExist exception. 
create(**kwargs)create a new object with given arguments.
order_by(*fields)sets the ordering of the previously returned queryset according to the arguments passed in it.

例子 :

以下示例使用Python命令外壳。

>>> 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'
, ]>
>>> Hospital.objects.get(city='Delhi')

>>> Hospital.objects.get(city='kolkata') # raise error as there are multiple objects

这些是最流行的方法。然而,这种方法的数量是巨大的。您可以查看 django 文档以获取完整参考。

创建自定义管理器:

有时您可能希望 django 管理器以默认管理器不具备的某种方式工作。在这种情况下,您可以制作自己的自定义管理器。程序很简单。您必须创建一个继承自 Manager 类的类。这是一个例子——

例子 :

让我们谈谈医院模式。我们正在创建一个名为 CustomManager 的自定义管理器,它类似于默认的 django 管理器,除了一件事。当我们调用 CustomManager 对象的 all() 方法时,我们不会获取所有对象。相反,我们将获得所有具有 city = 'kolkata' 的对象 –

Python3
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')


Python3
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


每个管理器类都有一个 get_queryset 方法。它用于根据它作为参数的属性获取对象的查询集。如果没有提供参数,那么它将返回所有对象。在此示例中,我们通过继承 Manager 类并仅覆盖 get_queryset 方法来创建自定义 django 管理器。

所以我们定义了一个自定义管理器。现在我们要做的就是将这个管理器与医院模型联系起来——

蟒蛇3

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 关于 manager 的官方文档 – https://docs.djangoproject.com/en/3.0/topics/db/managers/