我怎样才能避免用户在 Django 中注册一个已经使用过的电子邮件?

How can i avoid a user from registering an already used email in django?

我正在测试我的注册视图,我注意到如果我尝试使用一个已经存在的用户名进行注册,我会得到一个错误;如果我尝试使用现有的电子邮件注册,该应用程序会让我这样做。

显然,我不希望有人在我的网站上使用同一个电子邮件地址注册多个帐户。我是 Django 的新手,因为我注意到表单会检查用户名是否已经存在,所以我认为它会对电子邮件字段做同样的事情。

我真的不知道该怎么做,我应该处理我的观点还是表单?我怎样才能让它循环遍历我的数据库并查找是否已经注册了电子邮件?我以为 email = form.cleaned_data.get('email') 可以解决问题,但事实并非如此。 感谢任何帮助。

这是我的观点:

def register(request):
    if request.method == "POST":
        form = NewUserForm(request.POST)
        if form.is_valid():
            user = form.save()
            username = form.cleaned_data.get('username')
            email = form.cleaned_data.get('email')
            messages.success(request, f"New Account Created: {username}")
            login(request, user)
            messages.info(request, f"You are now logged in as {username}")
            return redirect("main:homepage")
        else:
            for msg in form.error_messages:
                messages.error(request, f"{msg}: {form.error_messages[msg]}")


    form = NewUserForm
    return render(request,
                  "main/register.html",
                  context={"form":form})

这是表格:

class NewUserForm(UserCreationForm):
    email = forms.EmailField(required=True)


    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2")


    def save(self, commit=True):
        user = super(NewUserForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        if commit:
            user.save()
        return user

根据您的代码,您需要做的就是从您的表单

ValidationError ]

class NewUserForm(UserCreationForm):
    email = forms.EmailField(required=True)

    <b>def clean_email(self):
        if User.objects.filter(email=self.cleaned_data['email']).exists():
            raise forms.ValidationError("the given email is already registered")
        return self.cleaned_data['email']</b>

    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2")

我可以帮忙 - 这就是我用来做这件事的东西。

从 forms.py 中的表格开始。 您已经在使用从 UserCreationForm 继承的表单(这很好)。 我的表单中包含的添加方法仅用于 class of 'input'.

的样式
class CustomUserCreationForm(UserCreationForm):

class Meta:
    model = User
    fields = ['first_name', 'email', 'username', 'password1', 'password2']
    labels = {
        'first_name': 'Name',
    }

def __init__(self, *args, **kwargs):
    super(CustomUserCreationForm, self).__init__(*args, **kwargs)

    for name, field in self.fields.items():
        field.widget.attrs.update({'class': 'input'})

然后在views.py中,我的代码是相似的,但是在'elif form.is_valid()'的测试之上,需要插入email变量和'if'语句来测试它是否已经存在. 如果电子邮件已经存在,则显示 message.error。 如果电子邮件不存在,则转到 'elif' 语句。 在 'elif' 之后,接下来的两行代码确保所有用户名都是小写的,然后通过 'user.save()' 保存用户,然后发生成功消息和重定向。

视图如下:

def registerUser(request):

form = CustomUserCreationForm()

if request.method == 'POST':
    form = CustomUserCreationForm(request.POST)
    

    email = request.POST['email']
    if User.objects.filter(email=email).exists():
        messages.error(request, 'That email is already in use')


    elif form.is_valid():
        user = form.save(commit=False)
        user.username = user.username.lower()
        user.save()

        messages.success(request, 'User account was created!')

        login(request, user)
        return redirect('edit-account')
    
    else:
        messages.error(request, 'An error has occured during registration')

context = {'page': page, 'form': form}
return render(request, 'users/login_register.html', context)

现在这是与上述表单和视图一起使用的模板。 外层 'for loop' 遍历表单中的字段并输出(使用 forms.py 中应用的样式)和内层循环,遍历任何错误消息(由 UserCreationForm 提供)并在字段附近输出(这些错误不会包括通过 'from django.contrib import messages').

处理的电子邮件重复警告消息

模板:

      <form method="POST" action="{% url 'register' %}" class="form auth__form">
      {% csrf_token %}

      {% for field in form %}
      <div class="form__field">
          <label for="formInput#text">{{field.label}}</label>
          {{field}}

          {% for error in field.errors %}
          <p style="color: red;">{{error}}</p>
          {% endfor %}

      </div>

      {% endfor %}

      <div class="auth__actions">
          <input class="btn btn--sub btn--lg" type="submit" value="Sign  In" />
      </div>
  </form>

如果您使用的是 main.html(由其他模板扩展),则将以下代码放在 main.html 中的“{% block content %}”标签上方。以下代码将循环遍历所有出现的消息并输出到页面顶部。 当用户尝试使用已在使用的电子邮件地址注册时,以下内容将包含 warning/error 消息。

{% if messages %}

{% for message in messages %}
<div class="alert  alert--{{message.tags}}">
    <p class="alert__message">{{message}}</p>
    <button class="alert__close">x</button>
</div>

{% endfor %}

{% endif %}

一定要在 views.py 的顶部导入这个: 来自 django.contrib 导入消息

并且一定要在 forms.py 的顶部导入它: 从 django.contrib.auth.forms 导入 UserCreationForm