簡體   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