2015-05-28 2 views
0

С такой конфигурацией, как это:Джанго наследования и подкласс атрибуты

class A (models.Model): 
    common_attribute = models.IntegerField() 

class B (A): 
    subclass_attribute = models.IntegerField() 

class C (models.Model) 
    a = ForeignKey(A) 

... если экземпляр C содержит экземпляр B, Django, кажется, рассматривать это как пример А, и я могу» t получить доступ к casubclass_attribute. Есть ли способ обойти это? Я не хочу использовать абстрактное наследование из-за трудностей с ForeignKeys. Я хочу, чтобы C поддерживал любой подкласс A.

ответ

1

Вы можете обойти трудности с ForeignKey, используя django-polymorphic.

Джанго Полиморфные позволяет запрашивать объекты базового класса, но получают экземпляры класса ребенка:

>>> 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"> ] 

Чтобы использовать Джанго полиморфные вам нужно только объявить свои модели с полиморфной моделью в качестве базового класса:

from django.db import models 
from polymorphic import PolymorphicModel 

class ModelA(PolymorphicModel): 
    field1 = models.CharField(max_length=10) 

class ModelB(ModelA): 
    field2 = models.CharField(max_length=10) 

class ModelC(ModelB): 
    field3 = models.CharField(max_length=10) 

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

# The model holding the relation may be any kind of model, polymorphic or not 
class RelatingModel(models.Model): 
    many2many = models.ManyToManyField('ModelA') # ManyToMany relation to a polymorphic model 

>>> o=RelatingModel.objects.create() 
>>> o.many2many.add(ModelA.objects.get(id=1)) 
>>> o.many2many.add(ModelB.objects.get(id=2)) 
>>> o.many2many.add(ModelC.objects.get(id=3)) 

>>> o.many2many.all() 
[ <ModelA: id 1, field1 (CharField)>, 
    <ModelB: id 2, field1 (CharField), field2 (CharField)>, 
    <ModelC: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ] 

Примите во внимание, что эти запросы будут slightly less performant.

Смежные вопросы