Должны ли классы аутентификации и классы разрешений в представлениях Django REST Framework определяться с помощью списков или кортежей?

Я пытаюсь понять, как лучше всего устанавливать классы аутентификации и классы разрешений в APIView Django REST Framework. В частности, я видел, как для определения этих атрибутов используются как кортежи, так и списки:

Использование кортежа:

class Home(APIView):
    authentication_classes = (JWTAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)

Использование списка:

class Home(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [permissions.IsAuthenticated]

Кажется, оба подхода работают правильно, но я не уверен, есть ли какие-то конкретные причины предпочитать один другому. Должен ли я использовать список или кортеж в этом сценарии? Есть ли какие-либо последствия для использования одного над другим с точки зрения производительности, читаемости или следования лучшим практикам Django REST Framework?

Я пробовал использовать как кортежи, так и списки для классов аутентификации и классов разрешений в APIView Django REST Framework. Оба работают нормально, но я не уверен, какой из них лучше или рекомендуется. Я ожидал найти четкие указания по этому поводу.

🤔 А знаете ли вы, что...
Python имеет богатую стандартную библиотеку, включая модули для работы с текстом, файлами и сетями.


1
51
3

Ответы:

Решено

Оба работают одинаково. В документации Django REST Framework, кажется, отдаются предпочтение спискам, так что, возможно, стоит использовать списки.

class ListUsers(APIView):
    authentication_classes = [authentication.TokenAuthentication]
    permission_classes = [permissions.IsAdminUser]

Сначала я объясню процесс аутентификации в DRF.

class APIView(View):
    def initialize_request(self, request, *args, **kwargs):
        """
        Returns the initial request object.
        """
        parser_context = self.get_parser_context(request)

        return Request(
            request,
            parsers=self.get_parsers(),
            authenticators=self.get_authenticators(),
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context
        )

Функция, которая фактически выполняет аутентификацию в DRF, — это функция Perform_authentication, но перед этим, когда метод Initialize_request создает объект запроса, он вызывает метод get_authenticators и передает его в аргумент.

class APIView(View):
    ...
    def get_authenticators(self):
        """
        Instantiates and returns the list of authenticators that this view can use.
        """
        return [auth() for auth in self.authentication_classes]
    ...

Здесь функция get_authenticators повторяет переменную аутентификации_classes, определенную в представлении, созданном пользователями, для создания и возврата каждого объекта класса аутентификации.

В этом процессе используется переменная Authentication_classes, определенная спрашивающим.

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

Проверка разрешений такая же.

class APIView(View):
    def dispatch(self, request, *args, **kwargs):
        ...
        try:
            self.initial(request, *args, **kwargs)

    def initial(self, request, *args, **kwargs):
        ...
        self.check_permissions(request)
        ...

    def check_permissions(self, request):
        for permission in self.get_permissions():
            if not permission.has_permission(request, self):
        ...

    def get_permissions(self):
        """
        Instantiates and returns the list of permissions that this view requires.
        """
        return [permission() for permission in self.permission_classes]

Процесс проверки разрешений в DRF APIView аналогичен описанному выше.

Значение Permissions_classes, установленное пользователем, используется в методе get_permissions и выполняет тот же процесс аутентификации, что и ранее.

То есть, поскольку классы разрешений или классы аутентификации должны использоваться в повторениях, вам придется использовать массив или кортеж этих проблемных типов данных.

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


Сразу к делу: работают и tuple, и list. По сути, если вы хотите изменить переменную, используйте списки. Если вы специально не хотите и не хотите, чтобы переменную кто-то менял, то используйте кортежи. Здесь речь идет просто о проблеме неизменности и изменчивости.