Django自定义UserCreationForm无法从forms.py导入views.py如何解决
问题根因
你的UserRegisterForm无法导入的核心问题是forms.py存在缩进错误:UserRegisterForm被错误嵌套写在了UserLoginForm类的内部,不属于模块顶层可直接导入的成员,而同层级的UserLoginForm本身是顶层类,所以可以正常导入。
同时你的代码还存在另外两处会导致运行报错的问题:
UserCreationForm内置的密码字段为password1(输入密码)、password2(确认密码),你表单Meta中声明的password字段不存在- 注册视图中
password = form.save(commit=False)写法错误,save(commit=False)返回的是用户对象,无法直接获取密码
修正后的forms.py代码
from django import forms from django.contrib.auth import authenticate from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User class UserLoginForm(forms.Form): username = forms.CharField() password = forms.CharField(widget=forms.PasswordInput) def clean(self, *args, **kwargs): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') if username and password: user = authenticate(username=username, password=password) if not user: raise forms.ValidationError('This user does not exist') if not user.check_password(password): raise forms.ValidationError('Incorrect password') if not user.is_active: raise forms.ValidationError('This user is not active') return super(UserLoginForm, self).clean(*args, **kwargs) # 缩进拉到和UserLoginForm同级,成为模块顶层类 class UserRegisterForm(UserCreationForm): email = forms.EmailField(label='Email address') email2 = forms.EmailField(label='Confirm email') class Meta: model = User fields = [ 'username', 'email', 'email2', 'password1', # 替换为UserCreationForm内置的密码字段 'password2' ] # 改为全局clean方法,才能同时获取两个邮箱字段做校验 def clean(self): cleaned_data = super().clean() email = cleaned_data.get('email') email2 = cleaned_data.get('email2') if email != email2: raise forms.ValidationError("emails must match") email_qs = User.objects.filter(email=email) if email_qs.exists(): raise forms.ValidationError( "This email is already being used" ) return cleaned_data
修正后的注册视图代码
def register_view(request): next = request.GET.get('next') form = UserRegisterForm(request.POST or None) if form.is_valid(): user = form.save(commit=False) # UserCreationForm会自动处理密码加密,直接保存即可 user.save() new_user = authenticate(username=user.username, password=form.cleaned_data.get('password1')) login(request, new_user) if next: return redirect(next) return redirect('/') context = { 'form': form, } return render(request, 'signup.html', context)
修正后即可正常导入UserRegisterForm,注册功能也能正常运行。
内容的提问来源于stack exchange,提问作者Jie-Liang Lin
相关产品推荐
相关产品推荐

