Django. Разграничить права пользователей по клиентам
Имеем:
Django модель список клиентов (таблица в БД со списком клиентов и другой различной информацией)
Что требуется:
Предоставлять пользователям Django доступ к информации по определённому клиенту\клиентам (права на клиентов мы можем изменять) т.е что бы при авторизации пользователя отображался список клиентов к информации о которых у пользователя есть доступ.
Прошу описать схему как это можно реализовать.
Ответы (3 шт):
Для начала, как я понял - надо вывести список клиентов, а потом детальное отображение каждого клиента? 2 функции (или класса) со списком клиентов и их детальном отображении. Соответственно, в первой view (список) - будет примерно такой запрос: Model.objects.all() - вывод всех клиентов. Потом детальное отображение: в создании пути, естественно нужен url-параметр, ну у вас это, что угодно, но в качестве примера пусть будет pk - path('list_users/<int:user_id>/',detail,name='detail'). Ну и во view:
def detail(request,user_id):
user = Model.objects.get(id=user_id)
...
Ну и еще нужна проверка доступа. Ну здесь всё просто. К примеру в функции detail(детальное отображение клиентов) сделать проверку: if request.user.(тут пишите либо is_staff или is_authenticated, короче, что вам надо, то и пишите). Или воспользоваться функцией has_pemrs(туда передаете права, которыми должны обладать пользователи). Не знаю поможет ли вам это информация.
https://docs.djangoproject.com/en/3.2/ref/contrib/auth/
чтобы получить текущего пользователя, достаточно взять его из request.user . передавать id на страницу списка пользователей, доступных для отображения смысла нет. Надо отталкиваться от request.user
Права на клиентов создаете сами, либо через Meta ( https://docs.djangoproject.com/en/3.2/ref/models/options/#permissions ), либо ручками.
Исходя из этих прав, на странице отображения списка пользователей, фильтруете queryset клиентов в зависимости от доступных прав
Нужно больше подробностей? Предоставьте больше информации (где, в админке или нет, как идет разграчением доступа к клиентам)
То что вам нужно называется ACL - access control list.
В django я бы делал так. Создаем модель, скажем в приложении aclapp:
class ACL(models.Model):
model_content_type = models.ForeignKey(
ContentType, on_delete=models.CASCADE)
object_id = models.CharField(max_length=30)
username = models.CharField(max_length=30)
Запись в ACL будет означать, что пользователь username имеет доступ к объекту с идентификатором object_id типа описываемого model_content_type.
Теперь нужно модифицировать менеджер, чтоб он учитывал эту таблицу в запросах:
class AclAwareManager(models.Manager):
def __init__(self, username, model):
self.username = username
self.content_type = ContentType.objects.get_for_model(model)
def get_queryset(self):
return super().get_queryset().filter(id__in=_get_acl_filter())
def _get_acl_filter(self)
return RawSQL("select object_id from aclapp_acl where username = %s and model_conent_type = %s",
(self.username, self.content_type.id,))
И использовать в модели:
class Client(models.Model):
name = models.CharField(...)
...
def accessible_objects(self, user):
return AclAwareManager(user.usename, Client)
Ну и теперь можно использовать менеджер например во view:
def clients_view(request):
clients = Client.accessible_objects(request.user).filter(name='some name')
На практике вместо username обычно хранят группу, и смотрят на вхождение пользователя в группу. Так же обычно создают по ACL записи на разный вид действия - т.е. одна запись описывет, кто может читать, вторая - кто может модифицирвать и т.д.