Вы пытаетесь реализовать постоянство для иерархии наследования. Использование одного конкретного стола и переключателя type
- хороший способ сделать это. Однако я думаю, что ваша реализация, а именно:
for animal in animals:
if (animal.type == "cat"):
animal_proxy = # make me a cat
идет против зерна Джанго. Тип включения не должен быть посторонним для прокси (или модели) класса.
На вашем месте я бы сделал следующее:
Во-первых, добавьте менеджер с учетом типов к моделям прокси. Это гарантирует, что Dog.objects
всегда будет извлекать Animal
экземпляров с type="dog"
, а Cat.objects
будет извлекать Animal
экземпляров с type="cat"
.
class TypeAwareManager(models.Manager):
def __init__(self, type, *args, **kwargs):
super(TypeAwareManager, self).__init__(*args, **kwargs)
self.type = type
def get_query_set(self):
return super(TypeAwareManager, self).get_query_set().filter(
type = self.type)
class Dog(Animal):
objects = TypeAwareManager('dog')
...
class Cat(Animal):
objects = TypeAwareManager('cat')
...
Во-вторых, извлекать экземпляры подкласса отдельно. Затем вы можете объединить их, прежде чем работать с ними. Я использовал itertools.chain
, чтобы объединить два Querysets
.
from itertools import chain
q1 = Cat.objects.all() # [<Cat: Daisy [cat]>]
q2 = Dog.objects.all() # [<Dog: Bruno [dog]>]
for each in chain(q1, q2):
each.make_noise()
# Meow Meow
# Woof Woof