Opened 12 years ago
Closed 12 years ago
#20541 closed Cleanup/optimization (fixed)
Differenciate user from superuser creation in django.contrib.auth at a signal level
| Reported by: | Owned by: | Anton Baklanov | |
|---|---|---|---|
| Component: | contrib.auth | Version: | 1.5 |
| Severity: | Normal | Keywords: | |
| Cc: | antonbaklanov@… | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | yes | UI/UX: | no |
Description
Hi all,
Currently the steps to create a superuser (auth.models.User.create_superuser) are:
1) Create user
2) Save User
3) Assign staff, active, superuser
4) Save again
When the first save happens the post_save signal is raised, but the user is not a superuser yet. The signal will get raised again after a few lines, which is wasteful. My proposal is to implement superuser creation like this:
class UserManager(BaseUserManager):
def create_user(self, username, email=None, password=None, save=True, **extra_fields):
"""
Creates and saves a User with the given username, email and password.
"""
now = timezone.now()
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=False, is_active=True, is_superuser=False,
last_login=now, date_joined=now, **extra_fields)
user.set_password(password)
if save:
user.save(using=self._db)
return user
def create_superuser(self, username, email, password, **extra_fields):
u = self.create_user(username, email, password, save=False, **extra_fields)
u.is_staff = True
u.is_active = True
u.is_superuser = True
u.save(using=self._db)
return u
Now when post_save is fired, one can check is_superuser, is_staff or is_active and take action based on that.
Change History (3)
comment:1 by , 12 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:2 by , 12 years ago
| Cc: | added |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
here is my pull request for this https://github.com/django/django/pull/1305
comment:3 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
I fully accept that the underlying problem -- that saving a superuser involves 2 saves -- should be solved. I'm just not completely convinced about the solution. The extra save=True argument seems messy to me.
Personally, I'd rather see the 'guts' of create_user factored out into in internal method that is called by both create_user and create_superuser - that way, the public call to create_user would end up looking a lot like create_superuser, but with reversed boolean values.