I have the following code:
@api_view(['GET'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def jobs(request):
if request.user == 'admin':
job = Job.objects.all()
jobserializer = JobViewSeralizers(job, many = True)
return Response(jobserializer.data)
else:
job = Job.objects.filter(owner = request.user)
jobserializer = JobViewSeralizers(job, many = True)
return Response(jobserializer.data)
When I use postman and log in as a normal user, else
condition runs. But if i log in as admin user, if
condition does not run. It still run else
condition. Is there something wrong with my code for if
condition?
Request.user is a reference to a User object, not just the login name of the user. See Using the Django authentication system | Django documentation | Django
I understand that it is a reference to User object. In the case of my code, if i logged in using admin account, the else condition will run and it will filter owner == request.user
. In this case, request.user
will have admin
stored as i logged in with admin account and the output will show those jobs that owner == admin
. But why I cannot put this request.user=='admin'
as a condition?
Because request.user
is an object of type User, while 'admin'
is a String. The two are never going to be equal. See the referenced docs.
This is not a correct statement. The variable, request.user
will have a reference to the User object having a username of admin
.
I think i kind of get it. Thank you very much! I dont know if this is the right way but it worked:
@api_view(['GET'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def jobs(request):
currentuser=request.user
print(type(currentuser))
user = str(currentuser)
print(type(user))
if user == 'admin':
job = Job.objects.all()
jobserializer = JobViewSeralizers(job, many = True)
return Response(jobserializer.data)
else:
job = Job.objects.filter(owner = request.user)
jobserializer = JobViewSeralizers(job, many = True)
return Response(jobserializer.data)
Sorry, that’s dangerously wrong.
In addition to the above, see Using the Django authentication system | Django documentation | Django
and django.contrib.auth | Django documentation | Django
One attribute you could look for is the username
attribute of the User object. In other words request.user.username == 'admin'
. That’s still “wrong”, but less so than your approach.
A production-quality deployment will generally have more than one superuser account. What you probably want to check is is_superuser
. e.g. if request.user.is_superuser:
May I ask how come is dangerously wrong? It is some security issue? But thanks for linking the fields for me. I forget about is_superuser
field.
Because you’re tying an authorization function to an implementation of an api (the str
method of the User object) that is not necessarily “stable”.
There is no documented requirement that print(user)
always return only the username
field. It’s possible that the next version of Django changes AbstractBaseUser from:
def __str__(self):
return self.get_username()
to:
def __str__(self):
return "User: "+self.get_username()
and your system breaks.
When there are valid APIs for performing a given function, there’s no reason for using an invalid API just because it currently happens to work.
Oh okay. Thanks for the clear explanation !