How to model data for to add feature that allow inviting a user to a team within an application

class Category(models.Model):
    id = models.CharField(
        _("id"),
        max_length=40,
        default=uuid.uuid4,
        unique=True,
        primary_key=True,
    )
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, unique=True, blank=True, null=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = "categories"

    def __str__(self) -> str:
        return f"{self.name}"


class Permission(models.Model):
    id = models.CharField(
        _("id"),
        max_length=40,
        default=uuid.uuid4,
        unique=True,
        primary_key=True,
    )
    name = models.CharField(max_length=100, blank=True, null=True, unique=True)
    slug = models.CharField(max_length=100, unique=True, blank=True, null=True)
    category = models.ForeignKey(Category, related_name='permissions', on_delete=models.CASCADE, blank=True, null=True)
    
    def __str__(self):
        return f"{self.category} | {self.name}"


class Role(models.Model):
    id = models.CharField(
        _("id"),
        max_length=40,
        default=uuid.uuid4,
        unique=True,
        primary_key=True,
    )
    name = models.CharField(max_length=50, blank=True, null=True)
    description = models.CharField(max_length=255, blank=True, null=True)
    permission = models.ManyToManyField(Permission, related_name="role", blank=True, null=True) 
    
    def __str__(self):
        return f"{self.name}"


class Account(models.Model):
    id = models.CharField(
        _("id"),
        max_length=40,
        default=uuid.uuid4,
        unique=True,
        primary_key=True,
    )
    user = models.OneToOneField(User, on_delete=models.SET_NULL, related_name="account", blank=True, null=True)

    def __str__(self):
        return f"{self.id} -  {self.user}"


class Member(models.Model):
    id = models.CharField(
        _("id"),
        max_length=40,
        default=uuid.uuid4,
        unique=True,
        primary_key=True,
    )
    user = models.ForeignKey(User, on_delete=models.SET_NULL, related_name="member", blank=True, null=True)
    role = models.ForeignKey(Role, on_delete=models.SET_NULL, related_name="member_role", null=True, blank=True)

    def __str__(self):
        return f"{self.id} - {self.user} - {self.role}"
    

class Team(models.Model):
    id = models.CharField(
        _("id"),
        max_length=40,
        default=uuid.uuid4,
        unique=True,
        primary_key=True,
    )
    # role = models.CharField(blank=True, null=True, max_length=50)
    member =  models.ManyToManyField(Member)
    account = models.OneToOneField(Account, on_delete=models.SET_NULL, related_name="account_team", blank=True, null=True)

    def __str__(self):
        return f"{self.id}, a/c: {self.account.id}"

Pls need help with these as i see a lot duplication on users roles on account and member tables. Is it the right thing to do.
My use case, i want to be able to invite users to join a team and have a role attached to them. so that on login they are able to see the list of account or businesses they are attached to. pls need help with this.

Can you be more specific as to what you mean by:

Also, it might be easier to figure out with a more precise statement of your models and your relationships.

What I’m understanding you to describe here is that:

  • A User is assigned to some number of Role.

  • Each Role is assigned to some number of Permission

  • The assignment of a User to a Role is identified as a Member

  • A Member is assigned to some number of Team

    • Or, looking at it from the other direction, a Team consists of some number of Member
  • A Team is also associated with an Account, which is associated with a User

    • (Perhaps this is someone who manages that Account?)

Side note - Your Member model is the through table of a many-to-many relationship between User and Role. If you’re not needing additional data on Member, you can get rid of that model and directly define the ManyToMany field between User and Role.

This was helpful. Thanks