Я пытаюсь понять, как лучше всего устанавливать классы аутентификации и классы разрешений в 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 имеет богатую стандартную библиотеку, включая модули для работы с текстом, файлами и сетями.
Оба работают одинаково. В документации 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 реализовал описанную выше логику для разрешений и аутентификации, заключается в том, чтобы разрешить использование множественной аутентификации и разрешений.