bennylope / django-organizations

:couple: Multi-user accounts for Django projects

Home Page:http://django-organizations.readthedocs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple Organizations

steverecio opened this issue · comments

I read the documentation on using multiple organizations but I'm getting an error introducing the second organization. How do I link users to the second organization? I want the ability to create a team and then additionally create user groups underneath that structure. The rationale is an organization invites their employees to the platform and then can organize them into groups who can share information.

When running the migration to add the Group model I get the following error: teams.TeamMember: (fields.E336) The model is used as an intermediate model by 'teams.Group.users', but it does not have a foreign key to 'Group' or 'User'.

See models below:

from functools import partial
from django.db import models
from organizations.utils import create_organization
from organizations.abstract import (AbstractOrganization,
                                    AbstractOrganizationUser,
                                    AbstractOrganizationOwner)


class Team(AbstractOrganization):
    """
    Root model for team structure
    """
    @classmethod
    def create_team(cls, *args, **kwargs):
        func = partial(create_organization, model=cls)
        return func(*args, **kwargs)

    @property
    def team_members(self):
        return self.organization_users


class TeamMember(AbstractOrganizationUser):
    """
    An individual on a team
    """
    @property
    def team(self):
        return self.organization


class TeamAdmin(AbstractOrganizationOwner):
    """
    The administrator for a team
    """
    @property
    def team(self):
        return self.organization

    @property
    def team_member(self):
        return self.organization_user


class Group(AbstractOrganization):
    """
    Root model for user groups
    """

    team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='team')

    @classmethod
    def create_group(cls, *args, **kwargs):
        func = partial(create_organization, model=cls)
        return func(*args, **kwargs)

    @property
    def group_members(self):
        return self.organization_users

Are these all in the same app?

Yeah I have a SaaS platform built on django and these models are all in a django app called teams. Is there a reason I would need to separate the parent orgs and user groups into separate django apps?

Yep, it's a limitation of how the abstract metaclasses work.

Unlike in the example of multi-table inheritance, you cannot add more than one custom organization model to an individual app. Each additional organization class you want must be defined in its own app. Only one organization set per app. (from a note buried in the docs).

You have a couple of options:

  1. Create a separate app for the sub groups (for the Group functionality)
  2. Create the Group related models using a different strategy than the AbstractOrganization class

I'd give consideration to the first option regardless of how you approach this, for the reasons above and for general architectural concerns. If you're not interested in using other features like view mixins and invitations for the Groups, you could use a simple model with a ForeignKey to your main Team model and a ManyToMany field linking to your TeamMember model.

Ok yeah I missed that note about one org per app. I built my own invitations app because it didn't work very easily with my SPA / DRF setup. I'll have to think about the pros / cons of the two approaches. I think I only really need a simple ManyToMany field but it may still make sense to split out user groups into its own app from an organizational perspective.