在Django中设计组织特定模型的最佳方式是什么?

6
这是一个数据库模型设计问题。假设我正在设计一个类似于Slack的应用程序。Slack有多个组织,在每个组织中,只有该组织才能访问某些对象(例如聊天记录、文件等)。在Django中,设置这些按组织分配的对象的最佳方法是什么?
一种简单的解决方案是为每个对象附加一个外键。像这样:
class Organization(models.Model):
    # ...

class File(models.Model):
    organization = models.ForeignKey(
        'Organization',
        on_delete=models.CASCADE,
    )
    # ...

class ChatThread(models.Model):
    organization = models.ForeignKey(
        'Organization',
        on_delete=models.CASCADE,
    )
    # ...

但是如果我们这样做,我们需要在organization上加上索引,由于有很多这样的每个组织对象,这似乎有点浪费。

是否有更清晰的设计方式?


你为什么认为这是浪费的?在某个层面上,你希望将文件与某个组织相关联,并使用ForeignKey/ManyToMany来关联它们是我能想到的最好的方法。 - sgauri
4个回答

6

我认为你的方法已经足够好了。如果要对组织列进行索引,您可以使用db_index=False来禁用索引的创建。

如果您想抽象出组织字段并在所有组织对象上提供一些方法,您可以使用抽象模型,如下所示:

class Organization(models.Model):
    # ...

class OrganizationModel(models.Model):
    organization = models.ForeignKey(
        'Organization',
        on_delete=models.CASCADE,
        db_index=False,
    )

    class Meta:
        abstract = True

class File(OrganizationModel):
    # ...

class ChatThread(OrganizationModel):
    # ...

3
您的方法很好,如果每个组织都可以共享相同的文件,则应使用models.ManyToManyField,但我怀疑Slack是否像这样工作。
此外,使用Slack,您可以从任何地方访问文件,但您共享的每个文件并不总是可以在每个线程上发布。
您所提供的模型结构似乎是实现您想要的最佳方式,如果每个组织中都有人使用您的应用程序,则可能需要为每个人设计一个新模型。
以下是我会选择的内容:
class Organization(models.Model):
    # ...

#each person is part of an organization
class Person(models.Model):
    organization = models.ForeignKey('Organization', on_delete=models.CASCADE)
    # ...

#each file is part of an organization
class File(models.Model):
    organization = models.ForeignKey('Organization', on_delete=models.CASCADE)
# ...

#each thread is part an Organization
#each thread can have many users, each user can join many thread.
#each thread can have many files, each file can be shared across one or many thread
class ChatThread(models.Model):
    organization = models.ForeignKey('Organization',  on_delete=models.CASCADE)
    people = models.ManyToManyField(Person, ...)
    files = models.ManyToManyField(File, ...)
    # ...

0

我不确定这一点,但如果你正在设计一个像Slack这样的应用程序,我认为你需要使用租户来设计它,例如:customer.domain.com,这样更好地组织信息。

在你的基本组织中,你可以像这个例子一样做:

# The Organization Model
class Organization(models.Model):
  # ...

#each person is part of an organization
class Person(models.Model):
  organization = models.ForeignKey('Organization', on_delete=models.CASCADE)
  # ...

#each file is part of an organization
class File(models.Model):
  organization = models.ForeignKey('Organization', on_delete=models.CASCADE)
  # ...

#each thread is part an Organization
#each thread can have many users, each user can join many thread.
#each thread can have many files, each file can be shared across one or many thread
class ChatThread(models.Model):
  organization = models.ForeignKey('Organization',  on_delete=models.CASCADE)
  people = models.ManyToManyField(Person, ...)
  files = models.ManyToManyField(File, ...)
  # ...

0

对我来说,真正的问题是:

你的文件模型是否总是需要组织? 聊天线程模型也是同样的问题吗?

如果不是,那么你就不应该使用ForeignKey,而应该使用ManyToManyField。 这样你就可以避免模型之间的依赖关系。

否则,你的模型是正确的。


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