简体   繁体   中英

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

I was testing my registration view and i noticed that if i try to register using an alreaxy existing Username, i'll get an error; if i try to register using an already existing email, the app will let me do so.

Obviously, i don't want someone to register multiple accounts with the same email on my site. I'm fairly new to Django, and since i noticed that the form checked if an username already exists, i thought it would do the same with the email field.

I don't really know how to go from that, should i work on my view or on the form? And how can i make it loop through my DB and find if an e-mail had already been registered? I thought email = form.cleaned_data.get('email') would do the trick, but it didn't. Any help is appreciated.

Here is my view:

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})

And here is the 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

According to your code, all you need to do is raise a ValidationError from your form


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

    

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

I can help - here is what I use for this very thing.

Starting with the form in forms.py. You are already using a form that inherits from UserCreationForm (this is good). The added method included with my form is just for styling with 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'})

Then in the views.py, my code is similar but above the test for 'elif form.is_valid()', one needs to insert the email variable and the 'if' statement to test if it already exists. If the email already exists then display the message.error. If the email doesnt exist then move onto the 'elif' statement. After the 'elif' the next two lines of code ensure any username is all lowercase before subsequently the user is saved via 'user.save()' and then success messages and redirects take place.

Here is the view:

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)

Now here is the Template that goes with the above form and view. The outer 'for loop', loops through the fields in form and outputs (with the styling applied in forms.py) and the inner loop, loops through any error messages (provided by UserCreationForm) and outputs adjacent the field (these errors wont include the email duplicate warning message, that is handled via 'from django.contrib import messages').

Template:

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

If you are using a main.html (that is extended by other templates), then place the following code above the '{% block content %}' tags in main.html. The following code will loop through any messages as they occur and output towards the top of your page. The following will include the warning/error message when a user attempts to register with an email address already in use.

{% 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 %}

Be sure to have imported this at top of views.py: from django.contrib import messages

And be sure to have imported this at top of forms.py: from django.contrib.auth.forms import UserCreationForm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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