django admin form won't be modify - django

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.

Related

Validation for model forms

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

Check Email Validation Django

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

Django Forms - Set username field equal to email field

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

Manager isn't available; User has been swapped for 'pet.Person'

I'm been using the default user model in django for quite a abit and I realize , if I need to further enhance it , I would have to create my own custom User Model in django 1.5 .
I created my custom user model and I have a function which allows users to sign in .
I think my custom user model is incompatible with my function because it wouldn't allow me to do request.user . How can I fix this so I can use request.user again?
views
def LoginRequest(request):
form = LoginForm(request.POST or None)
if request.user.is_authenticated():
username = User.objects.get(username=request.user)
url = reverse('world:Profile', kwargs = {'slug': person.slug})
return HttpResponseRedirect(url)
if request.POST and form.is_valid():
user = form.authenticate_user()
login(request, user)
username= User.objects.get(username=request.user)
person = Person.objects.get(user=request.user)
url = reverse('world:Profile', kwargs = {'slug': person.slug})
return HttpResponseRedirect(url)
return render(request, 'login.html',{'form': form})
models
class PersonManager(BaseUserManager):
def create_user(self, email,date_of_birth, username,password=None,):
if not email:
msg = 'Users must have an email address'
raise ValueError(msg)
if not username:
msg = 'This username is not valid'
raise ValueError(msg)
if not date_of_birth:
msg = 'Please Verify Your DOB'
raise ValueError(msg)
user = self.model(
email=PersonManager.normalize_email(email),username=username,date_of_birth=date_of_birth)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email,username,password,date_of_birth):
user = self.create_user(email,password=password,username=username,date_of_birth=date_of_birth)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Person(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(verbose_name='email address',max_length=255,unique=True,db_index=True,)
username = models.CharField(max_length=255, unique=True)
date_of_birth = models.DateField()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'date_of_birth',]
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
objects = PersonManager()
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def __unicode__(self):
return self.email
The problem is that User refers to django.contrib.auth.models.User and now you have got a Custom User pet.Person assuming you have in the settings.py
AUTH_USER_MODEL = "pet.Person"
you have to define User with the Custom User model and you can do this with get_user_model at the top of the file where you use User
from django.contrib.auth import get_user_model
User = get_user_model()
now you will be able to use Custom User model and the problem has been fixed.
For anyone else who might come across this problem, I also solved it by simply doing this on forms.py:
add this at the top of the forms.py file
from .models import YourCustomUser
and then add this to your forms.py CustomUser form:
class SignUpForm(UserCreationForm):
#profile_year = blaaa blaa blaaa irrelevant.. You have your own stuff here don't worry about it
# here is the important part.. add a class Meta-
class Meta:
model = YourCustomUser #this is the "YourCustomUser" that you imported at the top of the file
fields = ('username', 'password1', 'password2', #etc etc, other fields you want displayed on the form)
BIG NOTES, ATTENTION:
This code worked for my case. I have a view for signing users up, I had a problem here and I solved it, I haven't tried it for logging in users.
The include = () part is required, or you can add exclude = (), but you have to have one
Important caveat to update the above solutions...
If you're facing this kind of problem, you've probably tried various solutions around the web telling you to add AUTH_USER_MODEL = users.CustomUser to settings.py and then to add the following code to views.py forms.py and any other file that calls User:
from django.contrib.auth import get_user_model
User = get_user_model()
And then you scratch your head when you get the error:
Manager isn't available; 'auth.User' has been swapped for 'users.User'
Anytime your code references User such as:
User.objects.get()
Cause you know you already put objects = UserManager() in your custom user class (UserManager being the name of your custom manager that extends BaseUserManager).
Well as it turns out doing:
User = get_user_model() # somewhere at the top of your .py file
# followed by
User.objects.get() # in a function/method of that same file
Is NOT equivalent to:
get_user_model().objects.get() # without the need for User = get_user_model() anywhere
Perhaps not intuitive, but it turns out that that in python, executing User = get_user_model() once at the time of import does not then result in User being defined across subsequent calls (i.e. it does not turn User into a "constant" of sorts which you might expect if you're coming from a C/C++ background; meaning that the execution of User = get_user_model() occurs at the time of imports, but is then de-referenced before subsequent called to class or function/method in that file).
So to sum up, in all files that reference the User class (e.g. calling functions or variables such as User.objects.get() User.objects.all() User.DoesNotExist etc...):
# Add the following import line
from django.contrib.auth import get_user_model
# Replace all references to User with get_user_model() such as...
user = get_user_model().objects.get(pk=uid)
# instead of user = User.objects.get(pk=uid)
# or
queryset = get_user_model().objects.all()
# instead of queryset = User.objects.all()
# etc...
Hope this helps save others some time...
In forms.py
# change
from django.contrib.auth.models import User
# to
from django.contrib.auth import get_user_model
Then add the following code at the top
User = get_user_model()
All the solutions provided above did not work in my case. If you using Django version 3.1 there is another solution for you:
In auth/forms, comment out line 10 and change the model in line 104 & 153 to your defined model.

How to create password input field in django

Hi I am using the django model class with some field and a password field. Instead of displaying regular plain text I want to display password input. I created a model class like this:
class UserForm(ModelForm):
class Meta:
password = forms.CharField(widget=forms.PasswordInput)
model = User
widgets = {
'password': forms.PasswordInput(),
}
But i am getting the following error: NameError: name 'forms' is not defined.
I am using django version 1.4.0. I followed this link : Django password problems
Still getting the same error. What should i do. Where am i getting wrong.Please help
The widget needs to be a function call, not a property. You were missing parenthesis.
class UserForm(ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
You need to include the following in your imports;
from django import forms
Why not just create your own password field that you can use in all your models.
from django import forms
class PasswordField(forms.CharField):
widget = forms.PasswordInput
class PasswordModelField(models.CharField):
def formfield(self, **kwargs):
defaults = {'form_class': PasswordField}
defaults.update(kwargs)
return super(PasswordModelField, self).formfield(**defaults)
So now in your model you use
password = PasswordModelField()
#DrTyrsa is correct. Don't forget your parentheses.
from django.forms import CharField, Form, PasswordInput
class UserForm(Form):
password = CharField(widget=PasswordInput())
I did as a follow without any extra import
from django import forms
class Loginform(forms.Form):
attrs = {
"type": "password"
}
password = forms.CharField(widget=forms.TextInput(attrs=attrs))
The idea comes form source code:
https://docs.djangoproject.com/en/2.0/_modules/django/forms/fields/#CharField
Since this question was asked a couple years ago, and it is well indexed on search results, this answer might help some people coming here with the same problem but be using a more recent Django version.
I'm using Django 1.11 but it should work for Django 2.0 as well.
Taking into account that you using a model user I will assume that you are using the default User() model from Django.
Since the User() model already has a password field, we can just add a widget to it.
from django import forms
from django.contrib.auth.models import User
# also, it will work with a custom user model if needed.
# from .models import User
class UserRegistrationForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'password']
widgets = {
# telling Django your password field in the mode is a password input on the template
'password': forms.PasswordInput()
}
Check the docs
I'm fairly new to Django, if my answer was not accurate enough, please let us know, I'd be happy to edit it later on.
** Try to use this **
password1 = forms.CharField(widget=forms.PasswordInput(attrs={
'class': 'input-text with-border', 'placeholder': 'Password'}))
password2 = forms.CharField(widget=forms.PasswordInput(attrs={
'class': 'input-text with-border', 'placeholder': 'Repeat Password'}))
It's very simple.
You should get password form field out of Meta class.
What was written by the OP at password = forms.Charfield(widget=forms.PasswordInput) was correct. It just does not belong in the class Meta: section. Instead, it should be above it, indented one level below class UserForm....
The solutions above works if the field is nullable. Using render_value will render the password into the input field and show the value as asterix placeholders.
Attention: This is great if you simply want to hide the password from users, but the password will be readable by using javascript.
class UserForm(forms.ModelForm):
class Meta:
model = Org
fields = '__all__'
widgets = {
'password': forms.PasswordInput(render_value=True),
}
Edit:
Found a better solution without exposing the current password.
PASSWORD_ASTERIX_PLACEHOLDER will be set as value when loading the input. Before saving the model, it reverts the value to the old one if a user is not setting an explicit new password.
FormInput:
class PrefilledPasswordInput(PasswordInput):
PASSWORD_ASTERIX_PLACEHOLDER: str = 'hidden-password'
def __init__(self, attrs: dict = None, *args, **kwargs):
if not attrs:
attrs = {}
attrs.setdefault('value', PrefilledPasswordInput.PASSWORD_ASTERIX_PLACEHOLDER)
super().__init__(attrs=attrs, *args, **kwargs)
ModelField:
class PasswordCharField(models.CharField):
def to_python(self, value):
return super().to_python(value)
def pre_save(self, model_instance, add):
attr_name = self.get_attname()
if not add:
# Reset to old value if matching with PASSWORD_ASTERIX_PLACEHOLDER
old_instance = self.model.objects.get(id=model_instance.id)
current_value: str = getattr(model_instance, attr_name)
if current_value == PrefilledPasswordInput.PASSWORD_ASTERIX_PLACEHOLDER:
old_value: str = getattr(old_instance, attr_name)
setattr(model_instance, attr_name, old_value)
return super().pre_save(model_instance, add)
Your admin-(form):
class UserForm(forms.ModelForm):
class Meta:
model = Org
fields = '__all__'
widgets = {
'password': PrefilledPasswordInput(),
}
Your model:
class User(SomeBaseModel):
...
password = PasswordCharField(max_length=32, null=False, blank=False)
from django import forms
class loginForm(forms.Form):
username = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Your userName'}))
password = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'please enter password'}))