2013-09-11 4 views
5
class Animal(models.Model): 
    .... 
    class Meta: 
     abstract = True 

class Cat(models.Model, Animal): 
    ... 

class Dog(models.Model, Animal): 
    .... 

Я хочу, чтобы иметь возможность возвращать все экземпляры запросов всех подклассов Animal. Допустим, у меня есть функция, называемая allData, которая возвращает массив/список всех наборов запросов подклассов.Доступ к подклассам Django из абстрактного класса

Например:

x = animal.allData()[0] # should return the first element in the array. 

Я не против того, как мы делаем это, используя модули, такие как django-model-utils или нет. Я просто хочу, чтобы вернуть все подзадачи запросов.

+2

Обратите внимание, что ни один из ответов здесь не отражает тот факт, что это абстрактная базовая модель. Ответы предполагают конкретную базовую модель. –

ответ

13

Это невозможно в одном запросе. У вас есть два варианта: один используется для использования django-model-utils или вы можете использовать django_polymorphic.

Полиморфный лучше подходит для вашей задачи, однако django-model-utils сделан видным членом сообщества django и, как таковой, имеет много хорошей поддержки.

Если бы мне пришлось выбирать, я бы выбрал django-model-utils с момента его создания членом команды django и, следовательно, будет поддерживаться. Полиморфизм поддерживается divio, который является частной компанией, которая активно использует django в Швейцарии.

Как выбрать подклассы. Вам нужно сделать две вещи, используя django-model-utils. Во-первых, вам нужно изменить переменную objects в вашей модели InheritanceManager() как так (взято из документации):

from model_utils.managers import InheritanceManager 

class Place(models.Model): 
    # ... 
    objects = InheritanceManager() 

class Restaurant(Place): 
    # ... 

class Bar(Place): 
    # ... 

nearby_places = Place.objects.filter(location='here').select_subclasses() 
for place in nearby_places: 
    # "place" will automatically be an instance of Place, Restaurant, or Bar 

Код выше возвращает все Bar с и Restaurant потому, что он использует select_subclasses.

2

Вы могли бы быть заинтересованы в django_polymorphic

Пример из документации проекта:

Когда мы храним модели, которые наследуют от Project модели ...

>>> Project.objects.create(topic="Department Party") 
>>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner") 
>>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter") 

... и хотите получить все наши проекты, подклассы моделей возвращаются:

>>> Project.objects.all() 
[ <Project:   id 1, topic "Department Party">, 
    <ArtProject:  id 2, topic "Painting with Tim", artist "T. Turner">, 
    <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ] 
Смежные вопросы