中间模型中的 GenericForeignKeys

GenericForeignKeys in Intermediate Models

我正在尝试创建介于 '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) 该模型被'simulations.Dumby.groups'用作中间模型,但它没有'Dumby'或'Group'的外键。

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

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

groups = generic.GenericRelation(Permissions)

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