Disable LoginRequiredMiddleware on DRF views

This commit is contained in:
Bruno Alla 2024-08-30 18:42:43 +01:00
parent d295dfe5a7
commit dee68ecfce
No known key found for this signature in database
3 changed files with 22 additions and 0 deletions

View File

@ -8,6 +8,7 @@ methods on viewsets that should be included by routers.
"""
import types
from django import VERSION as DJANGO_VERSION
from django.forms.utils import pretty_name
from rest_framework.views import APIView
@ -73,6 +74,11 @@ def api_view(http_method_names=None):
WrappedAPIView.schema = getattr(func, 'schema',
APIView.schema)
# Exempt all DRF views from Django's LoginRequiredMiddleware. Users should set
# DEFAULT_PERMISSION_CLASSES to 'rest_framework.permissions.IsAuthenticated' instead
if DJANGO_VERSION >= (5, 1):
func.login_required = False
return WrappedAPIView.as_view()
return decorator

View File

@ -1,6 +1,7 @@
"""
Provides an APIView class that is the base of all views in REST framework.
"""
from django import VERSION as DJANGO_VERSION
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.db import connections, models
@ -139,6 +140,11 @@ class APIView(View):
view.cls = cls
view.initkwargs = initkwargs
# Exempt all DRF views from Django's LoginRequiredMiddleware. Users should set
# DEFAULT_PERMISSION_CLASSES to 'rest_framework.permissions.IsAuthenticated' instead
if DJANGO_VERSION >= (5, 1):
view.login_required = False
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)

View File

@ -1,5 +1,7 @@
import copy
import unittest
from django import VERSION as DJANGO_VERSION
from django.test import TestCase
from rest_framework import status
@ -81,6 +83,10 @@ class ClassBasedViewIntegrationTests(TestCase):
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert sanitise_json_error(response.data) == expected
@unittest.skipUnless(DJANGO_VERSION >= (5, 1), 'Only for Django 5.1+')
def test_django_51_login_required_disabled(self):
assert self.view.login_required is False
class FunctionBasedViewIntegrationTests(TestCase):
def setUp(self):
@ -95,6 +101,10 @@ class FunctionBasedViewIntegrationTests(TestCase):
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert sanitise_json_error(response.data) == expected
@unittest.skipUnless(DJANGO_VERSION >= (5, 1), 'Only for Django 5.1+')
def test_django_51_login_required_disabled(self):
assert self.view.login_required is False
class TestCustomExceptionHandler(TestCase):
def setUp(self):