如何解决Django自定义Driver模型的密码验证不匹配问题?
问题分析与解决方案
你的代码有三个关键问题导致登录验证失败:
- 密码重复哈希:每次调用
save()都会重新哈希密码,哪怕当前存储的已经是哈希值。比如修改司机姓名后保存,数据库里的哈希密码会被再次哈希,最终存储的是哈希的哈希值,自然无法和明文密码匹配。 - 密码比对逻辑错误:
check_password直接用==对比明文和哈希值,这完全行不通——哈希是单向加密,必须用Django提供的验证函数来判断明文和哈希值是否对应。 - 密码字段长度不足:Django生成的哈希密码长度远超过50,你设置的
max_length=50会截断哈希值,导致验证失败。
修正后的代码
from django.db import models from django.contrib.auth.hashers import make_password, check_password class Driver(models.Model): name = models.CharField(max_length=50) phone_number = models.CharField(max_length=15) email = models.EmailField(unique=True, null=True) # 加大密码字段长度,适配Django哈希值 password = models.CharField(max_length=255) def __str__(self): return self.name def save(self, *args, **kwargs): # 仅当实例是新建,或密码字段被修改时才哈希密码 if self._state.added or 'password' in [f.name for f in self._meta.fields if self._state.fields_cache.get(f.name) != getattr(self, f.name)]: self.password = make_password(self.password) super().save(*args, **kwargs) def check_password(self, password): # 使用Django官方的密码验证函数 return check_password(password, self.password)
更优实践
如果你的项目需要用到Django的认证系统(比如登录、权限管理),强烈建议继承AbstractBaseUser或AbstractUser,这样可以直接复用Django内置的set_password()、check_password()以及其他认证相关功能,不需要自己实现这些基础逻辑,也能避免后续踩更多坑。
内容的提问来源于stack exchange,提问作者Yoocee Ansah
相关产品推荐
相关产品推荐

