Opened 8 years ago
Closed 8 years ago
#26745 closed New feature (wontfix)
Add the ability to customize user creation in the createsuperuser command
Reported by: | Lyra2108 | Owned by: | nobody |
---|---|---|---|
Component: | contrib.auth | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | markush | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
We want to perform actions after the creation of the superuser. But we do not want to rewrite the createsuper command entirely.
This should be done in a transaction, because if the post actions fail the user shall not be created.
Additionally it might be useful to also have a pre create action which can modify the user data passed to the create_superuser()
method on the user manager and add non required parameters to the user data before the creation of the super user.
We thought about something along these lines:
-
django/contrib/auth/management/commands/createsuperuser.py
old new 10 10 from django.contrib.auth.management import get_default_username 11 11 from django.core import exceptions 12 12 from django.core.management.base import BaseCommand, CommandError 13 from django.db import DEFAULT_DB_ALIAS 13 from django.db import DEFAULT_DB_ALIAS, transaction 14 14 from django.utils.encoding import force_str 15 15 from django.utils.six.moves import input 16 16 from django.utils.text import capfirst … … 146 146 if username: 147 147 user_data[self.UserModel.USERNAME_FIELD] = username 148 148 user_data['password'] = password 149 self.UserModel._default_manager.db_manager(database).create_superuser(**user_data) 149 with transaction.atomic(): 150 user_data = self.pre_create(user_data) 151 user = self.UserModel._default_manager.db_manager(database).create_superuser(**user_data) 152 self.post_create(user) 150 153 if options['verbosity'] >= 1: 151 154 self.stdout.write("Superuser created successfully.") 152 155 156 def pre_create(self, user_data): 157 return user_data 158 159 def post_create(self, user): 160 pass 161 153 162 def get_input_data(self, field, message, default=None): 154 163 """ 155 164 Override this method if you want to customize data inputs or
Diff is against v1.8.13 but this shouldn't make a difference.
Change History (8)
follow-up: 4 comment:1 by , 8 years ago
comment:2 by , 8 years ago
I am not particularly fond of either solution.
- Signal registration is global and would happen for every user not just the superuser
- A custom manager seems overkill if all you want is to add some data somewhere and do not have your own user model
- Overriding the command is still work but probably the best solution suggested
Another option: Stuff something onto AppConfig and make create_superuser use apps.get_app_config(get_user_model()._meta.app_label).create_superuser
which by default just be (ie if not defined):
UserModel._default_manager.db_manager(database).create_superuser(**user_data)
I think pre/post are overkill, someone customizing that can as well just write the create_superuser line too.
comment:3 by , 8 years ago
Summary: | Add the possibilty to extend the createsuper user command → Add the ability to customize user creation in the createsuperuser command |
---|
Of course a signal could check the is_superuser
attribute and act accordingly. Whether or not the use case also applies to superusers created in other ways is of course another question.
comment:4 by , 8 years ago
Besides that the signal will also be called for a normal user request, we don't want to create the user at all, if the post create actions fail. If we would use the signal for this, we would have to do the rollback manually because the user is already saved in the database. The transaction would make that simpler.
comment:5 by , 8 years ago
Could you please explain the use case a bit more? i.e. what actions do you want to perform?
comment:6 by , 8 years ago
The main use case is to add permissions for the super user. Without the permissions the user isn't set up correctly and shouldn't be created.
comment:7 by , 8 years ago
Oh, I guess you're using permissions in a somewhat unusual way since ModelBackend
defines superusers as having all permissions.
Is the likelihood of the post_save
signal failing really so large that you must perform actions in the same transaction? See also #24228 which questions whether or not pre_save
and post_save
should be in the transaction.
comment:8 by , 8 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Let's reopen if you can find enthusiasm for some solution on the DevelopersMailingList.
Could you provide more details about your use case? Is the
post_save
signal or overriding the model's manager not sufficient? I'm skeptical of more customizations points as these things increase complexity.