22

In the Django documentation, it uses User.objects.create_user() to create a user. I am confused, what is the difference between that and User.objects.create() and User().save() which are the normal ways to create objects of other models

5 Answers 5

36

The most significant difference is that if you supply a password to the .create() method, it will be set verbatim on the user, and will not be usable to authenticate the user.

>>> user = User.objects.create(username="foo", password="bar") >>> user.password 'bar' >>> user.check_password("bar") False 

Instead, the create_user() method hashes the password argument, which is then.

>>> user = User.objects.create_user(username="foo", password="bar") >>> user.password 'pbkdf2_sha256$120000$2pHBVu3tYYbK$ESG1nbUY2ZhEmstJ7Fzu1DioXmGYXiLw31YDkOGn9E0=' >>> user.check_password("bar") True 

See https://github.com/django/django/blob/master/django/contrib/auth/models.py#L145.

Some other 'tidying' is also done. See the rest of the function linked above.

Sign up to request clarification or add additional context in comments.

3 Comments

What if I created a custom user, by extending models.Model not AbstractUser because I will use oAuth2, so I don't need the password field. then, I could use the create function safely, right ? create_user won't be available because of not extending AbstractUser.
As other users have replied here, the create_user method has some other useful features. What you suggest is safe, and you can use settings.AUTH_USER_MODEL to configure your custom user, but note that it comes with other useful features besides just the password field. Indeed django-oauth-toolkit.readthedocs.io suggests integrating with the standard AbstractUser model. You could always use it for the sake of convention and disregard the password field.
A minor thing to note and be aware of is that creating a User without the built-in create_user function may potentially cause you issues with other functions that depend on the password being encrypted. For example, during testing where you may want to have a user signed in for a specific request e.g testing with DRF
6

User.objects.create_user() is a helper function that provides helpful utilities to create a user that otherwise you would have to do yourself. As per the documentation:

Creates, saves and returns a User

The username and password are set as given. The domain portion of email is automatically converted to lowercase, and the returned User object will have is_active set to True.

If no password is provided, set_unusable_password() will be called.

The extra_fields keyword arguments are passed through to the User’s __init__ method to allow setting arbitrary fields on a custom user model.

Without create_user() you could create the functionality yourself using the methods you mentioned, but it provides useful processing and utility.

Comments

4

create() and save() are generic methods to create a model instance. They don't do anything specific to the User model while create_user() method is specific method to create the user.

While creating user with generic methods, the value you set as a password will not be hashed.You need to do it by yourself like this.

u = User(username="username") u.set_password("password") u.save() 

Also you can't do the same with create() method without an additional database query.

While with the create_user() the username and password are set as given and password will be hashed automatically and the returned User object will have is_active set to True

Comments

1

You should get the user model:

from django.contrib.auth import get_user_model UserModel = get_user_model() user = UserModel.objects.create(username="Mr Foo", password="bar") user.save() 

Or:

user = UserModel.objects.create_user("Mr Foo", password="bar") user.save() 

Comments

0

If you use create_user() you don't need to save it with save(). create_user() already saves the user to the database see: https://docs.djangoproject.com/en/4.0/topics/auth/default/

2 Comments

This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review
This reiterates what OP already states in the question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.