You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django admin后台调用自定义模型的set_password加密方法

当然可以,有三种常见的实现方案,可根据你的实际需求选择:

方案1:重写ModelAdmin的save_model方法(仅作用于Admin后台)

这是最贴合你需求的方案,只会修改Admin后台的保存逻辑,不会影响其他业务代码里的模型操作。
在你app的admin.py中添加如下代码:

from django.contrib import admin
from .models import MyModel

class MyModelAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # 仅当密码字段被修改时才做加密处理,避免重复加密
        if 'encrypted_pass' in form.changed_data:
            raw_pwd = form.cleaned_data['encrypted_pass']
            obj.set_password(raw_pwd)
        super().save_model(request, obj, form, change)

# 注册模型时绑定自定义的ModelAdmin
admin.site.register(MyModel, MyModelAdmin)

方案2:重写模型的save方法(全局生效)

如果你希望所有场景下保存模型时都自动加密密码(包括API、脚本等非Admin场景),可以直接修改模型的save逻辑:

from django.contrib.auth.hashers import make_password
from django.db import models
from django.utils import timezone

class MyModel(models.Model):
    name = models.CharField(max_length=255)
    created_on = models.DateTimeField(default=timezone.now)
    encrypted_pass = models.CharField(max_length=255, null=False)

    def set_password(self, raw_password):
        self.encrypted_pass = make_password(raw_password)

    def save(self, *args, **kwargs):
        # 新增对象 或 密码字段被修改时触发加密
        if not self.pk or MyModel.objects.get(pk=self.pk).encrypted_pass != self.encrypted_pass:
            self.set_password(self.encrypted_pass)
        super().save(*args, **kwargs)

方案3:自定义Admin表单(便于扩展校验规则)

如果你还需要给密码字段加强度校验、格式校验等逻辑,可以通过自定义表单实现:

from django import forms
from django.contrib import admin
from django.contrib.auth.hashers import make_password
from .models import MyModel

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ["name", "encrypted_pass"]
    
    def clean_encrypted_pass(self):
        raw_pwd = self.cleaned_data["encrypted_pass"]
        # 修改场景下如果用户没有修改密码,直接返回原有哈希值不重复加密
        if self.instance.pk and raw_pwd == self.instance.encrypted_pass:
            return raw_pwd
        # 这里还可以添加自定义的密码强度校验逻辑
        # if len(raw_pwd) < 8:
        #     raise forms.ValidationError("密码长度不能少于8位")
        return make_password(raw_pwd)

class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm

admin.site.register(MyModel, MyModelAdmin)

注意事项

所有方案都做了防重复加密的处理,避免已经加密的哈希值被二次加密导致密码校验失败。如果你的业务逻辑里有其他修改密码的入口,注意保持逻辑一致即可。

内容的提问来源于stack exchange,提问作者mp252

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:57:04