Python Django中与抽象模型相关的外键字段
我有这个模型:Python Django中与抽象模型相关的外键字段,python,django,foreign-keys,abstract,Python,Django,Foreign Keys,Abstract,我有这个模型: class BaseModel(models.Model): .... class Meta: abstract = True class ModelA(BaseModel): .... class ModelB(BaseModel): .... class MyExtModel(models.Model) myfield = models.ForeignKey(BaseModel) 但这是不正确的,因为我有B
class BaseModel(models.Model):
....
class Meta:
abstract = True
class ModelA(BaseModel):
....
class ModelB(BaseModel):
....
class MyExtModel(models.Model)
myfield = models.ForeignKey(BaseModel)
但这是不正确的,因为我有BaseModel
像Abstract
。实际上,我在尝试makemigration
命令时出错
错误是:
ERRORS:
myapp.MyExtModel.myfield: (fields.E300) Field defines a relation with model 'BaseModel', which is either not installed, or is abstract.
有没有一种方法可以使用抽象的基础模型
我还尝试使用:
myfield = models.ForeignKey(BaseModel, related_name="%(app_label)s_%(class)s_related")
当我面临这样的情况时,我必须为不同的型号制作外键,我选择使用
GenericForeignKey
您可以在这里查看官方文档:
这些文档很好地解释了如何使用它:
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class TaggedItem(models.Model):
tag = models.SlugField()
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
def __str__(self): # __unicode__ on Python 2
return self.tag
- 字段content\u type存储通用外键指向的模型
- 字段对象\u id存储外键的id
- 字段content\u object帮助您基于其他两个字段直接访问相关对象
from django.contrib.auth.models import User
guido = User.objects.get(username='Guido')
t = TaggedItem(content_object=guido, tag='bdfl')
t.save()
t.content_object
<User: Guido>
来自django.contrib.auth.models导入用户
guido=User.objects.get(username='guido')
t=TaggedItem(content\u object=guido,tag='bdfl')
t、 保存()
t、 内容对象
除了我不太熟悉的GenericForeignKey
的不错答案之外,有时候(只是有时候,只要可能),通过使用与“基本”模型的一对一关系来简化模型是值得的
使外键管理更容易。如果我记得清楚的话,抽象类上的外键是不可能的。在Django中不可能为抽象模型安装外键。 但是,您可以将外键安装到非抽象基类。唯一的限制是反向外键关系将返回基类实例。 您可以通过使用来规避此限制 Django多态允许您查询基类对象,但检索子类实例:
>>> 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"> ]
外键还将返回子类实例,我假定这是您需要的:
# 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)> ]
#持有关系的模型可以是任何类型的模型,多态或非多态
类关系模型(models.Model):
many2many=models.ManyToManyField('ModelA')#与多态模型的manytomy关系
>>>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()
[ ,
,
]
考虑到这些查询将被删除。我不知道多态模型……这可能会对我有所帮助。我不了解一个方面:多态模型是基于泛型关联的吗?什么时候需要使用GenericRelation(内容类型)而不是PolymorphicModel?可能这个问题超出了我最初问题的上下文……泛型关系与多态模型无关。泛型关系对于应用程序中的泛型模型类型非常有用,并且具有基本不同模型的外键。我的应用程序中有一个通用的图像模型,事件和团队模型都可以有图像。这是一种通用关系。我还有一个从团队继承的InternationalTeam模型,然后团队也会有图像,而无需在模型中明确指定。
# 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)> ]