子类化models.Manager

San*_*eep 7 python django model django-models

我认为对该models.manager对象get_query_set进行子类化并覆盖该方法或仅在子类中创建一个新方法并使用该方法没有区别.因为我从django书中取了例子;

class MaleManager(models.Manager):
    def get_query_set(self):
        return super(MaleManager, self).get_query_set().filter(sex='M')
class FemaleManager(models.Manager):
    def get_query_set(self):
        return super(FemaleManager, self).get_query_set().filter(sex='F')
class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
    people = models.Manager()
    men = MaleManager()
    women = FemaleManager()
Run Code Online (Sandbox Code Playgroud)

有了这个,我可以用; Person.women.all()或者Person.men.all()取得所有男女模特对象.但是,我想可以实现类似的事情,而不是get_query_set简单地干掉这个方法;

class MaleManager(models.Manager):
    def get_male(self):
        return self.filter(sex='M')
class FemaleManager(models.Manager):
    def get_female(self):
        return  return self.filter(sex='F')
class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
    people = models.Manager()
    men = MaleManager()
    women = FemaleManager()
Run Code Online (Sandbox Code Playgroud)

现在,有了这个,我可以用一点技术来获取所有这些对象; Person.objects.get_male()Person.objects.get_female().但是,在我如何获取对象之间没有任何细微的差别,但在第一种情况下可读性和使用方面存在差异,而第二种情况更易于理解且代码较少.它们在编码和编码方面有一些显着差异.模式?第二个是另一个,如果我将两个方法都放在同一个类中,那该怎么办?

class PeopleManager(models.Manager):
        def get_male(self):
            return self.filter(sex='M')
        def get_female(self):
            return  return self.filter(sex='F')
Run Code Online (Sandbox Code Playgroud)

DrT*_*rsa 3

  1. 通常您不需要模型有多个经理。最好扩展默认管理器。

    class PeopleManager(models.Manager):
        def get_male(self):
            return self.filter(sex='M')
    
        def get_female(self):
            return  return self.filter(sex='F')
    
    class Person(models.Model):
        ....
        objects = PeopleManager()
    
    Run Code Online (Sandbox Code Playgroud)

    然后您将能够使用Person.objects.get_male(),Person.objects.get_female()以及诸如 之类的内置方法Person.objects.order_by()django.contrib.auth.models例如,您可以查看自定义管理器。

  2. get_query_set有利于传承。例如你可以定义

    class SmithManager(PeopleManager):
        def get_queryset(self):
            return super(SmithManager, self).get_query_set().filter(last_name='Smith')
    
    Run Code Online (Sandbox Code Playgroud)

    并且经理的所有方法将仅返回史密斯,(Person.objects.get_male()将仅返回名为史密斯的男性等)。而且您不需要重写所有方法。