Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create staff user in Django

Tags:

python

django

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? :-)

like image 860
Jamgreen Avatar asked Jun 08 '15 14:06

Jamgreen


People also ask

What is 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.

How do I give staff permissions in Django?

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.

How do I create a user in Django?

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 ...


1 Answers

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.

like image 127
allcaps Avatar answered Sep 28 '22 00:09

allcaps