【问题标题】:Django User with that username already exists具有该用户名的 Django 用户已存在
【发布时间】:2023-03-30 04:40:02
【问题描述】:

我的目标 - 尝试在 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')

views.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')

models.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

我的问题 - 我收到错误“使用该用户名的用户已经存在”我不知道当我尝试创建一个已经注册的新用户时这个错误出现的原因和位置用户名,但它的帐户尚未激活(user.is_active = False)。

据我所知,当我们在 views.py 中使用“form.is_valid()”时,会调用 clean_fields 函数来验证表单,但是我已经根据需要覆盖了“clean_username”,所以 为什么我收到此错误?它是从哪里生成的?以及如何解决这个问题?

我还想提一下,当用户注册时,它也是注册的“学生”,这就是我使用“regUser”功能的原因。此外,我在 stackoverflow thisthis 上阅读了与此类似的其他一些问题,一些答案是从“forms.Form”而不是“UserCreationForm”继承表单,但为什么有人可以解释?

请不要将此问题标记为已回答我已经回答了所有问题,但没有任何帮助。

【问题讨论】:

    标签: python html django authentication


    【解决方案1】:

    你定义的用户模型继承了AbstactUserusername在那里定义。

    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 模型中“不活动”意味着“已丢弃”,我建议在用户被停用时将用户的username 更改为垃圾值。

    【讨论】:

      猜你喜欢
      • 2017-08-05
      • 2017-07-06
      • 1970-01-01
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      相关资源
      最近更新 更多