Таблица разрешений доступа к данным? - PullRequest
0 голосов
/ 09 июля 2020

Просто нужна помощь, чтобы перелезть через стену, на которую я наткнулся.

У меня есть веб-приложение, которому при каждой регистрации пользователя назначается лицензия. К этой лицензии прикреплены CustomPermissions, сообщающие, к каким значениям поля в материализованном представлении они имеют доступ. У меня есть API, который должен фильтровать данные, запрашиваемые пользователем, который запросил их, на основе лицензии пользователя. Ниже я нарисовал несколько примеров моделей, в которых изложена моя проблема.

class CustomPermission(models.Model):
    name = models.CharField(max_length=255)
    field = models.CharField(max_length=255)
    value = models.CharField(max_length=255)

class License(models.Model):
    name = models.CharField(max_length=255)
    permissions = models.ManyToManyField(CustomPermissions)
    ...

class User(AbstractBaseUser):
    license = models.ForeignKey(License, on_delete=models.CASCADE)
    ...

Это отлично работает, если я фильтрую только столбцы с текстовыми значениями. Я могу просто сделать

...
user = request.user
permissions = user.license.permissions.values_list('field', 'value')
return queryset.objects.filter(**{field: value for field, value in permissions})

Эта проблема заключается в том, что я не могу фильтровать по другим типам данных (например, по дате). Например, если бы я хотел ограничить доступ к данным, опубликованным за последние 90 дней, это невозможно представить в этой модели.

Чтобы решить эту проблему, я подумал об использовании разреженной таблицы для модели CustomPermission. Что-то вроде

class CustomPermission(models.Model):
    name = models.CharField(max_length=255)
    field = models.CharField(max_length=255)
    operation = models.CharField(max_length='32')
    text_value = models.CharField(max_length=255, null=True, blank=True)
    date_value = models.DateField(null=True, blank=True)

Где операция равна '__gt', '__lt', ... et c, text_value - текстовое значение, а date_value - date_value. Затем я бы сделал что-то похожее на приведенное выше с

...
user = request.user
permissions = user.license.permissions.values_list('field', 'operation', 'text_value', 'date_value')
return queryset.objects.filter(**{fld+op: txt_val or dat_val for fld, op, txt_val, dat_val in permissions})

, но это кажется неправильным и может быстро стать беспорядочным. Есть предложения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...