Django: Как управлять разрешениями на основе сложного запроса

Я создаю приложение, используя django rest_framework.

У меня есть следующие модели:

  • Сотрудник (отношение "многие к одному" к проекту)
  • Проект (отношения "многие к одному" к Менеджеру)
  • Менеджер

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

Вот библиотеки, которые я использую:

asgiref==3.4.1
Django==3.2.6
django-filter==2.4.0
django-rest-framework==0.1.0
djangorestframework==3.12.4
pytz==2021.1
sqlparse==0.4.1

Я представляю себе что-то вроде этого:

class Employee(models.Model):
    name = models.CharField()
    assignment = models.ForeignKey('Project', on_delete=models.SET_NULL, null=True, blank=True, 
                                   related_name='assigned_to_project')


class Project(models.Model):
    name = models.CharField()
    owner = models.ForeignKey('Manager', on_delete=models.SET_NULL, null=True, blank=True, 
                              related_name='managed_by')

class Manager(models.Model):
    name = models.CharField()

Что касается разрешений, я представляю себе пользовательское разрешение на сотрудника, которое выглядит примерно так:

def has_permission(self, request, obj=None):
    if obj:
        if obj.assignment is not None:
            """ Start sudo-code
            - Use the value saved in obj.assignment (for example the PrimaryKey of the project it is assigned to)
            - Follow that PK to the project table, and look to see if obj.owner is not None.
            - If it isn't None, take the PK and follow it to the manager. 
            - Compare the pk of manager with the ID of the user that is currently logged in, and if so, allow the permissions
            End sudo Code """

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

https://www.django-rest-framework.org/api-guide/permissions/#examples

class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Instance must have an attribute named `owner`.
        return obj.owner == request.user
Вернуться на верх