簡體   English   中英

與Django中的抽象模型相關的ForeignKey字段

[英]ForeignKey field related to abstract model in Django

我有這個型號:

class BaseModel(models.Model):
    ....

    class Meta:
        abstract = True


class ModelA(BaseModel):
    ....

class ModelB(BaseModel):
    ....


class MyExtModel(models.Model)
    myfield = models.ForeignKey(BaseModel)

但這不正確,因為我有像Abstract BaseModel 事實上,當我嘗試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")

在Django中無法將外鍵安裝到抽象模型中。 但是,您可以將外鍵安裝到非抽象基類。 唯一的限制是反向外鍵關系將返回基類實例。 您可以使用django-polymorphic來規避此限制。

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

要使用django polymorphic,您只需要將具有Polymorphic Model的模型聲明為基類:

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)

外鍵也將返回子類實例,這是我需要的假設:

# 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)> ]

考慮到這些查詢的性能稍差

當我遇到像我必須使用不同模型的ForeignKeys的情況時,我選擇使用GenericForeignKey你可以在這里查看官方文檔: Django ContentTypes:Generic Relations

文檔很好地解釋了如何使用它:

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_type存儲通用外鍵指向的模型

  • 字段object_id存儲外鍵的ID,

  • 字段content_object可幫助您根據其他2個字段直接訪問相關對象

它不是最好的解決方案,但它可以節省我的一些項目

使用它的例子:

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>

除了GenericForeignKey的好回答,我不熟悉,有時候(有時候,只要有可能),通過與“基礎”模型使用一對一關系來簡化模型是值得的。

之后使外鍵管理更容易。 如果我記得很清楚,抽象類上的外鍵是不可能的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM