Hello everyone.
I’m facing some difficulties understanding staff permissions for User model.
It is clear that is_superuser grants all permissions (including admin features). However I can’t understand the role of is_staff field:
is_staff describes as “Designates whether the user can log into this admin site.” However if is_staff field set to True and is_superuser field set to False the user is not able to access admin. Is that how it supposed to work? If yes, than what is the use of is_staff field if superuser has to set user’s permissions to access admin page manually?
Well, imagine that you have the following scenario.
You build a company website. This website have a internal dashboard or management area (not the django admin). A user can be a superuser of that management area, but not from the django admin (superuser=True but is_staff=False). But someone can have access to the django admin, but not to be a superuser (is_superuser=False but is_staff=True).
They’re completely different flags that mean different things.
Remember, the Django admin site is a very special place, you must keep it reserved to a few people, as the documentation states on the 1st paragraph of The Django admin site.
@leandrodesouzadev , thanks for helping!
So, if I understand right :
- User with
is_staff = Truehas an access to django admin dashboard without permissions until explicitly specified; is_superuserhas all permissions except django admin (untilis_staffis set);- combination of
is_superuser + is_staffgrants all permissions of two points above?
That is correct.
This isn’t quite accurate.
The is_superuser setting bypasses all permissions tests within the admin. If is_superuser is set, then no other permissions ever need to be assigned.
(Note: The general intent for this is that is_superuser bypasses all permission tests. However, it’s valid for a custom permissions test to ignore this setting, making it possible to create views that block individuals with only is_superuser.)
That is strange because in my case removing ‘is_staff’ but keeping ‘is_superuser=True’ denies to enter admin url. I might missed something.
And additionally I don’t clearly understand where permissions applied to: either to admin site only or project globally. I noticed that granting some particular app permissions to user displays those models in admin while other hidden but roaming on the website still allows to access a views which are not permitted. Do I still have to restrict it manually in template with ‘has_permission()” ?
I believe that looking to is_staff is more like:
“You only will be able to login/access the admin if you have this flag set. No matter if you have one, none or all permissions”
While is_superuser is like:
“No matter which permission is checked against this user consider it to have it. But this permission doesn’t have anything to do with the is_staff permission”
Nope, you’re right.
That is correct, and is why I specified that these settings affect the admin. (Or in the view, as that typically is the more common case for applying permission limitations.)
All permission limitations within your project is your responsibility to define and enforce.
(For some additional thoughts on this, see (SOLVED) How to add a more fine grid authentication/permissions to groups in Django - #4 by KenWhitesell and the topics it links.)
@KenWhitesell , @leandrodesouzadev.
Thank all of you for explaining. More staff make sense now.
Marking @KenWhitesell answer as solution as last replied.
Based on your explanations, @KenWhitesell it seems that this flag would be better named has_admin_access or something like that.
I have also apparently misunderstood the is_staff flag - probably in no small part due to the number of examples I recall seeing that used the flag for restricting permissions but in light of this conversation it seems that usage may be misguided: the is_staff does not enforce nor even imply group membership - i.e. does not really mean that the user with the flag is part of a staff group - much less restrict or enforce permissions based on the value of this flag.
That’s assuming that granting access to the admin is the only function that can be performed by the is_staff flag. But, as you point out -
There are other valid uses of that flag by applications. It is certainly possible to create your own apps and views as a logical extension of the Django Admin, using the same patterns of permissions as used by the admin contrib app.
Whether or not this would be “misguided” should only be considered in the context of that application.
(Keep in mind that the Django Admin is just an app. Structurally within Django, it’s no different than any other app. The mistake I see made most often is that people think that there’s something “special” or “magical” about it, when in reality it’s just another collection of forms and views. Very useful forms and views, but pretty much standard Django otherwise.)
Correct - that’s how it’s documented at
- User.is_staff (Note that this is documented as a field and not as a method. It has no dependencies or internal relationship to any other fields on
User.) - The Django Admin site Overview:
By default, logging in to the admin requires that the user has the
is_staffattribute set toTrue.
I’d also like to add that is_staff is one of those artifacts that goes back 20 years and is highly unlikely to be changed at this point unless there’s an extremely compelling and undeniable reason to do so.