python - 在 Django 中,是否可以为某个父类(super class)定义外键,但在查询时返回了子类?

标签 python django inheritance django-models django-model-utils

假设我有以下模型:

class SomeSuperClass(models.Model):
    ...

class SomeSubClassA(SomeSuperClass)
    ...

class SomeSubClassB(SomeSuperClass)
    ...

class SomeConnector(models.Model):
    reference = models.ForeignKey(SomeSuperClass, on_delete=models.CASCADE)
    ...

现在我想要的是以某种方式遍历 SomeConnector 的对象时,我总是希望立即拥有相应子类的对象,而不是父类(super class)的对象。例如

for sc in SomeConnector.objects.all():

    # somehow get the correct subclass of this `reference` field here,
    # assuming it to be callable under sc.reference_correct_subclass:
    print(sc.reference_correct_subclass.__class__.__name__)

可以产生例如:

'SomeSubClassA'
'SomeSubClassB'
'SomeSubClassA'
'SomeSubClassA'

但是永远不应该使用父类(super class)的对象。

我知道django-model-utils我可以通过直接查询父类(super class)来做一些类似的事情,就像这样:

SomeSuperClass.objects_inheritance.select_subclasses()

其中 objects_inheritance 是附加到 SomeSuperClassInheritanceManager。但是,当父类(super class)用作我想用于查询的另一个类中的外键时,我还不知道如何重现这一点。

最佳答案

我可以通过将 ForeignKey 字段与一个额外的子类 ForwardManyToOneDescriptor 子类化来让它工作,正如我在 this thread 中找到的那样.

这个子类的代码是这样的:

from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor

class InheritanceForwardManyToOneDescriptor(ForwardManyToOneDescriptor):
    def get_queryset(self, **hints):
        return self.field.remote_field.model.objects_inheritance.db_manager(hints=hints).select_subclasses()


class InheritanceForeignKey(models.ForeignKey):
    forward_related_accessor_class = InheritanceForwardManyToOneDescriptor

要在我的代码示例中使用它,那么它将像这样集成:

class SomeConnector(models.Model):
    reference = InheritanceForeignKey(SomeSuperClass, on_delete=models.CASCADE)

关于python - 在 Django 中,是否可以为某个父类(super class)定义外键,但在查询时返回了子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64026839/

相关文章:

python - 如何在不调整其内容大小的情况下使 SVG 图像的视口(viewport)变为正方形?

Python套接字: WinError 10022

Scala注解继承

c++ - 不完整类型 --> 无法从我的对象访问指针值

ruby - 我如何调用祖 parent 的方法,并在 ruby​​ 中跳过 parent

python - 我如何每分钟自动将一个新的 csv 文件从我的本地电脑导入到谷歌表格?

python - for/in 循环构造是否保留顺序?

django - 流式 HTTP 响应,刷新到浏览器

python - 在 Django 管理中搜索时出错

html - 通过邮件发送动态 html 文件