Django复用UserCreationForm更新用户时避免重复生成随机密码
解决方案
核心逻辑:Django 的 ModelForm 可通过 self.instance.pk 判断当前操作是创建新用户还是更新已有用户,仅在创建新用户时执行密码生成逻辑即可。
修改后的表单代码
class EmployeeRegistrationForm(UserCreationForm): email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control mb-2', 'placeholder': 'Email address'})) first_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control mb-2', 'placeholder': 'First name'})) last_name = forms.CharField( widget=forms.TextInput(attrs={'class': 'form-control mb-2', 'placeholder': 'Last name'})) password1 = None password2 = None class Meta: model = User fields = ['email', 'first_name', 'last_name'] def clean(self): cleaned_data = super().clean() # 仅新用户生成随机密码 if not self.instance.pk: password = User.objects.make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789') cleaned_data['password1'] = password cleaned_data['password2'] = password return cleaned_data def save(self, commit=True): user = super().save(commit=False) user.email = self.cleaned_data['email'] user.first_name = self.cleaned_data['first_name'] user.last_name = self.cleaned_data['last_name'] if user.username == '': if len(user.first_name.split()) and len(user.last_name.split()) > 1: username = f'{"".join(user.first_name.split()[:2])}{"."}{"".join(user.last_name.split())}' elif len(user.first_name.split()) > 1: username = f'{"".join(user.first_name.split()[:2])}{"."}{user.last_name}' elif len(user.last_name.split()) > 1: username = f'{user.first_name}{"."}{"".join(user.last_name.split())}' else: username = f'{user.first_name}{"."}{user.last_name}' username = username.lower() user.username = username # 仅新用户设置密码 if not self.instance.pk: user.set_password(self.cleaned_data['password1']) if commit: user.save() return user
修改完成后原视图无需调整,编辑用户资料时将不再自动生成新密码,仅保留用户名、姓名、邮箱等字段的更新能力。
内容的提问来源于stack exchange,提问作者John Todorovic
相关产品推荐
相关产品推荐

