如何在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
相关产品推荐
相关产品推荐

