How to create password input field in django - 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'}))

Related

Overwrite maxlength/minlength of username by Django User model in the ModelForm

Try to overwrite User models by the following code, but somehow I cannot overwrite the max_length and min_length of username.
More specifically, when I check by python manage.py shell, I do overwrite them. But it seems has no effect on the html which was rendered(username maxlength is still 150).
Don't know which parts get wrong, please help.
from django import forms
from django.contrib.auth.models import User
class RegistrationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
email = self.fields['email']
username = self.fields['username']
email.required = True
email.label_suffix = ' '
username.label_suffix = ' '
######### this is not work!!!###############
username.min_length = 6
username.max_length = 30
############################################
class Meta:
model = User
fields = ('username', 'email')
labels = {
'username': '帳號',
}
help_texts = {
'username': '',
}
Instead of modifying the form, you should modify/override the model.
I recommend using django-auth-tools for building your own custom user model. It supplies basic models, views and forms which can be easily extended.
If you are trying to override just the model form field, you could do something like this
class RegistrationForm(forms.ModelForm):
username = forms.CharField(required=True, min_length=6, max_length=30)
class Meta:
model = User
fields = ('username', 'email')
or
class RegistrationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields['username'] = forms.CharField(required=True, min_length=6, max_length=30)
class Meta:
model = User
fields = ('username', 'email')
But I would recommend creating a Custom User Model inherited from AbstractBaseUser to override the username or email field as documented in https://docs.djangoproject.com/en/1.10/topics/auth/customizing/

How to make UserCreationForm email field required

I am a newbie in Django.
I would like the email field in the subclassed UserCreationForm to be required.
I have tried the commented methods but none has worked so far. I have tried the solution from this but to no avail. Any help would be appreciated.
class MyRegistrationForm(UserCreationForm):
captcha = NoReCaptchaField()
#email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'class': 'mdl-textfield__input'}))
class Meta:
model = User
fields = ('first_name', 'last_name', 'username', 'email', 'password')
#email = {
# 'required': True
#}
widgets = {
'first_name': forms.TextInput(attrs={'class': 'mdl-textfield__input'}),
'last_name': forms.TextInput(attrs={'class': 'mdl-textfield__input'}),
'username': forms.TextInput(attrs={'class': 'mdl-textfield__input'}),
#'email': forms.TextInput(attrs={'class': 'mdl-textfield__input'})
}
def save(self, commit=True):
user = super(MyRegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data["first_name"]
user.last_name = self.cleaned_data["last_name"]
user.username = self.cleaned_data["username"]
user.email = self.cleaned_data["email"]
#user.user_level = self.cleaned_data["user_level"]
if commit:
user.save()
return user
def __init__(self, *args, **kwargs):
super(MyRegistrationForm, self).__init__(*args, **kwargs)
self.fields['password1'].widget.attrs['class'] = 'mdl-textfield__input'
self.fields['password2'].widget.attrs['class'] = 'mdl-textfield__input'
#self.fields['email'].required=True
This solved the problem: email = forms.CharField(required=True, widget=forms.EmailInput(attrs={'class': 'validate',}))
I checked Django's User model and it has required=False. So, I think you cannot achieve what you are looking for with the default User model based on note section of "Overriding the default fields" in the django documentation. I have inluded the snippet
ModelForm is a regular Form which can automatically generate certain
fields. The fields that are automatically generated depend on the
content of the Meta class and on which fields have already been
defined declaratively. Basically, ModelForm will only generate fields
that are missing from the form, or in other words, fields that weren’t
defined declaratively.
Fields defined declaratively are left as-is, therefore any
customizations made to Meta attributes such as widgets, labels,
help_texts, or error_messages are ignored; these only apply to fields
that are generated automatically.
Similarly, fields defined declaratively do not draw their attributes
like max_length or required from the corresponding model. If you want
to maintain the behavior specified in the model, you must set the
relevant arguments explicitly when declaring the form field.
For example, if the Article model looks like this:
class Article(models.Model):
headline = models.CharField(
max_length=200,
null=True,
blank=True,
help_text='Use puns liberally',
)
content = models.TextField() and you want to do some custom validation for headline, while keeping the blank and help_text values
as specified, you might define ArticleForm like this:
class ArticleForm(ModelForm):
headline = MyFormField(
max_length=200,
required=False,
help_text='Use puns liberally',
)
class Meta:
model = Article
fields = ['headline', 'content'] You must ensure that the type of the form field can be used to set the contents of the corresponding
model field. When they are not compatible, you will get a ValueError
as no implicit conversion takes place.
So try this,
from django.forms import EmailField
from django.core.validators import EMPTY_VALUES
# I used django [emailfield code][2] as reference for the code of MyEmailField
# Also, following comment in django [custom form fields document][2]:
# If the built-in Field classes don’t meet your needs, you can easily create custom Field classes. To do this, just create a subclass of django.forms.Field. Its only requirements are that it implement a clean() method and that its __init__() method accept the core arguments mentioned above (required, label, initial, widget, help_text).
# You can also customize how a field will be accessed by overriding get_bound_field().
class MyEmailField(forms.EmailField):
def __init__(self, *args, **kwargs):
super(MyEmailField, self).__init__(*args, strip=True, **kwargs)
# Clean would be called when checking is_clean
def clean(self,value):
if value in EMPTY_VALUES:
raise Exception('Email required')
value = self.value.strip()
return super(MyEmailField, self).clean(value)
class MyRegistrationForm(UserCreationForm):
captcha = NoReCaptchaField()
# All available arguments listed in django [core fields argument document][2]. Currently they are required, label, label_suffix, initial, widget, help_text, error_messages, validators, localize, disabled
email = MyEmailField(required=True)
class Meta:
model = User
fields = ('first_name', 'last_name', 'username', 'email', 'password')
# other part of your code
PS: I have not tested this code but based on the documentation I think this should take you in a good direction.
Few more references:
Django auth.user with unique email
How to make email field unique in model User from contrib.auth in Django
https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
Add this to your forms.py file:
class Userform(UserCreationForm):
email = forms.EmailField(required=True)
class meta:
model = User
fields = ('name','email')

django admin form won't be modify

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.

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

Django PasswordInput

I'm using PasswordInput, for an attribute that is optional.
models.py
password = models.CharField(_('Site Password'), max_length=128,
blank=True, null=True)
forms.py
from django.forms import PasswordInput
...
class Meta:
model = ...
widgets = {
'password': PasswordInput(),
}
Which works as expected. However using this widget means there is no way to clear this input, once the password has been set once!
I was hoping to have something like the AdminFileWidget, where there is an option to clear the image/file by selecting the 'clear' checkbox.
Other option is to add an additional 'clear_password' field to the ModelForm.
clear_password = forms.BooleanField(label=_('Clear'), initial=False,
required=False)
And clear the password on save method:
def save(self, commit=True):
...
if self.cleaned_data['clear_password']:
obj.password = None
else:
# Save the provided password in hashed format
obj.password = make_password(self.cleaned_data['password'])
And this works too. But I was hoping a more cleaner solution ..
I had a look at django.forms.widgets.ClearableFileInput .. but it's way too complex for a newbie like me :-(.
Any help will be appreciated. Many Thanks
You could clear the value of the form by passing a null value to the value attribute.
Something like that :
from django.forms import PasswordInput
from models import YourModel
password = forms.PasswordInput(attrs={'value': ''})
class Meta:
model = YourModel