Django中外键、多对多关系和通用外键的最佳实践

4

我正在尝试在Django中创建一个墙壁,我已经做出了一项重要的设计决策。

我有以下类:

WallPost(墙贴), UserProfile(用户配置文件), Group(组), Event(事件)

问题是我有用户配置文件、活动和群组都会有墙壁可以发布。因此,我不能从发布者的用户模型建立外键关系,因为有多个模型可以发布(除非使用通用键,但我感觉必须有一个所有墙贴的封闭对象,如一个墙壁对象)。

然后我想到了拥有一个中间类型的对象,比如墙壁,墙贴将外键到这个墙壁上,然后用户组和活动将外键到墙壁上。对我来说这也显得效率低下,因为墙壁无需存储任何东西,只是一个封闭对象。

在使用Django中的外键、多对多关系和通用外键时,最佳实践是什么?即如何确定关系的方向?

感谢所有的帮助。


我会使用“墙体对象策略”(Wall object strategy)。它高效且合理。 - Will
这堵墙似乎没有任何数据需要保存,所以看起来有些浪费。 - Mohammed
请您详细说明一下,什么是访问控制? - Mohammed
2
限制用户和/或用户组可以查看、发布、编辑墙上的帖子。将这个逻辑和数据放在墙上可能是有意义的。一般来说,墙可能会开始轻量级,但我的直觉告诉我你最终会很高兴你把它分开,因为你可能会想把逻辑和/或数据放在那里。 - Will
是的,我认为你说得对。我确信在我的初始设计中有些事情我没有考虑到。我打算创建一个包含墙对象的方案。 - Mohammed
1个回答

2
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)

我会这样做。

你不需要在个人资料上留言,因为群组和活动也可以有留言墙。 - Will
@Vadym 我想避免为每种类型创建一个墙,因为更通用的设计似乎更优雅,并且将来扩展会更简单。 - Mohammed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接