如何在Django中将邮箱同时作为用户名存入数据库?
实现邮箱作为用户名的注册页面解决方案
1. 修改表单文件(forms.py)
创建仅展示邮箱、密码、重复密码的表单,同时在保存用户时自动将邮箱地址赋值给username字段,适配Django User模型要求:
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django import forms class EmailAsUsernameSignUpForm(UserCreationForm): email = forms.EmailField( max_length=254, required=True, help_text='请输入有效的邮箱地址' ) class Meta: model = User fields = ['email', 'password1', 'password2'] # 仅保留需要的三个字段 def save(self, commit=True): user = super().save(commit=False) # 将邮箱赋值给username字段 user.username = self.cleaned_data['email'] if commit: user.save() return user def clean_email(self): # 验证邮箱唯一性 email = self.cleaned_data.get('email') if User.objects.filter(email=email).exists(): raise forms.ValidationError('该邮箱已被注册') return email
2. 更新注册视图(views.py)
函数视图修改
替换原Example_register视图,使用新表单:
@unauthenticatedUser def Example_register(request): form = EmailAsUsernameSignUpForm() if request.method == 'POST': form = EmailAsUsernameSignUpForm(request.POST) if form.is_valid(): user = form.save() # 添加用户到指定分组 group = Group.objects.get(name='studends') user.groups.add(group) messages.success(request, '账号创建成功,请登录') return redirect('login') context = {'form': form} return render(request, 'exampl_register.html', context)
类视图(带邮箱验证)修改
如果使用SignUpView类视图,替换表单并保留原有激活逻辑:
class SignUpView(View): form_class = EmailAsUsernameSignUpForm template_name = 'signup.html' def get(self, request, *args, **kwargs): form = self.form_class() return render(request, self.template_name, {'form': form}) def post(self, request, *args, **kwargs): form = self.form_class(request.POST) if form.is_valid(): user = form.save(commit=False) user.is_active = False # 激活前禁用账号 user.save() # 发送激活邮件 current_site = get_current_site(request) subject = '激活你的账号' message = render_to_string('account_activation_email.html', { 'user': user, 'domain': current_site.domain, 'uid': urlsafe_base64_encode(force_bytes(user.pk)), 'token': account_activation_token.make_token(user), }) user.email_user(subject, message) messages.success(request, '请检查邮箱完成账号激活') return redirect('login') return render(request, self.template_name, {'form': form})
3. 注册页面模板示例
确保模板仅渲染表单的三个字段(以exampl_register.html为例):
<form method="POST"> {% csrf_token %} <div> {{ form.email.label_tag }} {{ form.email }} {% if form.email.errors %} <span class="error">{{ form.email.errors.0 }}</span> {% endif %} </div> <div> {{ form.password1.label_tag }} {{ form.password1 }} {% if form.password1.errors %} <span class="error">{{ form.password1.errors.0 }}</span> {% endif %} </div> <div> {{ form.password2.label_tag }} {{ form.password2 }} {% if form.password2.errors %} <span class="error">{{ form.password2.errors.0 }}</span> {% endif %} </div> <button type="submit">完成注册</button> </form>
关键说明
- 原登录逻辑无需修改:你已实现用邮箱作为
username参数调用authenticate,与邮箱赋值给username的逻辑完全匹配。 - Profile模型及信号保持不变:用户创建时会自动生成关联的Profile记录。
内容的提问来源于stack exchange,提问作者user19433213
相关产品推荐
相关产品推荐

