Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django UserCreationForm custom fields

I am trying to create form for user registration and add some custom fields. For doing that, I've subclassed UserCretionForm and added fields as shown in django documentation. Then I've created function-based view and template based on this form. Now, I can successfully create user and this user is added to admin panel as expected. Problem is that, I can't add class and style for this form's fields. Widgets are not working except for username field. I'm adding my scripts here for illustrating my problem more accurately:

forms.py

from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User


class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=32, help_text='First name')
    last_name = forms.CharField(max_length=32, help_text='Last name')
    email = forms.EmailField(max_length=64, help_text='Enter a valid email address')

    class Meta(UserCreationForm.Meta):
        model = User
        # I've tried both of these 'fields' declaration, result is the same
        # fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', )
        fields = UserCreationForm.Meta.fields + ('first_name', 'last_name', 'email',)

        widgets = {
            'username': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Username'}),
            'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First Name'}),
            'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last Name'}),
            'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}),
            'password1': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password'}),
            'password2': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password Again'}),
        }

views.py

from django.contrib.auth import login, authenticate
from django.contrib.auth.views import LoginView
from django.shortcuts import render, redirect

from .forms import SignUpForm, SignInForm


def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=username, password=raw_password)
            login(request, user)
            return redirect('/')
    else:
        form = SignUpForm()
    return render

Widgets in 'forms.py' are not working except for 'username' field. In other words, in web browser 'username' input is shown with "class='form-control'" and "placeholder='Username'", but other fields don't have class and placeholder attribute as I expected. What can be the reason?

like image 491
Elgin Cahangirov Avatar asked Jan 01 '18 12:01

Elgin Cahangirov


People also ask

What is UserCreationForm in Django?

Django UserCreationForm is used for creating a new user that can use our web application. It has three fields: username, password1, and password2(which is basically used for password confirmation). To use the UserCreationForm, we need to import it from django.

How do I add a field in Django?

To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB.

What is usercreationform in Django?

Django UserCreationForm is used for creating a new user that can use our web application. It has three fields: username, password1, and password2 (which is basically used for password confirmation).

How do I create a new user in Django?

Django Creating Users using UserCreationForm Last updated on July 27, 2020 Django authentication framework provides a form named UserCreationForm (which inherits from ModelForm class) to handle the creation of new users. It has three fields namely username, password1 and password2 (for password confirmation).

What are the primary attributes of a user in Django?

User objects consist of the following primary attributes. Django UserCreationForm is used for creating a new user that can use our web application. It has three fields: username, password1, and password2 (which is basically used for password confirmation). To use the UserCreationForm, we need to import it from django.contrib.auth.forms.

What are the fields of usercreationform?

It has three fields: username, password1, and password2 (which is basically used for password confirmation). To use the UserCreationForm, we need to import it from django.contrib.auth.forms.


2 Answers

You don't need to define fields unders widgets. Define them as static at class level.

class SignUpForm(UserCreationForm):
    username = forms.CharField(forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Username'}))
    first_name = forms.CharField(forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First Name'}), max_length=32, help_text='First name')
    last_name=forms.CharField(forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last Name'}), max_length=32, help_text='Last name')
    email=forms.EmailField(forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}), max_length=64, help_text='Enter a valid email address')
    password1=forms.CharField(forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password'}))
    password2=forms.CharField(forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password Again'}))

    class Meta(UserCreationForm.Meta):
        model = User
        # I've tried both of these 'fields' declaration, result is the same
        # fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', )
        fields = UserCreationForm.Meta.fields + ('first_name', 'last_name', 'email',)
like image 87
Chirdeep Tomar Avatar answered Oct 21 '22 10:10

Chirdeep Tomar


Just need to add a note on @Chirdeep answer, if you tried to render the form you would lose the field.help_text for the password.

In order to fix, we can re-write the forms as below please note to import the password_validation from django.contrib.auth

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import password_validation
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.validators import UnicodeUsernameValidator

username_validator = UnicodeUsernameValidator()

class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=12, min_length=4, required=True, help_text='Required: First Name',
                                widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First Name'}))
    last_name = forms.CharField(max_length=12, min_length=4, required=True, help_text='Required: Last Name',
                               widget=(forms.TextInput(attrs={'class': 'form-control'})))
    email = forms.EmailField(max_length=50, help_text='Required. Inform a valid email address.',
                             widget=(forms.TextInput(attrs={'class': 'form-control'})))
    password1 = forms.CharField(label=_('Password'),
                                widget=(forms.PasswordInput(attrs={'class': 'form-control'})),
                                help_text=password_validation.password_validators_help_text_html())
    password2 = forms.CharField(label=_('Password Confirmation'), widget=forms.PasswordInput(attrs={'class': 'form-control'}),
                                help_text=_('Just Enter the same password, for confirmation'))
    username = forms.CharField(
        label=_('Username'),
        max_length=150,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={'unique': _("A user with that username already exists.")},
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2',)
like image 41
Ahmed Al-Haffar Avatar answered Oct 21 '22 10:10

Ahmed Al-Haffar