I'm trying to create a staff user in Django with
UserModel.objects.create_user(username="A", email="[email protected]", password="a", is_staff=True)
but in UserManager in Django at https://github.com/django/django/blob/master/django/contrib/auth/models.py it says
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, username, email, password,
is_staff, is_superuser, **extra_fields):
"""
Creates and saves a User with the given username, email and password.
"""
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
user = self.model(username=username, email=email,
is_staff=is_staff, is_superuser=is_superuser,
**extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, False, False,
**extra_fields)
def create_superuser(self, username, email, password, **extra_fields):
return self._create_user(username, email, password, True, True,
**extra_fields)
so when trying to set is_staff = False
it will always override this field with is_staff = True
unless I use create_superuser
instead of create_user
; however, create_superuser
also sets is_superuser = True
.
Have they forgot to create the method create_staff_user
in Django? :-)
staff. - A user marked as staff can access the Django admin. But permissions to create, read, update and delete data in the Django admin must be given explicitly to a user. By default, a superuser is marked as staff.
To do this, create a group in Groups in the django admin. You can add model permissions according to the models you would wish the staff or users to have access to. Once that is done, add your your users to that group. You do that by selecting the user of interest and adding them to the created groups.
from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # Redirect to a success page. ... else: # Return an 'invalid ...
No, I don't think that 'they' forgot the create_staff_method.
This is the pull request that gave birth to the _create_user
method and the reason for doing so is:
don't raise db signals twice when creating superuser
Both create_user and create_superuser methods make use of the same private method. Understanding this, and knowing that there are no true private methods in Python makes utilising _create_user directly an option. But an ugly option.
The create_user method is extra method for your convenience. You are right that calling it with is_staff=True
won't give the expected result. I think that is the real bug. The error is:
TypeError: _create_user() got multiple values for keyword argument 'is_staff'
Your code (username is a positional argument):
User.objects.create_user('john', email='[email protected]', password='johnpassword', is_staff=True)
What the documentation on creating users suggest:
user = User.objects.create_user('john', '[email protected]', 'johnpassword')
user.is_staff=True
user.save()
But this way we are calling save twice. :/
The UserManager is a subclass of BaseUserManager which is a subclass of Manager. So you can also do:
email = normalize_email('[email protected]')
user = User.objects.create(username='john',
email=email, is_staff=True )
user.set_password(password)
user.save()
Since explicit is better than implicit and simple is better than complex... I would go for the most basic and simple User.objects.create
. Or wait for https://code.djangoproject.com/ticket/25009 to land.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With