首页 > 解决方案 > 登录表单写道“ ”已经存在

问题描述

所以,我有一个问题。我有一个登录表单,但是当我尝试登录时,它写道''已经存在。这怎么可能?如果用户有一个帐户,这意味着它会存在。但为什么我会犯这个错误?

视图.py

def login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST, request.FILES)
        print(form.errors)
        if form.is_valid():
            cd = form.cleaned_data
            user = authenticate(email=cd['email'], password=cd['password'])
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return HttpResponse('Authenticated successfully')
                else:
                    return HttpResponse('Disabled account')
            else:
                return HttpResponse('Invalid login')
        else:
            return HttpResponse('Form is not valid')
    else:
        form = LoginForm()
    return render(request, 'account/login.html', {'form': form})

我得到一个错误:

<ul class="errorlist"><li>email<ul class="errorlist"><li>User with this already exists.</li></ul></li></ul>

登录表单

class LoginForm(ModelForm):

    class Meta:
        model = User
        fields = ['email', 'password']

        widgets = {
            'email': EmailInput(attrs={
                'class': 'form-email',
                'placeholder': 'email'
            }),
            'password': PasswordInput(attrs={
                'class': 'form-password',
                'placeholder': 'password'
            })
        }

用户模型

class User(models.Model):
    CHOICES = (
        ('1', 'Author'),
        ('2', 'Customer'),
        ('3', 'Author and Customer')
    )
    first_name = models.CharField(max_length=64, blank=False, verbose_name='')
    last_name = models.CharField(max_length=64, blank=False, verbose_name='')
    patronymic = models.CharField(max_length=64, blank=False, verbose_name='')
    age = models.PositiveSmallIntegerField(verbose_name='', blank=False)
    email = models.EmailField(unique=True, max_length=128, blank=False, verbose_name='')
    password = models.CharField(max_length=32, blank=False, verbose_name='')
    role = models.CharField(max_length=32, choices=CHOICES, default='Customer')
    about = models.TextField(max_length=512, verbose_name='', blank=True)

标签: pythondjangoauthentication

解决方案


如果 aModelForm没有instance指定,则表示它正在用于创建实例,因此当is_valid在您的表单上调用时,它会发现您提供的用户名已经存在,因此它返回False。出于这个原因,用于登录用户的表单需要是一个普通的Form类。

进一步推进 Django 已经提供了一个可用于身份验证的内置表单django.contrib.auth.forms.AuthenticationForm[Django docs]。查看您的实现,您有一个自定义用户模型,其中电子邮件作为USERNAME_FIELDAuthenticationForm足够多才多艺来处理这个,所以你可以直接在你的视图中使用它(或者如果你想自定义你可以从它继承的表单小部件)。

如果要在小部件上设置属性,只需继承AuthenticationForm并在 forms__init__方法中设置它们:

from django.contrib.auth.forms import AuthenticationForm

class LoginForm(AuthenticationForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['username'].widget.attrs.update({'class': 'form-email', 'placeholder': 'email'})
        self.fields['password'].widget.attrs.update({'class': 'form-password', 'placeholder': 'password'})

接下来在您的视图中使用此表单:

def login(request):
    if request.method == 'POST':
        form = LoginForm(request, request.POST, request.FILES)
        print(form.errors)
        if form.is_valid():
            user = form.get_user()
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return HttpResponse('Authenticated successfully')
                else:
                    return HttpResponse('Disabled account')
            else:
                return HttpResponse('Invalid login')
        else:
            return HttpResponse('Form is not valid')
    else:
        form = LoginForm(request)
    return render(request, 'account/login.html', {'form': form})

推荐阅读