Как настроить права пользователя django для одного пользователя с несколькими разрешениями? - PullRequest
0 голосов
/ 01 июля 2018

У меня есть следующая идея. Один пользователь может быть в нескольких компаниях. Пользователь имеет разные разрешения в каждой компании, в которой он находится. Приведенный ниже пример не работает, потому что один пользователь всегда будет иметь одинаковые разрешения.

Как мне настроить мою модель пользователя, чтобы один пользователь имел разные разрешения в каждой компании?

Вот что я пробовал до сих пор:

class User(AbstractUser):
    hourly_wage = models.DecimalField(decimal_places=2, max_digits=6, default=8.50)

    class Meta:
        permissions = (("is_general", "Can add people to his company and see everything"),
                       ("is_captain", "Can add/edit/delete everything"),
                       ("is_staff", "Can add/edit/delete jobs"),
                       ("is_programmer", "Can do what he or she wants to do"))

    def clean(self):
        self.username = self.username.lower()


class Company(models.Model):
    name = models.CharField(max_length=80)
    slug = models.SlugField(unique=True)
    users = models.ManyToManyField(User, related_name="companies")

    class Meta:
        verbose_name_plural = "companies"

1 Ответ

0 голосов
/ 01 июля 2018

Вы определяете модель для ManyToManyField, через которую протекает отношение «многие ко многим».

Так что вместо:

+---------+ M      N +-------------+ M      N +------------+
| Company |----------| User        |----------| Permission |
+---------+          +-------------+          +------------+
                     | permissions |
                     +-------------+

Мы пишем это так:

+---------+ 1      N +-------------+ M      1 +------+
| Company |----------| UserCompany |----------| User |
+---------+          +-------------+          +------+
                            | M
                            |
                            | N
                     +------------+
                     | Permission |
                     +------------+

Мы можем сделать это с:

from django.contrib.auth.models import Permission

class User(AbstractUser):

    def clean(self):
        self.username = self.username.lower()


class Company(models.Model):
    name = models.CharField(max_length=80)
    slug = models.SlugField(unique=True)
    users = models.ManyToManyField(User, <b>through='app.CompanyUser'</b>, related_name="companies")

    class Meta:
        verbose_name_plural = "companies"


class <b>CompanyUser</b>(models.Model):

    <b>user = models.ForeignKey('app.User', on_delete=models.CASCADE)</b>
    <b>company = models.ForeignKey('app.Company', on_delete=models.CASCADE)</b>
    <b>hourly_wage = models.DecimalField(decimal_places=2, max_digits=6, default=8.50)</b>
    <b>permissions = models.ManyToManyField(Permission, on_delete=models.CASCADE)</b>

Возможно, вы захотите перенести другую логику в модель с по . Например, hourly_wage, вероятно, также относится к (User, Company) - паре, а не относится к самой User.

Таким образом, вы можете добавить разрешения для UserCompany с помощью:

someusercompany.permissions.add(some_permission)

Затем вы проверяете, есть ли у UserCompany разрешение:

CompanyUser.objects.filter(
    user=some_user,
    company=some_company,
    some_permission=some_permission
).exists()

Подробнее об этом см. В документации о through параметре [django-doc] .

...