繁体   English   中英

Django 该用户名的用户已存在

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM