首页 > 解决方案 > 这是构建模型的好方法吗?

问题描述

一点点资料。我希望用户能够查看他们的提要,其中包含朋友的帖子、群组帖子等。我正在使用 Django Rest Framework 并将这个提要端点提供给前端。

我最初的想法只是为我需要的每个项目制作单独的模型(表格)。就像UserPost, GroupPost,一样EventPost,但我觉得在尝试合并数据时,它只会进行大量连接,并且必须将数据拼接在一起。

前任)

class UserPost(models.Model): # GroupPost, EventPost
    content = models.TextField(blank=True, default='')
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    # group/event = models.ForeignKey(Group/Event, on_delete=models.CASCADE)

如果我们想为其他模型添加帖子类型功能,这似乎不是一个好方法。


我的另一种方法是使用中间模型。Postmodel 是基础UserPostGroupPost,EventPost是与 post 具有 OneToOne 关系的中间模型,并且与模型具有GroupPost外键 (OneToMany) 关系Group

前任)

class Post(models.Model):
    content = models.TextField(blank=True, default='')
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE)

class UserPost(UUID_PK, models.Model):
    post = models.OneToOneField(
        Post, null=True, blank=True, related_name='_uPost', on_delete=models.CASCADE)


class Group(models.Model):
    name = models.CharField(max_length=64)
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='_groups')
    members = models.ManyToManyField(settings.AUTH_USER_MODEL)

class GroupPost(models.Model):
    post = models.OneToOneField(
        Post, null=True, blank=True, related_name='_gPost', on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)


class Event(models.Model):
    name = models.CharField(max_length=64)
    about = models.TextField(null=True, blank=True)
    event_date = models.DateTimeField(null=True, blank=True)
    invited = models.ManyToManyField(settings.AUTH_USER_MODEL)

    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='_events')

class EventPost(models.Model):
    post = models.OneToOneField(
        Post, null=True, blank=True, related_name='_ePost', on_delete=models.CASCADE)
    event = models.ForeignKey(Event, on_delete=models.CASCADE)

这种方法还不错,但现在确实需要额外的查询。然后模仿获取用户的“提要”,我会像这样过滤

users = # friends
groups = # groups of the user
events = # events of the user

posts = Post.objects.filter(Q(created_by__in=users, _gPost__isnull=True, _ePost__isnull=True) | Q(
        _gPost__group__in=groups) | Q(_ePost__event__in=events)).distinct().select_related('created_by')

# _gPost__isnull=True and _ePost__isnull=True is exclude the other types of post and only get the "normal" posts.

这看起来很糟糕。

我不确定这是否是一个足够好的方法,或者是否有其他人建议改进它。

我确实研究了 GenericRelationship,但不确定这是否真的会让这变得更好。我有一些处理 GenericRelationship 的模型,并且在大多数情况下,有点痛苦。

标签: djangodatabasedjango-modelsdatabase-design

解决方案


推荐阅读