对象创建根据基本模型字段分配代理 class
Object creation assigns proxy class based on base model field(s)
我希望能够使用基础模型创建一个对象,但实际上将该对象创建为代理class,具体取决于对象的字段。
例如,对于以下型号:
class Animal(models.Model):
species = models.CharField()
class Cat(Animal):
class Meta:
proxy = True
class Dog(Animal):
class Meta:
proxy = True
如何设置才能
cat = Animal.objects.create(species="cat")
dog = Animal.objects.create(species="dog")
Animal.objects.all() # Returns queryset of [cat, dog]
Cat.objects.all() # Returns queryset of [cat]
Dog.objects.all() # Returns queryset of [dog]
编辑:
我会对这两种解决方案感兴趣:
a) 首先将对象创建为 Animal
然后转换为代理 class 然后
b)对象直接创建为代理class
(不幸的是,解决方案类型 A 可能与我的用例最相关)
您应该为每个代理创建一个 custom manager。
class Animal(models.Model):
species = models.CharField()
class CatManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(species='cat')
class DogManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(species='dog')
class Cat(Animal):
objects = CatManager()
class Meta:
proxy = True
class Dog(Animal):
objects = DogManager()
class Meta:
proxy = True
根据物种定义custom manager for Animal
which will filter the queryset。在这里,我们将使用 class 名称作为物种名称的基础。
class AnimalManager(models.Manager):
def get_queryset(self):
if self.model is Animal:
return super().get_queryset()
return super().get_queryset().filter(species=self.model.__name__.casefold())
class Animal(models.Model):
objects = AnimalManager()
species = models.CharField(max_length=100)
class Cat(Animal):
class Meta:
proxy = True
class Dog(Animal):
class Meta:
proxy = True
输出
>>> from my_app.models import *
>>>
>>> # Create the animals
>>> Animal.objects.create(species="cat")
<Animal: Animal object (1)>
>>> Animal.objects.create(species="dog")
<Animal: Animal object (2)>
>>> Animal.objects.create(species="cat")
<Animal: Animal object (3)>
>>> Animal.objects.create(species="cat")
<Animal: Animal object (4)>
>>> Animal.objects.create(species="dog")
<Animal: Animal object (5)>
>>>
>>> # Query the animals
>>> Animal.objects.all()
<QuerySet [<Animal: Animal object (1)>, <Animal: Animal object (2)>, <Animal: Animal object (3)>, <Animal: Animal object (4)>, <Animal: Animal object (5)>]>
>>> Cat.objects.all()
<QuerySet [<Cat: Cat object (1)>, <Cat: Cat object (3)>, <Cat: Cat object (4)>]>
>>> Dog.objects.all()
<QuerySet [<Dog: Dog object (2)>, <Dog: Dog object (5)>]>
我希望能够使用基础模型创建一个对象,但实际上将该对象创建为代理class,具体取决于对象的字段。
例如,对于以下型号:
class Animal(models.Model):
species = models.CharField()
class Cat(Animal):
class Meta:
proxy = True
class Dog(Animal):
class Meta:
proxy = True
如何设置才能
cat = Animal.objects.create(species="cat")
dog = Animal.objects.create(species="dog")
Animal.objects.all() # Returns queryset of [cat, dog]
Cat.objects.all() # Returns queryset of [cat]
Dog.objects.all() # Returns queryset of [dog]
编辑: 我会对这两种解决方案感兴趣:
a) 首先将对象创建为 Animal
然后转换为代理 class 然后
b)对象直接创建为代理class
(不幸的是,解决方案类型 A 可能与我的用例最相关)
您应该为每个代理创建一个 custom manager。
class Animal(models.Model):
species = models.CharField()
class CatManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(species='cat')
class DogManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(species='dog')
class Cat(Animal):
objects = CatManager()
class Meta:
proxy = True
class Dog(Animal):
objects = DogManager()
class Meta:
proxy = True
根据物种定义custom manager for Animal
which will filter the queryset。在这里,我们将使用 class 名称作为物种名称的基础。
class AnimalManager(models.Manager):
def get_queryset(self):
if self.model is Animal:
return super().get_queryset()
return super().get_queryset().filter(species=self.model.__name__.casefold())
class Animal(models.Model):
objects = AnimalManager()
species = models.CharField(max_length=100)
class Cat(Animal):
class Meta:
proxy = True
class Dog(Animal):
class Meta:
proxy = True
输出
>>> from my_app.models import *
>>>
>>> # Create the animals
>>> Animal.objects.create(species="cat")
<Animal: Animal object (1)>
>>> Animal.objects.create(species="dog")
<Animal: Animal object (2)>
>>> Animal.objects.create(species="cat")
<Animal: Animal object (3)>
>>> Animal.objects.create(species="cat")
<Animal: Animal object (4)>
>>> Animal.objects.create(species="dog")
<Animal: Animal object (5)>
>>>
>>> # Query the animals
>>> Animal.objects.all()
<QuerySet [<Animal: Animal object (1)>, <Animal: Animal object (2)>, <Animal: Animal object (3)>, <Animal: Animal object (4)>, <Animal: Animal object (5)>]>
>>> Cat.objects.all()
<QuerySet [<Cat: Cat object (1)>, <Cat: Cat object (3)>, <Cat: Cat object (4)>]>
>>> Dog.objects.all()
<QuerySet [<Dog: Dog object (2)>, <Dog: Dog object (5)>]>