Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django多对多泛型关系_Python_Django_Django Models - Fatal编程技术网

Python Django多对多泛型关系

Python Django多对多泛型关系,python,django,django-models,Python,Django,Django Models,我认为我需要建立一种“多对多通用关系” 我有两类参与者: class MemberParticipant(AbstractParticipant): class Meta: app_label = 'participants' class FriendParticipant(AbstractParticipant): """ Abstract participant common information shared for all rewards.

我认为我需要建立一种“多对多通用关系”

我有两类参与者:

class MemberParticipant(AbstractParticipant):
    class Meta:
        app_label = 'participants'


class FriendParticipant(AbstractParticipant):
    """
    Abstract participant common information shared for all rewards.
    """
    pass
这些参与者可以获得2种不同类型的1个或多个奖励(奖励模式来自另一个应用程序):

所以现在我需要把这些联系起来。这就是我想建立关系的方式(见下文)这行得通吗,你看到了什么问题吗

下面建议的链接模型:

class ParticipantReward(models.Model):


    participant_content_type = models.ForeignKey(ContentType, editable=False,
                                                        related_name='%(app_label)s_%(class)s_as_participant',
                                                        )
    participant_object_id = models.PositiveIntegerField()
    participant = generic.GenericForeignKey('participant_content_type', 'participant_object_id')


    reward_content_type = models.ForeignKey(ContentType, editable=False,
                                                        related_name='%(app_label)s_%(class)s_as_reward',
                                                        )
    reward_object_id = models.PositiveIntegerField()
    reward = generic.GenericForeignKey('reward_content_type', 'reward_object_id')

注意:我使用的是Django 1.6

考虑到您现有的表,您的方法是正确的。虽然没有任何官方消息(2007年涉及核心开发人员,似乎没有去任何地方),但我确实发现这采用了相同的方法(并在第三方库中提供),而且还有一个流行的答案是类似的,只是关系的一方是通用的

我想说,这个功能从未进入django的主干的原因是,虽然这是一个罕见的需求,但使用现有的工具很容易实现。此外,想要定制“直通”表的可能性可能相当高,因此大多数最终用户实现都会涉及一些定制代码

唯一其他可能更简单的方法是建立基本参与者和奖励模型,这些模型之间有很多关系,然后使用这些模型作为成员/朋友等进行扩展


最终,你只需要权衡一个通用关系的复杂性与将对象的数据分布在两个模型之间的复杂性。

回复晚了,但我在寻找实现通用m2m关系的方法时发现了这段对话,我觉得我的2美分对未来的谷歌用户会有所帮助

正如格雷格所说,你选择的方法是一个很好的方法

然而,当您想要使用反向关系或预取等功能时,我不会将通用多对多限定为“使用现有工具易于实现”

第三方应用程序django-genericm2m很不错,但在我看来有几个缺点(默认情况下,“through”对象都在同一个数据库表中,并且您没有“add”/“remove”方法,因此批量添加/删除)


有鉴于此,因为我需要一些东西来实现通用的多对多关系“django方式”,也因为我想了解一点django的内部结构,所以我最近发布了。它有一个与django内置的GenericForeignKey和ManyToManyField非常相似的API(带有预取,通过模型…),并添加了删除行为定制。目前它唯一缺少的是一个合适的django管理界面。

我个人更喜欢使用ForeignKey,而不是GenericForeignKey,以获得ORM提供的额外功能。@schillingt感谢您的回复。奖励可以是单凭证奖励或多凭证奖励,参与者可以是MemberParticipant或FriendParticipant。这意味着如果我选择标准的FK,我需要4个FK,其中两个总是空白的。这对我来说是糟糕的数据库设计,所以我确实认为通用的foreignkey更有意义,但我愿意接受建议。我对你的评论“获得额外功能”很感兴趣。使用GenericForeignKey会有什么损失?你不能再在筛选或排除中使用这些字段了。这一部分的底部提到了。当然,我仍然可以按参与者对象直接搜索参与者?当然可以,这只是稍微复杂一点,因为你必须同时筛选参与者内容类型和参与者对象id,而不是单个对象。谢谢你的回复Greg,您链接的第三方库看起来非常有趣。
class ParticipantReward(models.Model):


    participant_content_type = models.ForeignKey(ContentType, editable=False,
                                                        related_name='%(app_label)s_%(class)s_as_participant',
                                                        )
    participant_object_id = models.PositiveIntegerField()
    participant = generic.GenericForeignKey('participant_content_type', 'participant_object_id')


    reward_content_type = models.ForeignKey(ContentType, editable=False,
                                                        related_name='%(app_label)s_%(class)s_as_reward',
                                                        )
    reward_object_id = models.PositiveIntegerField()
    reward = generic.GenericForeignKey('reward_content_type', 'reward_object_id')