I'm trying to style the django forms, I could apply the class to the TextInputs with widget but for the email and password it doesn't apply. Any idea why?
Also, how can I delete the text above password? The password requisites, it isn't help_text
forms.py
class SignupForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['email', 'first_name', 'last_name', 'password1', 'password2']
widgets = {
'email': forms.EmailInput(attrs={'class': 'forms-group__input'}),
'first_name': forms.TextInput(attrs={'class': 'forms-group__input'}),
'last_name': forms.TextInput(attrs={'class': 'forms-group__input'}),
'password1': forms.PasswordInput(attrs={'class': 'forms-group__input'}),
'password2': forms.PasswordInput(attrs={'class': 'forms-group__input'}),
}
forms.html
<form class="forms-group__form" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
{{ field.errors }} <br>
<div class="forms-group__input-field">
<label class="forms-group__label">{{ field.label_tag }}</label><br>
{{ field }}<br>
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
<div class="forms-group__button-div"><input class="button submit-button forms-group__button" type="submit" value="Update Profile"></div>
</form>
Fields that are declared in the form class are not automatically generated by the ModelForm, hence declaring a widget for them in the widgets attribute of the Meta does not work. You can either forego declaring it in the class and let it be generated automatically:
class SignupForm(UserCreationForm):
email = forms.EmailField()
...
Or you can specify the widget for the field in the field itself:
class SignupForm(UserCreationForm):
email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'forms-group__input'}))
...
Related
So i was using crispy forms to display my register view as i wanted to override the defaults labels i ran into an issue when it comes to the password label and the confirmation password label, i simply cannot change then even when i override then as i did with the username one, would appreciate any help.
Here is the abstractuser model
class CustomUser(AbstractUser):
setor_escolhas = (
("R", "Revendedora"),
("C", "Concessionária"),
)
setor= models.CharField(max_length=1,choices=setor_escolhas, blank=False, null=False)
Here is mine register form:
class UserCadastroForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = CustomUser
fields = ['username', 'email', 'password1','setor', 'password2' ]
labels={'username':'Usuário','setor':'Setor da sua empresa','password1':'Senha'}
And here is mine template format
{% extends "APP_IVG/layout.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class= "content-section">
<form method= "POST">
{% csrf_token %}
<fieldset class = 'form-group'>
<legend class= "border-bottom mb-4"> Junte-se hoje</legend>
{{ form|crispy }}
</fieldset>
<div class = "form-group">
<button class= "btn btn-outline-info" type= "submit"> Cadastre-se </button>
</div>
</form>
<div class= "border-top pt-3">
<small class= "text-muted">
Já tem uma conta? <a class= "ml-2" href = "{% url 'Login' %}"> Clique aqui </a>
</small>
</div>
</div>
{% endblock content %}
You may do it by two ways, override it in the __init__ method
class UserCadastroForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].label = 'password 1 label'
self.fields['password2'].label = 'password 2 label'
Or you may just override form fields:
class UserCadastroForm(UserCreationForm):
password1 = forms.CharField(
label='password 1 label',
strip=False,
widget=forms.PasswordInput(),
help_text='HELP TEXT',
)
password2 = forms.CharField(
label='password 2 label',
widget=forms.PasswordInput(),
strip=False,
help_text='HELP TEXT',
)
So i'm using the auth.models.user to create user model and by default it's passing ('first_name', 'last_name', 'username', 'email', 'password1', 'password2'). and the forms.py:
class UserSignUpForm(UserCreationForm):
class Meta:
fields = ('first_name','last_name','username', 'email', 'password1', 'password2')
model = user
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.fields['username'].label = 'Username'
self.fields['email'].label = "Email Address"
i try to allowing user to edit their personal information from all avaliable fields in UserSignUpForm, except the password fields. so i created this views.py (function based view):
def edit_account(request):
user = request.user
form = UserSignUpForm(instance=user)
if request.method == 'POST':
form = UserSignUpForm(request.POST, instance=user,)
if form.is_valid():
form = UserSignUpForm(instance=user)
form.save()
messages.success(request, 'Your account has been updated.')
return redirect('/dashboard/profile/')
context = {'editform':form}
return render(request, 'accounts/updateaccounts.html', context)
tried submit the specific field form like{{editform.first_name}} after passsing it in the html page (because i dont want to user be able edit their password) but it still not update/saving the new user data. is there any method so it can be save? thanks
In the html file, have you tried printing the form errors to see what's happening? try this:
<form method = "POST">
{% csrf_token %}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
</form>
Also, you have a " form = UserSignUpForm(instance=user)" outside of the if request.POST...
You also have a " form = UserSignUpForm(instance=user)" after form is valid.
I am working with this simple form and can't able to display inline validation in each line. I want validation as it worked in the Django admin site, with particular fields. How could it be done! It only shows the HTML validation like "Please fill out the field"
models.py
class MemberRegistration(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
phone = models.CharField(max_length=50)
def __str__(self):
return self.name
forms.py
from django import forms
from . models import MemberRegistration
from django.core import validators
class MemberForm(forms.ModelForm):
name = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder':'Name'}),
max_length=100, error_messages = {
'required':"Please Enter your Name"})
email = forms.EmailField(widget=forms.EmailInput(
attrs={'class': 'form-control', 'placeholder':'E-mail'}),
required=True, max_length=100)
phone = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder':'Phone'}),
required=True, max_length=100)
class Meta:
model = MemberRegistration
fields = "__all__"
def clean_name(self):
all_clean_data = super().clean()
name = all_clean_data['name']
if name == "":
raise forms.ValidationError("Name field is required")
member_form.html:
{% block body_block %}
<div class="container">
<h1>This is member reg form</h1>
<form method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="">Name</label>
{{ form.name.errors }}
{{form.name}}
</div>
<div class="form-group">
<label for="">Email</label>
{{ form.email.errors }}
{{form.email}}
</div>
<div class="form-group">
<label for="">Phone</label>
{{form.phone}}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% endblock %}
How I can do this with Django's built-in validation?
despite of the hours of struggle i am unable to bootstrap a django form created with UserCreationForm. i want to add bootstrap classes to the tag but due to my poor knowledge of django class based views i am unable to have a workaround.
urls.py
urlpatterns = [
path('signup/', views.SignUp.as_view(), name='signup'),
path('', include('django.contrib.auth.urls')),
]
views.py
class SignUp(CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('accounts:login')
template_name = 'accounts/signup.html'
forms.py
class CustomUserCreationForm(UserCreationForm):
class Meta:
fields = ('first_name', 'last_name', 'email', 'age', 'height', 'avatar', 'password1', 'password2')
model = get_user_model()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password2'].label = "Confirm Password"
Current Output
enter image description here
Output I want
enter image description here
Please take a look at this
https://simpleisbetterthancomplex.com/tutorial/2018/08/13/how-to-use-bootstrap-4-forms-with-django.html
or
https://django-bootstrap3.readthedocs.io/en/latest/templatetags.html
And also when you are rendering your field in your template, For example
{% bootstrap_field form.myfield form_group_class='custom-class-name' %}
You can add a custom class like so. and it 'll show up as a class in your HTML when you inspect so you can use it for your CSS
So, I am posting an answer to my own question so that someone looking for that same thing will find the solution in one place. What exactly I was looking for is;
forms.py
class CustomUserCreationForm(UserCreationForm):
class Meta:
fields = ('first_name', 'last_name', 'email', 'age', 'height', 'avatar', 'password1', 'password2')
model = get_user_model()
first_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'First Name',
'class': 'form-control',
}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Last Name',
'class': 'form-control',
}))
email = forms.CharField(widget=forms.EmailInput(attrs={'placeholder': 'Email',
'class': 'form-control mb-4',
}))
age = forms.IntegerField(widget=forms.NumberInput(attrs={'placeholder': 'Age',
'class': 'form-control',
}))
height = forms.IntegerField(widget=forms.NumberInput(attrs={'placeholder': 'Height(cm)',
'class': 'form-control',
}))
avatar = forms.ImageField(widget=forms.FileInput(attrs={'placeholder': 'Avatar',
'class': 'form-control mb-4',
}))
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password',
'class': 'form-control mb-4',
}))
password2 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password',
'class': 'form-control mb-4',
}))
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password2'].label = "Confirm Password"
views.py
class SignUp(CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('accounts:login')
template_name = 'accounts/register.html'
accounts/register.html
{% extends 'base.html' %}
{% block title %}
SignUp
{% endblock title %}
{% block content %}
<div style="margin: 75px 0px 0px 0px; background: rgb(87,77,255);
background: linear-gradient(276deg, rgba(87,77,255,0.8830882694874825) 24%, rgba(7,96,255,0.5385504543614321) 77%);" class="bg_cover">
<form class="text-center col-md-5" method="POST" enctype="multipart/form-data">
<p class="h4 mb-4">SignUp</p>
{% csrf_token %}
<div class="form-row mb-4">
<div class="col">
{{ form.first_name }}
</div>
<div class="col">
{{ form.last_name }}
</div>
</div>
{{ form.email }}
<div class="form-row mb-4">
<div class="col">
{{ form.age }}
</div>
<div class="col">
{{ form.height }}
</div>
</div>
{{ form.avatar }}
{{ form.password1 }}
{{ form.password2 }}
<button class="btn-block btn btn-primary my-4" type="submit">Sign up</button>
</form>
</div>
{% endblock content %}
results
You can subclass the UserCreationFrom as i did in the CustomUserCreationForm class, then all you have to do is add your desired attributes(bootstrap class names, id's etc) to the form fields you want to modify(beautify). Speaking of "accounts/register.html" written in the SignUp view, i am explicitly telling the django where to find the template. In the template you can render the entire form by {{ form.as_p }} or render individual fields as i did in the template!
Hopefully, my answer would save you from headache i went through to find that!
I am using the django's form wizard in the authentication system.
I have 2 form wizards steps. In the second, I have two buttons: the Prev Step button and the Submit button. When the Prev Step button is used to go backwards, I get the django's warning to fill out the field.
How do I disable validations for the Prev Step button and keep the validations for the Submit button?
I already disabled the javascript validations for the Prev Step button.
My html:
<!-- Forms -->
{{ wizard.management_form }}
{% for field in wizard.form %}
<div class="wrap-input100 rs1-wrap-input100 validate-input m-b-20">
{{ field }}
<span class="focus-input100"></span>
</div>
{% endfor %}
<!-- Buttons -->
{% if wizard.steps.next %}
<div class="container-login100-form-btn">
<button type="submit" value="{{ wizard.steps.next }}" class="login100-form-btn">Next step</button>
</div>
{% else %}
<div class="container-login100-form-btn">
<div class="split-left">
<button type="submit" value="{{ wizard.steps.prev }}" class="login100-form-btn" formnovalidate>Prev step</button>
</div>
<div class="split-right">
<button type="submit" class="login100-form-btn">Sign up</button>
</div>
</div>
{% endif %}
views:
class signup(SessionWizardView):
template_name='accounts/signup.html'
form_list = [UserCreationForm_1, UserCreationForm_2]
def done(self, form_list, **kwargs):
form_step = [form for form in form_list]
# step 1: ModelForm
user = form_step[0].save()
auth_login( self.request, user )
# step 2: Form
user = form_step[1].save()
return redirect( 'home' )
forms:
class UserCreationForm_1(forms.ModelForm):
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class':'input100', 'placeholder': 'Password'}))
password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class':'input100', 'placeholder': 'Repeat Password'}))
class Meta:
model = MyUser
fields = ('shown_name', 'email')
widgets = {
'email': forms.EmailInput(attrs={'class':'input100', 'placeholder': 'Email'}),
'shown_name': forms.TextInput(attrs={'class':'input100', 'placeholder': 'User name'}),
}
class UserCreationForm_2(forms.Form):
name = forms.CharField( max_length=40, widget=forms.TextInput(attrs={'class':'input100', 'placeholder': 'Name'}) )
date_of_birth = forms.DateField( widget=forms.DateInput(attrs={'class':'input100', 'placeholder': 'Date of Birth'}) )
phone = PhoneNumberField( widget=forms.TextInput(attrs={'class':'input100', 'placeholder': 'Phone'}) )
In the second form wizard step, when I use the Prev button, this happens:
https://imgur.com/54VvvZx
When I use the Submit button, this happens:
https://imgur.com/JLCYMmr
The problem had nothing to do with Django. It was a javascript problem. I only had to remove the class validate-input from the forms' div.