子类化models.Manager

时间:2011-12-27 03:14:39

标签: python django django-models model

我认为对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()

有了这个,我可以用; 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()

现在,有了这个,我可以用一些技巧来获取所有这些对象; 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')

1 个答案:

答案 0 :(得分:4)

  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()
    

    然后,您就可以使用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')
    

    并且经理的所有方法都只返回Smiths,(Person.objects.get_male()只返回名为Smith的男性,依此类推)。而且您不需要重写所有方法。