Can someone explain how to validate an email adress in Django?
So for Example i want to check if an email is a valid college email adress with the ending .edu .
How can i do that?
from django import forms
from .models import SignUp
class SignUpForm(forms.ModelForm):
class Meta:
model = SignUp
fields = ['full_name','email']
def clean_email(self):
email = self.cleaned_data.get('email')
return email
Assuming that your SignUp.email field is an EmailField, Django will take care of validating that it's a valid email address. All you need to do is check that it ends in .edu, and raise a ValidationError if it doesn't.
class SignUpForm(forms.ModelForm):
class Meta:
model = SignUp
fields = ['full_name','email']
def clean_email(self):
email = self.cleaned_data.get('email')
if not email.endswith('.edu'):
raise forms.ValidationError("Only .edu email addresses allowed")
return email
If might be better to create a validator and add it to your model field. This way, Django will run your validator when you use your SignUpForm and when it does model validation in other places like the Django admin.
from django.core.exceptions import ValidationError
def validate_edu_email_address(value):
if email.endswith('.edu'):
raise forms.ValidationError("Only .edu email addresses allowed")
class SignUp(models.Model):
email = models.EmailField(validators=[validate_edu_email_address])
...
Just create a regular expression for your needs, or even better use some standard one.
import re
EMAIL_REGEX = r"(^[a-zA-Z0-9_.+-]+#[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
# EMAIL_REGEX = r'\w+#\.edu' # If you only want to allow edu.
class SignUpForm(forms.ModelForm):
...
def clean_email(self):
email = self.cleaned_data.get('email')
if email and not re.match(EMAIL_REGEX, email):
raise forms.ValidationError('Invalid email format')
return email
In fact, even better approach would be to use EmailField as #Alasdair suggested, that would automatically ensures the same for you (unless you really need to limit the email addresses to your custom format).
Related
I am trying to do validation for model forms to check if both 'email' and 'confirm_email' have same value. I tried searching online but getting some errors. I am making custom validators in models.py file.
Can you please help me with that. What would be the best way of validating model forms.
Here is my code.
MODELS.PY
from django.db import models
from django.core import validators
from django.core.exceptions import ValidationError
# Create your models here.
def validate_equal(self, email, confirm_email):
if email != confirm_email:
raise ValidationError(
('email does not match'),
params={'email': email, 'confirm_email': confirm_email}
)
class NewSubscriber(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField(max_length=254,unique=True)
confirm_email = models.EmailField(max_length=254, validators=[validate_equal('self', 'email', 'confirm_email')])
You can't do validation like that, especially when you want to compare fields. All you're doing here is passing the literal strings 'email' and 'confirm_email' (as well as 'self', for some reason) - and you're calling the validation function at define time.
Instead, use a clean method on the form itself.
class NewSubscriberForm(forms.ModelForm):
class Meta:
fields = '__all__'
def clean(self):
if self.cleaned_data['email'] != self.cleaned_data['confirm_email']:
raise forms.ValidationError('email does not match')
return self.cleaned_data
from django import forms
from .models import SignUp
class forml(forms.ModelForm):
class Meta:
model = SignUp
fields = ['Email', 'Name']
# exclude =['sam']
def clean_email(self):
email = self.cleaned_data.get('Email')
email_base, ext = email.split("#")
exname, domain = ext.split(".")
if not domain == "gov":
raise forms.ValidationError("plz write .gov")
return email
here i'm trying to force the user to sign up with .gov email but for a reason that i can't know it's doing the work !
Your problem is with the uppercase field names.
have you tried calling def clean_Email(self): ???
Also, consider having all your fields lowercase. In python, only class name should be Camelcase.
Hope it helps.
I've got a Django Model Form and I am trying to set the username field equal to the email field.
Here's my form
class UserForm(forms.ModelForm):
email = forms.EmailField()
username = forms.CharField(widget=forms.HiddenInput())
class Meta:
model = User
fields = ('email', 'username')
I am currently using some JavaScript to copy the new email value to the username hidden input before the user submits the form but I would like to do this server side.
I've tried to set it by doing the following UserForm['username'] = email before saving the form and got the following error object does not support item assignment.
Any tips would be appreciated.
I did not test this, I think it would work. If not check out overriding the save method which definitely works. Django Model Field Default Based Off Another Field in Same Model
class UserForm(forms.ModelForm):
email = forms.EmailField()
username = forms.CharField(default=email)
class Meta:
model = User
fields = ('email', 'username')
Maybe it will be useful
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import User
more info
enter link description here
class UserForm(UserCreationForm):
class Meta:
model = User
fields = ('email', 'username')
email = forms.EmailInput(attrs={'placeholder': "Email"})
def save(self, commit=True):
user = super(UserForm, self).save(commit=False)
user.username = user.email
if commit:
user.save()
return user
I'm using Django 1.5 & Python 3.2.3.
I've got a custom Auth setup, which uses an email address instead of a username. There's no username defined in the model at all. That works fine. Yet, when I build a user creation form, it adds in a username field anyway. So I tried defining exactly which fields I want displayed, but it's still forcing a username field into the form anyway.... even tho it doesn't even exist in the custom auth model. How can I make it stop doing that?
My form for this is defined like so:
class UserCreateForm(UserCreationForm):
class Meta:
model = MyUsr
fields = ('email','fname','surname','password1','password2',
'activation_code','is_active')
At the docs, the Custom Users and Builtin Forms says it "Must be re-written for any custom user model." and I think that's what I'm doing here. Neither this, nor the UserCreationForm documentation say anything more about this though. So I don't know what I'm missing. I didn't find anything via Google either.
Your UserCreationForm should look something like
# forms.py
from .models import CustomUser
class UserCreationForm(forms.ModelForm):
password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
password2 = forms.CharField(label="Password confirmation", widget=forms.PasswordInput)
class Meta:
model = CustomUserModel
# Note - include all *required* CustomUser fields here,
# but don't need to include password1 and password2 as they are
# already included since they are defined above.
fields = ("email",)
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
msg = "Passwords don't match"
raise forms.ValidationError("Password mismatch")
return password2
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
You'll also want a user change form, which won't overrwrite the password field:
class UserChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField()
class Meta:
model = CustomUser
def clean_password(self):
# always return the initial value
return self.initial['password']
Define these in your admin like this:
#admin.py
from .forms import UserChangeForm, UserAddForm
class CustomUserAdmin(UserAdmin):
add_form = UserCreationForm
form = UserChangeForm
You'll also need to override list_display, list_filter, search_fields, ordering, filter_horizontal, fieldsets, and add_fieldsets (everything in django.contrib.auth.admin.UserAdmin that mentions username, I think I listed all of it).
You need to create your form from sctratch, it should not extend the UserCreationForm. The UserCreationForm have a username field explicitly defined in it as well as some other fields. You can look at it here.
Hi Here's a snippet from my admin.py
#admin.py
class UserForm(forms.ModelForm):
class Meta:
model = User
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError("This email already used")
return email
class UserAdmin(admin.ModelAdmin):
form = UserForm
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
I use this to check that a new user cannot be created with an email address already used. The problem is that when I edit an existing user the validation check fails, because there is a user with that mail address, but that's OK because it's the one I'm editing.
How can I tell the form validation to ignore the match against the current user?
Exclude the current instance from your query:
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exclude(pk=self.instance.pk).exists():
raise forms.ValidationError("This email already used")
return email
It's much more better to validate uniqueness using unique on model field.
You can use custom User model with unique email constraint.
Look at this for more info about implementing unique validation on your own https://stackoverflow.com/a/1560617/527064