92

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.

oguz ismail
  • 1
  • 16
  • 47
  • 69
shifu
  • 6,586
  • 5
  • 21
  • 21

7 Answers7

190

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()
fedorqui
  • 275,237
  • 103
  • 548
  • 598
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 5
    I don't see how your "full question" conflicts with my answer. If you need to create a user in code, you should use `User.objects.create_user()`. – Daniel Roseman Aug 29 '13 at 07:51
  • 16
    And where does this magical User object come from? H8 when code samples are given without that crucial 'imports' bit. `django.contrib.auth.models` – Jamie Pate Jun 27 '14 at 18:40
  • 6
    Docs for `create_user()`: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#django.contrib.auth.models.CustomUserManager.create_user – guettli Sep 26 '15 at 13:33
  • 5
    This can be reduced to `from django.contrib.auth.models import User; User.objects.create_superuser('foo', password='bar')`. – amath Feb 09 '18 at 16:10
  • For creating a regular user, use this one liner `User.objects.create_user(username='foo', password='bar', is_staff=True)` – rvernica Mar 21 '19 at 17:02
  • 5
    If you have defined your own user, you need to do `from django.contrib.auth import get_user_model` and then `User = get_user_model()` – theQuestionMan Dec 04 '20 at 06:24
  • this is not working for me, as of now in 2:14, getting auth_user error as it does not exist. please help – GD- Ganesh Deshmukh Apr 27 '21 at 20:45
29

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

python manage.py createsuperuser
Adizbek Ergashev
  • 732
  • 8
  • 17
23

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.

Du D.
  • 5,062
  • 2
  • 29
  • 34
5

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='johnsemail@email.com') # 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):
Zargold
  • 1,892
  • 18
  • 24
  • Note that the official docs (https://docs.djangoproject.com/en/1.10/topics/auth/default/#creating-users) import the user model from `django.contrib.auth.models`. Judging by your `other_info` kwargs, you might want to mention that your example uses a custom user model. – Escher Jan 26 '17 at 20:01
  • this was meant for illustration purposes, as in feel free to put any information that your particular User model has here... but sure if someone literally had "other_info" that would have to be a custom User model. – Zargold Jan 26 '17 at 20:44
3

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.

Snakes and Coffee
  • 8,747
  • 4
  • 40
  • 60
  • maybe i need to override default save for User doing that . – shifu Aug 29 '13 at 06:44
  • I don't think you should do that, since it is the default User object (meaning that if you did, it'd screw over everyone else using User, unless you subclassed). What's wrong with using `set_password`? – Snakes and Coffee Aug 29 '13 at 06:45
  • sry , but i have made some changes to original question to make it more related to what i m doing. – shifu Aug 29 '13 at 07:25
3

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')
Cubiczx
  • 1,005
  • 11
  • 10
-3

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.

Rahul Tanwani
  • 441
  • 3
  • 10
  • 1
    `user = User(username="django", password = "secret")` will **not** work as you expect. Please verify advice before sharing it. – Mark Henwood Oct 30 '13 at 14:06
  • Hey, I just missed calling save() after the first statement. Is there anything else wrong in here? – Rahul Tanwani Nov 04 '13 at 09:45
  • 1
    Your first and third examples result in a useless User object. The only correct ways to set passwords for a django User object are: 1 - calling `set_password` on an existing User object 2 - creating the User object with the `User.objects.create_user` helper function With both these methods you pass in the password in the same form an authenticating user would enter it, ensuring that the hash matching will work when they next try to log in. If you set a password using your other two examples, the user will never be able to log in as the hashing check will never pass. – Mark Henwood Nov 06 '13 at 18:34
  • 1
    That's right man. Intent for adding this example was to let the questioner know when can we expect plain text password. Please read the question and see if it makes sense. – Rahul Tanwani Nov 07 '13 at 08:09