更新时间:2023-02-27 13:15:49
在 Django 中无法为抽象模型安装外键.但是,您可以将外键安装到非抽象基类.唯一的限制是反向外键关系将返回基类实例.您可以通过使用 django-polymorphic 来规避此限制.
Django Polymorphic 允许您查询基类对象但检索子类实例:
>>>Project.objects.create(topic="部门党")>>>ArtProject.objects.create(topic="与蒂姆一起绘画",艺术家="T.特纳")>>>ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")>>>项目.objects.all()[ <项目:id 1,主题部门党">,<ArtProject:id 2,主题与蒂姆一起绘画",艺术家T.特纳">,<ResearchProject:id 3,题目燕子空气动力学",主管Dr. Winter">]要使用 django polymorphic,您只需要使用 Polymorphic Model 作为基类声明您的模型:
from django.db 导入模型从 polymorphic.models 导入 PolymorphicModel类模型A(多态模型):field1 = models.CharField(max_length=10)类 ModelB(ModelA):field2 = models.CharField(max_length=10)类 ModelC(ModelB):field3 = models.CharField(max_length=10)
外键也将返回子类实例,我假设这是您需要的:
# 持有关系的模型可以是任何类型的模型,多态或非多态类相关模型(模型.模型):many2many = models.ManyToManyField('ModelA') # ManyToMany 与多态模型的关系>>>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)>]
考虑到这些查询将性能稍低.
I have this model:
class BaseModel(models.Model):
....
class Meta:
abstract = True
class ModelA(BaseModel):
....
class ModelB(BaseModel):
....
class MyExtModel(models.Model)
myfield = models.ForeignKey(BaseModel)
But this is not correct because I have BaseModel
like Abstract
. Infact I have an error when I try makemigration
command.
The error is:
ERRORS:
myapp.MyExtModel.myfield: (fields.E300) Field defines a relation with model 'BaseModel', which is either not installed, or is abstract.
Is there a way to use an abstract base model?
I also tried to use:
myfield = models.ForeignKey(BaseModel, related_name="%(app_label)s_%(class)s_related")
It's not possible to install Foreign Keys to abstract models in Django. You can however install Foreign Keys to a non abstract base class. The only limitation is that the reverse Foreign Key relation will return the base class instances. You can circumvent this limitation by using django-polymorphic.
Django Polymorphic allows you to query the base class objects but retrieves the child class instances:
>>> 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"> ]
To use django polymorphic you only need to declare your models with Polymorphic Model as base class:
from django.db import models
from polymorphic.models 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)
Foreign keys will also return the child class instances, which is what you need I assume:
# 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)> ]
Take into account that these queries will be slightly less performant.