[英]Django User with that username already exists
我的目标- 尝试在 Django 中创建身份验证系统,并允许用户在未激活帐户时使用相同的用户名再次注册。
如果用户尝试使用某个用户名注册并且该用户名已经存在,则使用该当前用户更新该用户。
我的方法- 我使用“UserCreationForm”创建了一个表单并定义了我自己的方法来验证表单,并允许用户即使用户名已经存在但 user.is_active = False。
代码
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import User
class SignupForm(UserCreationForm):
email = forms.EmailField(max_length=200, help_text='Required')
name = forms.CharField()
institution = forms.CharField()
def clean_username(self):
username = self.cleaned_data.get('username')
user = None
try:
try:
user = User.objects.get(username=username)
print("is user active username", user.is_active)
except ObjectDoesNotExist as e:
pass
except Exception as e:
raise e
if not user:
pass
elif not user.is_active:
pass
else:
raise forms.ValidationError("This Username Already Exists")
except Exception as e:
raise e
return username
class Meta:
model = User
fields = ('username', 'email', 'institution', 'password1', 'password2')
视图.py
from .forms import SignupForm
def regUser(form):
'''
It will save Django user and student.
It recieves form.cleaned_data as argument
'''
print("reg user line 1")
user = User.objects.create_user(username=form['username'],
email=form['email'],
password=form['password1'],
is_active=False,
)
# notice is_active = False, becuase we will activate account if user will
# verify the email
user.save()
student = Student(user=user, name=form['name'], institution=form['institution'])
student.save()
return user
def signup(request):
if request.user.is_authenticated:
return redirect('accounts:home')
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
user = regUser(form.cleaned_data)
current_site = get_current_site(request)
message = render_to_string('accounts/acc_active_email.html', {
'user':user, 'domain':current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
mail_subject = 'Activate your account.'
to_email = form.cleaned_data.get('email')
email = EmailMessage(mail_subject, message, to=[to_email])
email.send()
return render(request, 'accounts/signup.html', {'email_sent': True})
else:
for field in form:
for error in field.errors:
messages.error(request, error)
return redirect("accounts:signup")
return render(request, 'accounts/signup.html')
模型.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
subject = models.CharField(max_length=250, default="default_value")
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=250, default="default_value")
institution = models.CharField(max_length=250, default="default_value")
def save(self):
super().save()
def __str__(self):
return self.user.username
我的问题- 我收到错误“具有该用户名的用户已经存在”当我尝试使用已注册的用户名创建新用户但帐户尚未激活时,我不知道为什么以及从何处出现此错误(用户.is_active = 假)。
据我所知,当我们在views.py中使用“form.is_valid()”时,会调用clean_fields函数来验证表单,但是我已经根据需要覆盖了“clean_username”,为什么会出现这个错误? 它是从哪里生成的? 以及如何解决这个问题?
另外我想提一下,当用户注册时,它也是注册的“学生”,这就是我使用“regUser”function 的原因。 另外我在stackoverflow上阅读了一些与此类似的其他问题, 这个答案是从“forms.Form”而不是“UserCreationForm”继承表单,但为什么有人可以解释?
请不要将此问题标记为已回答我已经解决了所有问题,但没有帮助。
您定义的用户 model 继承了AbstactUser
,并且在那里定义了username
。
class AbstractUser(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.
Username and password are required. Other fields are optional.
"""
username_validator = UnicodeUsernameValidator()
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
...
username
字段的属性unique
意味着用户名在所有用户中必须是唯一的,而不仅仅是活动用户。 (参考https://docs.djangoproject.com/en/3.1/ref/models/fields/#unique )
如果您想要允许用户在非活动用户中使用相同的用户名,请设置 unique=False。
但是,如果“非活动”在您的User
model 中意味着“丢弃”,我建议在用户被非激活时将用户的username
更改为垃圾值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.