0

This looks like a basic problem which I have not been able to solve.I have a simple HTML page with just a text box and a submit button.The text box is supposed to take email ids from users and store it in the DB upon clicking the submit button.Apart from the normal email format validation,I also need to check if the email already exists in the DB and then inform the user.My code is as follows:

models.py

from __future__ import unicode_literals
from django.db import models


class NotificationEmail(models.Model):
    email = models.EmailField(max_length=200)
    created = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return u'%s' % self.email

forms.py

from django import forms
from home.models import NotificationEmail

class NotifyForm(forms.ModelForm):
    class Meta:
        model = NotificationEmail
        fields = ['email']

    def check_duplicate_email(self):
        data = self.cleaned_data['email']
        if NotificationEmail.objects.filter(email=data).exists():
            raise forms.ValidationError('Your email is already in our list of users to be notified.Try a new email')

views.py

from django.shortcuts import render
from forms import NotifyForm

def notify(request):
    if request.method == 'POST':
        form = NotifyForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = NotifyForm()

    return render(request, 'index.html', {'form': form})

index.html

<form class="form-horizontal" method="POST" action ="">
    {% csrf_token %}
    <button type="submit">Notify Me</button>
    {{form.email}}
</form>

This saves emails in the DB upon clicking the submit button.However,it never checks for existing email ids and my DB has lots of duplicate ids.What am i doing wrong ?

Amistad
  • 7,100
  • 13
  • 48
  • 75
  • Rename `def check_duplicate_email(self):` to `def clean_email(self):`. Check [docs](https://docs.djangoproject.com/en/1.9/ref/forms/validation/#cleaning-a-specific-field-attribute). – JRodDynamite Apr 05 '16 at 08:23
  • did that and now it saves nothing to the DB.. – Amistad Apr 05 '16 at 08:35

2 Answers2

1

You can use the unique=True flag in the email field:

email = models.EmailField(max_length=200, unique=True)

dpdenton
  • 300
  • 1
  • 9
  • will that propagate as an error in the form validation for the templates ? – Amistad Apr 05 '16 at 08:21
  • yes it will - just make sure you render the error tags in the template – dpdenton Apr 05 '16 at 09:10
  • Yes..i did..However..i fixed this via the calling the clean_email method on my model form as it gave me more flexibility on what sort of error messages i could show on the template along with custom css classes – Amistad Apr 06 '16 at 09:19
1

from.is_valid() not call your check_duplicate_email() function.
You can write your custom validation like this:

def clean_email(self): data = self.cleaned_data['email'] if User.objects.filter(email=data).count() > 0: raise forms.ValidationError("We have a user with this user email-id") return data

For one more example Custom form validation

Community
  • 1
  • 1
GrvTyagi
  • 4,231
  • 1
  • 33
  • 40