使用django-polymorphic过滤ContentType ForeignKey

时间:2015-04-17 06:23:51

标签: python django django-models django-admin

我有一堆继承自django-polymorphic的多态模型的Django模型。在另一个模型中,我对ContentType有一个ForeignKey关系,我想限制从特定基类继承的模型。

示例:

from django.db import models
from polymorphic import PolymorphicModel
from django.contrib.contenttypes.models import ContentType

class MagicBaseModel(PolymorphicModel):
    def do_magic(self):
        # ...

class MagicObjectA(MagicBaseModel):
    def do_magic(self):
        super(MagicObjectA, self).do_magic(self)
        # ...

class MagicObjectB(MagicBaseModel):
    def do_magic(self):
        super(MagicObjectB, self).do_magic(self)
        # ...

class NonMagicObject(models.Model):
    # ...

class MagicAction(models.Model):
    magic_object_type = models.ForeignKey(ContentType)
    # ...

在上面的示例中,我想限制MagicAction.magic_object_type,以便只有MagicObjectA和MagicObjectB可供选择。

我尝试使用limit_choices_to这样:

magic_object_type = models.ForeignKey(ContentType, limit_choices_to=Q(polymorphic_ctype=ContentType.objects.get_for_model(MagicBaseModel)))

但是,似乎您无法在模型初始化期间执行该查询,因为ContentType模型还没有准备就绪。

有什么想法可以更好地解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我会尝试以下内容,灵感来自:Choose queryset for limit_choices_to based on object fields

您无法在ForeignKey函数中评估对这两种内容类型的查询,因为db尚未就绪。

因此,您需要使用一个函数,它将在需要时为您提取两个选项。

然后,在该功能中,您可以过滤'模型'内容类型实例的字段。

像这样:

def get_choices():
    query_a = ContentType.objects.filter(
        model=ContentType.objects.get_for_model(MagicObjectA).model)
    query_b = ContentType.objects.filter(
        model=ContentType.objects.get_for_model(MagicObjectB).model)
    return {'magic_object_type': query_a | query_b}

在你的字段声明中你可以参考这个函数,如下所示:

magic_object_type = models.ForeignKey(ContentType, limit_choices_to=get_choices)