How to create user from django shell

119.2k views Asked by At

When i create user from django-admin user password's are encrypted . but when i create user from django shell user-pasword is saved in plain text . Example :

{
    "date_joined": "2013-08-28T04:22:56.322185",
    "email": "",
    "first_name": "",
    "id": 5,
    "is_active": true,
    "is_staff": false,
    "is_superuser": false,
    "last_login": "2013-08-28T04:22:56.322134",
    "last_name": "",
    "password": "pbkdf2_sha256$10000$iGKbck9CED0b$6hWrKYiMPNGKhcfPVGal2YP4LkuP3Qwem+2ydswWACk=",
    "resource_uri": "/api/v1/user/5/",
    "username": "user4"
},
{
    "date_joined": "2013-08-29T01:15:36.414887",
    "email": "test@ophio",
    "first_name": "",
    "id": 6,
    "is_active": true,
    "is_staff": true,
    "is_superuser": true,
    "last_login": "2013-08-29T01:15:36.414807",
    "last_name": "",
    "password": "123test",
    "resource_uri": "/api/v1/user/6/",
    "username": "test3"
} 

I am trying to make REST style api for a simple blog app : when i try to insert a user by post request [ by passing JSON ] password is saved as plain text. how to override this behaviour.

7

There are 7 answers

7
Daniel Roseman On BEST ANSWER

You should not create the user via the normal User(...) syntax, as others have suggested. You should always use User.objects.create_user(), which takes care of setting the password properly.

user@host> manage.py shell
>>> from django.contrib.auth.models import User
>>> user=User.objects.create_user('foo', password='bar')
>>> user.is_superuser=True
>>> user.is_staff=True
>>> user.save()
3
Snakes and Coffee On

You use user.set_password to set passwords in the django shell. I'm not even sure if directly setting the password via user.password would even work, since Django expects a hash of the password.

The password field doesn't store passwords; it stores them as <algorithm>$<iterations>$<salt>$<hash>, so when it checks a password, it calculates the hash, and compares it. I doubt the user actually has a password whose calculated password hash is in <algorithm>$<iterations>$<salt>$<hash> form.

If you get the json with all the information needed to create the User, you could just do

User.objects.create_user(**data)

assuming your passed json is called data.

Note: This will throw an error if you have extra or missing items in data.

If you really want to override this behavior, you can do

def override_setattr(self,name,value):
    if name == 'password':
        self.set_password(value)
    else:
        super().__setattr__(self,name,value) #or however super should be used for your version

User.__setattr__ = override_setattr

I haven't tested this solution, but it should work. Use at your own risk.

4
Rahul Tanwani On

There are couple of way to set password for a django user object from django-shell.

user = User(username="django", password = "secret")
user.save()

This will store encrypted password.

user = User(username="django")
user.set_password("secret")
user.save()

This will store encrypted password.

But,

user = User(username="django")
user.password="secret"
user.save()

This will store plain text password. There is no hashing / encryptions applied since you are modifying the property directly.

2
Zargold On

Answer for those using django 1.9 or greater since from django.contrib.auth.models import User has been deprecated (possibly even earlier) but definitely by 1.9.

Instead do: in bash:

python manage.py shell

In the python shell to create a user with a password:

from django.apps import apps
User = apps.get_model('user', 'User')
me = User.objects.create(first_name='john', email='[email protected]') # other_info='other_info', etc.
me.set_password('WhateverIwant')  # this will be saved hashed and encrypted
me.save()

If coming from an API you should probably apply a Form as such:

import json
User = get_model('User')
class UserEditForm(BaseModelForm):
        """This allows for validity checking..."""

        class Meta:
            model = User
            fields = [
                'first_name', 'password', 'last_name',
                'dob', # etc...
            ]
# collect the data from the API:
post_data = request.POST.dict()
data = {
'first_name': post_data['firstName'],
'last_name': post_data['firstName'],
'password': post_data['password'], etc.
}
dudette = User()  # (this is for create if its edit you can get the User by pk with User.objects.get(pk=kwargs.pk))
form = UserEditForm(data, request.FILES, instance=dudette)
if form.is_valid():
    dudette = form.save()
else:
    dudette = {'success': False, 'message': unicode(form.errors)}
return json.dumps(dudette.json())  # assumes you have a json serializer on the model called def json(self):
0
Cubiczx On

To create Users execute:

$ python manage.py shell
>>>> from django.contrib.auth.models import User
>>>> user = User.objects.create_user('USERNAME', 'MAIL_NO_REQUIRED', 'PASSWORD')
3
Adizbek Ergashev On

The fastest way creating of super user for django, type in shell:

python manage.py createsuperuser
0
Du D. On

To automate the script you can use the pipe feature to execute the list of commands without having to type it out every time.

### content of "create_user.py" file
from django.contrib.auth import get_user_model

# see ref. below
UserModel = get_user_model()

if not UserModel.objects.filter(username='foo').exists():
    user=UserModel.objects.create_user('foo', password='bar')
    user.is_superuser=True
    user.is_staff=True
    user.save()

Ref: get_user_model()

Remember to activate VirtualEnv first, then run the command below (for Linux):

cat create_user.py | python manage.py shell

If you using window then substitute the cat command with the type command

type create_user.py | python manage.py shell

OR for both Linux and Windows

# if the script is not in the same path as manage.py, then you must 
#    specify the absolute path of the "create_user.py" 
python manage.py shell < create_user.py

Pitfall: don't include blank lines in any of the indented blocks, think of it as you pasting your code in the REPL. If you have any empty lines it won't work.