I have a custom authentication class following the docs
class ExampleAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
username = request.META.get('HTTP_X_USERNAME')
if not username:
return None
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user')
return (user, None)
and I used it in my APIView:
class profile(APIView):
permission_classes = ()
authentication_classes = (ExampleAuthentication,)
def get(self, request, format=None):
try:
print('user', request.user)
serializer = GetUserSerializer(request.user)
return JsonResponse({'code': 200,'data': serializer.data}, status=200)
except Exception as e:
return JsonResponse({'code': 500,'data': "Server error"}, status=500)
when I try to call it normally from the API through postman I got the following result from the print and it worked normally:
user User(143)
I wrote a test using force_authenticate():
class BaseUserAPITest(APITestCase):
def setUp(self):
# self.factory = APIRequestFactory()
self.user = models.User.objects.get_or_create(
username='test_user_1',
uid='test_user_1',
defaults={'agent_type': 1}
)
def test_details(self):
url = reverse("api.profile")
self.client.force_authenticate(user=self.user)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
I got server error because the print of request.user return a tuple instead of a User object, this is the print from the test log
user (<User: User(143)>, True)
I tried searching up and seem like there no result or explanation on why this happening
My version:
django==2.2.8
djangorestframework==3.10.2
CodePudding user response:
The problem is not force_authenticate but get_or_create method. It returns tuple. First element of the tuple is object and second one is boolean indicating if object was created or not. To fix change your code in setUp method to this:
def setUp(self):
# self.factory = APIRequestFactory()
self.user, _ = models.User.objects.get_or_create(
username='test_user_1',
uid='test_user_1',
defaults={'agent_type': 1}
)
