且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

与Django中抽象模型相关的ForeignKey字段

更新时间:2023-02-27 13:20:41

将外键安装到Django中的抽象模型。
但是,您可以将外键安装到非抽象基类。唯一的限制是反向外键关系将返回基类实例。
您可以使用 django-polymorphic 来规避此限制。

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允许您查询基类对象但检索子类实例:

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

要使用django多态,只需要声明以Polymorphic Model作为基类的模型即可。

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.