Django中外键,多对多和GenericForeignKey的最佳实践

时间:2012-08-07 16:06:19

标签: python django facebook facebook-wall

我正试图在Django做一堵墙,我做出了一个重要的设计决定。

我有以下课程:

WallPost, 用户资料, 组, 事件

问题是我有用户个人资料,事件和组,所有人都有可以发布的墙。因此,我无法与发布到模型的用户建立外键关系,因为有多个模型可以发布(除非我使用通用密钥,但我觉得所有的墙贴都必须有一些外壳像墙上的物体)。

然后,我想到了一个中间类型的对象,如墙壁上的墙壁就是外键,然后用户组和事件就会出现在墙上。这对我来说似乎效率低下,因为墙壁没有任何东西可以存储,而且只是一个封闭物体。

在django中使用ForeignKeys和ManyToManyFields以及GenericForeignKeys时的最佳做法是什么?至于你怎么知道这种关系应该走哪条路?

感谢您的所有输入。

1 个答案:

答案 0 :(得分:1)

class WallPost(models.Model):
    text = models.TextField()

class UserProfile(models.Model):
    name = models.CharField(max_length=128)
    wall_posts = models.ManyToManyField(WallPost, through='UserWall')

class UserWall(models.Model):
    profile = models.ForeignKey(UserProfile)
    post = models.ForeignKey(WallPost)

#same for groups
class Group(models.Model):
    name = models.CharField(max_length=128)
    wall_posts = models.ManyToManyField(WallPost, through='GroupWall')

class GroupWall(models.Model):
    group = models.ForeignKey(Group)
    post = models.ForeignKey(WallPost)

UserWall.objects.filter(profile_id=profile.id).select_related('post')
GroupWall.objects.filter(group_id=group.id).select_related('post')

#or
group = Group.objects.get(id=1).select_related('wall_posts')
posts = group.wall_posts.all()

class Wall(models.Model):
    TYPE = (
        (0, 'User'),
        (1, 'Group'),
        (2, 'Event'),
    )

    source = IntegerField() #id of user/group/event
    source_type = SmallIntegerField(choices=TYPE)


class WallPost(models.Model):
    text = models.TextField()
    wall = models.ForeignKey(Wall)

我会这样做的。