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  
    1010from django.contrib.auth.management import get_default_username
    1111from django.core import exceptions
    1212from django.core.management.base import BaseCommand, CommandError
    13 from django.db import DEFAULT_DB_ALIAS
     13from django.db import DEFAULT_DB_ALIAS, transaction
    1414from django.utils.encoding import force_str
    1515from django.utils.six.moves import input
    1616from django.utils.text import capfirst
     
    146146        if username:
    147147            user_data[self.UserModel.USERNAME_FIELD] = username
    148148            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)
    150153            if options['verbosity'] >= 1:
    151154                self.stdout.write("Superuser created successfully.")
    152155
     156    def pre_create(self, user_data):
     157        return user_data
     158
     159    def post_create(self, user):
     160        pass
     161
    153162    def get_input_data(self, field, message, default=None):
    154163        """
    155164        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)

comment:1 by Tim Graham, 8 years ago

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.

comment:2 by Florian Apolloner, 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.

Last edited 8 years ago by Florian Apolloner (previous) (diff)

comment:3 by Tim Graham, 8 years ago

Summary: Add the possibilty to extend the createsuper user commandAdd 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.

in reply to:  1 comment:4 by Lyra2108, 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 Tim Graham, 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 Lyra2108, 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 Tim Graham, 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 Tim Graham, 8 years ago

Resolution: wontfix
Status: newclosed

Let's reopen if you can find enthusiasm for some solution on the DevelopersMailingList.

Note: See TracTickets for help on using tickets.
Back to Top