中级模型中的GenericForeignKeys

时间:2016-09-28 21:09:35

标签: django django-models generic-foreign-key

我试图在' auth.Group'之间创建一个中间模型,权限。以及任何其他定制型号;这将作为权限或对哪些组可见的方式。

我已经能够在' auth.Group'之间创建一个中间模型ExamplePermissions。和一个模特。

    class Example(TimeStampable, Ownable, Model):
        groups = models.ManyToManyField('auth.Group', through='ExamplePermissions', related_name='examples')
        name = models.CharField(max_length=255)
        ...
        # Used for chaining/mixins
        objects = ExampleQuerySet.as_manager()

        def __str__(self):
            return self.name

    class ExamplePermissions(Model):
        example = models.ForeignKey(Example, related_name='group_details')
        group = models.ForeignKey('auth.Group', related_name='example_details')
        write_access = models.BooleanField(default=False)

        def __str__(self):
            return ("{0}'s Example {1}").format(str(self.group), str(self.example))

然而,问题是这反对了可重用性。要创建一个允许任何自定义模型与之关联的模型,我实现了一个GenericForeignKey来代替ForeignKey,如下所示:

    class Dumby(Model):
        groups = models.ManyToManyField('auth.Group', through='core.Permissions', related_name='dumbies')
        name = models.CharField(max_length=255)

        def __str__(self):
            return self.name

    class Permissions(Model):
        # Used to generically relate a model with the group model
        content_type = models.ForeignKey(ContentType, related_name='group_details')
        object_id = models.PositiveIntegerField()
        content_object = GenericForeignKey('content_type', 'object_id')
        #
        group = models.ForeignKey('auth.Group', related_name='content_details')
        write_access = models.BooleanField(default=False)

        def __str__(self):
            return ("{0}'s Content {1}".format(str(self.group), str(self.content_object)))

尝试进行迁移时,会出现以下错误:
core.Permissions:(fields.E336)该模型被模拟用作中间模型.Dumby.groups'但它没有外键到达Dumby'或者' Group'。

乍一看,在中间表中使用GenericForeignKey似乎是一个死胡同。如果是这种情况,除了为每个自定义模型创建自定义中间模型的繁琐冗余方法之外,是否有一些普遍接受的处理这种情况的方法?

1 个答案:

答案 0 :(得分:1)

在中间模型中使用GenericForeignKey时,请勿使用ManyToManyField;相反,使用GenericRelation,因此您的groups字段将简单地声明为:

groups = generic.GenericRelation(Permissions)

有关详细信息,请参阅reverse generic relations