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}
)