Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to design organization-specific models in Django?

This is a database model design question. Let's say I'm designing an app like Slack. Slack has multiple Organizations, and within each Organization there are objects that only should be accessed by that Organization (eg. its chat records, files, etc.). What is the best way to set up these per-Organization objects in Django?

A simple solution is to attach a ForeignKey to every one of these objects. Like so:

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,
    )
    # ...

But if we do it like this, we need to put an index on organization, and since there are many such per-Organization objects, it seems a little wasteful.

Is there a cleaner way to design this?

like image 356
foobar Avatar asked Mar 17 '18 16:03

foobar


People also ask

How do you define models in Django?

To define a many-to-one relationship, use django.db.models.ForeignKey . You use it just like any other Field type: by including it as a class attribute of your model. ForeignKey requires a positional argument: the class to which the model is related.

What is a model in Django How does it make data management easier?

In Django, the model is the object mapped to the database. When you create a model, Django executes SQL to create a corresponding table in the database (Figure 4-2) without you having to write a single line of SQL. Django prefixes the table name with the name of your Django application.

Should Django models be plural?

Always name your models using singular. Call it Company instead of Companies . A model definition is the representation of a single object (the object in this example is a company), and not a collection of companies.


1 Answers

I think your method is about as good as it would need to be. In terms of indexing the organization column, you can use db_index=False to disable the creation of an index.

If you want to abstract the organization field and have some methods available on all organization objects, you could use an abstract model like so:

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):
    # ...
like image 193
A. J. Parr Avatar answered Sep 28 '22 08:09

A. J. Parr