【问题标题】:Refer to child class foreign key in base abstract model在基础抽象模型中引用子类外键
【发布时间】:2021-08-17 13:42:07
【问题描述】:

我正在尝试访问基本抽象模型中的子模型外键,因此我不必在每个子模型中重复外键。

这是我的代码:

class BaseModel(models.Model):
    child_field = models.ForeignKey(to='child_class_either_ModelA_OR_ModelB')

    class Meta:
        abstract = True


class ModelA(BaseModel):
    ....

class ModelB(BaseModel):
    ....

我想在基本抽象模型中引用子模型。

有没有办法在基础模型中使用子模型?

【问题讨论】:

  • 我为您的问题添加了一个潜在的答案。它对您有用还是您遇到过任何问题?

标签: python python-3.x django django-models abstract-class


【解决方案1】:

由于抽象 BaseModel 中的字段将是 inherited,那么我们可以通过声明 @987654328 来让 ModelA.child_field 引用自身 (ModelA) 和 ModelB.child_field 引用自身 (ModelB) @ 引用自己作为记录的here

要创建递归关系(与自身具有多对一关系的对象),请使用models.ForeignKey('self', on_delete=models.CASCADE)

class BaseModel(models.Model):
    child_field = models.ForeignKey(to='self', on_delete=models.CASCADE, null=True)

    class Meta:
        abstract = True


class ModelA(BaseModel):
    field_a = models.CharField(max_length=200)


class ModelB(BaseModel):
    field_b = models.CharField(max_length=200)
>>> from my_app.models import *
>>> 
>>> model_a_1 = ModelA.objects.create(field_a="Value 1")
>>> model_a_2 = ModelA.objects.create(field_a="Value 2", child_field=model_a_1)
>>> ModelA.objects.values()
<QuerySet [{'id': 1, 'child_field_id': None, 'field_a': 'Value 1'}, {'id': 2, 'child_field_id': 1, 'field_a': 'Value 2'}]>
>>> 
>>> model_b_3 = ModelB.objects.create(field_b="Value 3")
>>> model_b_4 = ModelB.objects.create(field_b="Value 4", child_field=model_b_3)
>>> ModelB.objects.values()
<QuerySet [{'id': 1, 'child_field_id': None, 'field_b': 'Value 3'}, {'id': 2, 'child_field_id': 1, 'field_b': 'Value 4'}]>

不同子模型之间的交叉引用会失败,例如ModelA 链接到 ModelB

>>> model_a_5 = ModelA.objects.create(field_a="Value 5", child_field=model_b_4)
Traceback (most recent call last):
    raise ValueError(
ValueError: Cannot assign "<ModelB: ModelB object (2)>": "ModelA.child_field" must be a "ModelA" instance.
>>> 
>>> model_b_6 = ModelB.objects.create(field_b="Value 6", child_field=model_a_2)
Traceback (most recent call last):
    raise ValueError(
ValueError: Cannot assign "<ModelA: ModelA object (2)>": "ModelB.child_field" must be a "ModelB" instance.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    相关资源
    最近更新 更多