Django自定义用户模型密码未自动哈希致登录失败求助
Hey there! Let's break down why your user passwords are stuck as plaintext and how to fix this once and for all.
Why isn't the password being hashed automatically?
The root cause boils down to how Django handles password hashing for user models:
- Django's built-in
Usermodel uses itsUserManagerclass (specifically thecreate_user()method) to automatically hash passwords before saving. This method runs the plaintext password through Django's secure hashing algorithms behind the scenes. - If you're creating users with a basic
Profil.objects.create()call, or directly assigning a plaintext value to thepasswordfield, you're skipping this critical step. Django will just save the raw string because it has no trigger to hash it. - When you manually call
user.set_password(), that method explicitly triggers the hashing process—which is why login works after doing that.
How to auto-hash passwords when creating users?
Let's fix this with two targeted steps for your extended Profil model:
1. Attach the correct manager to your Profil model
First, update your model code to include Django's UserManager—this gives your extended model access to the password-hashing logic:
from django.db import models from django.contrib.auth.models import User, UserManager class Profil(User): # Replace with your actual extended fields (your original code cut off here) bio = models.TextField(blank=True, null=True) profile_pic = models.ImageField(upload_to='profiles/', blank=True) # Add the UserManager to enable create_user() objects = UserManager()
2. Always use create_user() to create users
Instead of using Profil.objects.create(), use the create_user() method from the manager. This will automatically hash the password:
# Example in Django shell or view code new_user = Profil.objects.create_user( username="johndoe", email="john@example.com", password="my_secure_password123" ) # Set your custom Profil fields if needed new_user.bio = "I love Django!" new_user.save()
Bonus: Better practice for extending user models
While inheriting the User model works, Django officially recommends extending AbstractUser instead—it avoids potential database layer quirks with direct inheritance. If you're early in your project, consider refactoring:
from django.db import models from django.contrib.auth.models import AbstractUser, UserManager class Profil(AbstractUser): bio = models.TextField(blank=True, null=True) profile_pic = models.ImageField(upload_to='profiles/', blank=True) objects = UserManager()
Then update your settings.py to tell Django to use your custom user model:
AUTH_USER_MODEL = 'your_app_name.Profil'
Quick verification
After making these changes, create a new user with create_user() and check your database—you'll see a long, hashed string instead of plaintext, and login will work without needing manual set_password() calls.
内容的提问来源于stack exchange,提问作者vildric

