【问题标题】:Django AbstractUser password is not hashingDjango AbstractUser 密码没有散列
【发布时间】:2020-11-09 16:46:06
【问题描述】:

我已将AbstractUser 用作自定义字段扩展的模型,由ModelForm 自动创建表单。问题是,除了超级用户之外的用户无法登录系统。我认为这是原因,他们的密码没有散列。我应该在哪里做?这是我的代码。

forms.py:

class CustomUserSignUpForm(ModelForm):
    class Meta:
        model = CustomUser
        fields = ['username', 'password', 'user_image', 'role', 'branch', 'license_number', 'fin_number', 'first_name', 'last_name', 'patronymic', 'phone_number', 'email', 'voen_number', 'is_active']

views.py:

def sign_up(request):
    if request.method == 'POST':
        form = CustomUserSignUpForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = CustomUserSignUpForm()

    context = {
        'form': form,
    }

    return render(request, 'sign_up.html', context)

models.py:

class CustomUser(AbstractUser):
    patronymic = models.CharField(_('Ata adı'), max_length=150, blank=True)
    role = models.ForeignKey(Role, on_delete=models.CASCADE, blank=True, null=True)
    user_image = models.FileField(_('Profil şəkli'), upload_to='static/assets/images/user-images', blank=True)
    branch = models.ForeignKey(Branch, on_delete=models.CASCADE, blank=True, null=True)
    phone_number = models.CharField(_('Telefon'), max_length=20, blank=True)
    voen_number = models.CharField(_('VÖEN'), max_length=30, blank=True)
    fin_number = models.CharField(_('FİN'), max_length=20, blank=True)
    license_number = models.CharField(_('Lisenziya'), max_length=40, blank=True)

    def __str__(self):
        return self.username

【问题讨论】:

    标签: django django-models django-forms django-views django-templates


    【解决方案1】:

    要定义一个函数来散列密码,你必须为你的用户表单继承保存方法

        class CustomUserSignUpForm(forms.ModelForm):
        ............
        def save(self, commit=True):
            # Save the provided password in hashed format
            user = super(CustomUserSignUpForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password"])
            if commit:
                user.save()
            return user
    

    【讨论】:

    • 这个方法我已经试过了。它在 super 和 self 下有红线。错误如下:Bad first argument 'CustomUserSignUpForm' given to super()Instance of 'Meta' has no 'cleaned_data' member
    • 我用Meta类更改了这个方法,错误已经消失,但密码又不是散列
    • 打扰一下,试试user = super().save(commit=False)
    • 伙计,非常感谢你!你救了我的命。我很抱歉,但你能解释一下原因吗?为什么在删除 ```CustomUserSignUpForm, self```` 后它会起作用?
    • user = super().save(commit=False) 我们从 ModelForm 继承了参数 commit=False 的 save 方法,它不会立即保存实例,之后我们调用 set_password 方法对密码进行哈希处理,然后调用模型 save 方法进行保存它到数据库
    【解决方案2】:

    这种对 ModelForm 的覆盖更好,因为:
    我检查用户是否存在。
    如果密码未编码,则对密码进行哈希处理。

    class UsuarioAdmin(admin.ModelAdmin):
    ...
    
    def save_model(self, request, obj, form, change):
        try:
            user_database = USUARIO.objects.get(pk=obj.pk)
        except Exception:
            user_database = None
        if user_database is None \
                or not (check_password(form.data['password'], user_database.password)
                        or user_database.password == form.data['password']):
            obj.password = make_password(obj.password)
        else:
            obj.password = user_database.password
        super().save_model(request, obj, form, change)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-09
      • 2013-02-28
      • 1970-01-01
      • 2013-03-09
      • 2016-02-13
      • 2022-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多