我希望能够组合来自不同Abstract类的不同自定义管理器函数的复杂查询。
我的模特是这样的:
class GenderManager(models.Manager):
def male(self):
return self.filter(gender="M")
def female(self):
return self.filter(gender="F")
class SpeciesManager(models.Manager):
def lion(self):
return self.filter(species="L")
def tiger(self):
return self.filter(species="T")
class GenderModel(models.Model):
gender = models.CharField(max_length=1)
objects = GenderManager()
class Meta:
abstract = True
class SpeciesModel(models.Model):
species = models.CharField(max_length=1)
objects = SpeciesManager()
class Meta:
abstract = True
class Animal(GenderModel,SpeciesModel):
name = models.CharField(max_length=30)
age = models.DecimalField(max_digits=4, decimal_places=2)
我想分割性别和物种的原因是,在我的模型中,有时我只需要从GenderModel继承,有时只需要从SpeciesModel继承。
在我想继承表单的情况下(比如在Animal类中),我希望能够进行这样的查询:
Animal.objects.male().tiger().filter(age__gte = 10.00)
但它不起作用。
但是,如果我不使用自定义管理器功能,它可以工作:
Animal.objects.filter(gender="M").filter(species="T").filter(age__gte = 10.00)
如何使其与自定义管理器功能一起使用,确实让它变干?
谢谢!
答案 0 :(得分:1)
由于Managers实际工作的方式无法做到这一点,但可以采用不同的方法来重构模型和逻辑,具体取决于复杂性以及模型实际需要的独立性。
由于您的经理实际上是需要具体类而不是抽象类,因此将两个管理器合并为一个管理器,毕竟您是在过滤具体类而不是抽象。
class GenderModel(models.Model):
gender = models.CharField(max_length=1)
class Meta:
abstract = True
class SpeciesModel(models.Model):
species = models.CharField(max_length=1)
class Meta:
abstract = True
class AnimalManager(models.Manager):
def gender(self):
return self.filter(gender="M")
def female(self):
return self.filter(gender="F")
def lion(self):
return self.filter(species="L")
def tiger(self):
return self.filter(species="T")
def get_male_tigers(self):
return self.filter(species="T").filter(gender="M").all()
class Animal(GenderModel,SpeciesModel):
name = models.CharField(max_length=30)
age = models.DecimalField(max_digits=4, decimal_places=2)
objects = AnimalManager()
然后:
animals = Animal.objects.get_male_tigers()
当然,您可以进一步重构您的需求
答案 1 :(得分:0)
objects
不能同时引用GenderManager
和SpeciesManager
。鉴于MRO的工作原理,在您的示例中,它是SpeciesManager
实例。
您可以创建第三个经理:
class AnimalManager(GenderManager, SpeciesManager):
def male_and_tiger(self):
return self.male & self.tiger()
[all other combinations here]
class Animal(GenderModel,SpeciesModel):
[...]
objects = AnimalManager()
但是我真的认为你被OOP继承恶魔所拥有了:)对orm的简单调用更好,更有前途证明(除非你想每次都为你的SpeciesManager
添加新方法添加新物种)