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:
{{{#!diff
--- ./django/contrib/auth/management/commands/createsuperuser.py
2016-06-11 01:02:02.307032020 +0200
+++ /home/markus/.venvs/inyoka/lib/python2.7/site-
packages/django/contrib/auth/management/commands/createsuperuser.py
2016-06-11 00:58:07.887693597 +0200
@@ -10,7 +10,7 @@
from django.contrib.auth.management import get_default_username
from django.core import exceptions
from django.core.management.base import BaseCommand, CommandError
-from django.db import DEFAULT_DB_ALIAS
+from django.db import DEFAULT_DB_ALIAS, transaction
from django.utils.encoding import force_str
from django.utils.six.moves import input
from django.utils.text import capfirst
@@ -146,10 +146,19 @@
if username:
user_data[self.UserModel.USERNAME_FIELD] = username
user_data['password'] = password
-
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
+ with transaction.atomic():
+ user_data = self.pre_create(user_data)
+ user =
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
+ self.post_create(user)
if options['verbosity'] >= 1:
self.stdout.write("Superuser created successfully.")
+ def pre_create(self, user_data):
+ return user_data
+
+ def post_create(self, user):
+ pass
+
def get_input_data(self, field, message, default=None):
"""
Override this method if you want to customize data inputs or
}}}
Diff is against v1.8.13 but this shouldn't make a difference.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Comment:
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:1>
Comment (by apollo13):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:2>
Comment (by timgraham):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:3>
Comment (by Lyra2108):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:4>
Comment (by timgraham):
Could you please explain the use case a bit more? i.e. what actions do you
want to perform?
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:5>
Comment (by Lyra2108):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:6>
Comment (by timgraham):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:7>
* status: new => closed
* resolution: => wontfix
Comment:
Let's reopen if you can find enthusiasm for some solution on the
DevelopersMailingList.
--
Ticket URL: <https://code.djangoproject.com/ticket/26745#comment:8>