I'm struggling to show error message in change_password in Django.
I tried all the ways I know to show errors in the template file, but nothing shows up when I put some wrong information on purpose.
I thought it's because of redirecting when the form is not valid. But, the changing password feature doesn't work without the redirecting.
Can anyone suggest a way to do that?
views.py
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('/accounts/profile')
else:
return redirect('/accounts/change-password')
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'accounts/change_password.html', args)
HTML template
<form method="POST">
{% csrf_token %}
<p class="error-message">
{{ form.errors.old_password }}
{{ form.errors.new_password1 }}
{{ form.errors.new_password2 }}
{{ form.non_field_errors }}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
{% endif %}
</p>
<div class="form-group row">
<label for="inputPassword" class="col-sm-3 col-form-label">Old Password</label>
<div class="col-sm-9">
<input type="password" class="form-control" name="old_password" placeholder="Old Password" required autofocus>
</div>
</div>
<div class="form-group row">
<label for="inputPassword" class="col-sm-3 col-form-label">New Password</label>
<div class="col-sm-9">
<input type="password" class="form-control" name="new_password1" placeholder="New Password" required>
</div>
</div>
<div class="form-group row">
<label for="inputPassword" class="col-sm-3 col-form-label">Confirm New Password</label>
<div class="col-sm-9">
<input type="password" class="form-control" name="new_password2" id="inputPassword" placeholder="Confirm New Password" required>
</div>
</div>
<input class="btn btn-modvisor btn-block" type="submit" name="" value="Submit">
</form>
Try without redirecting when there is an error, like this:
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('/accounts/profile')
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'accounts/change_password.html', args)
As you can see, like this the line return render(... is also called when the form is not valid.
Related
Django's SetPasswordForm doesn't render anything, please help.
This is what I got:
views.py
from django.contrib.auth.forms import SetPasswordForm
#login_required
def profile_security(request):
template = "profiles/profile_security.html"
form = SetPasswordForm
print("form.base_fields: %s" % form.base_fields)
context = {"profile_index_active": "active", "underline_security": "text-underline", "form": form}
return render(request, template, context)
html
<form method="post">{% csrf_token %}
{{ form.as_p }}
</form>
tried this html as well
<form method="post">{% csrf_token %}
<div class="form-group field-password1">
{{ form.new_password1.errors }}
<label for="id_new_password1">New Password</label>
{{ form.new_password1 }}
</div>
<div class="form-group field-password2">
{{ form.new_password2.errors }}
<label for="id_new_password2">Repeat New Password</label>
{{ form.new_password2 }}
</div>
<div class="form-group">
<input class="btn btn-success text-uppercase w-100" type="submit" value="Guardar nueva contraseña">
</div>
</form>
It does print the fields correctly:
form.base_fields: {'new_password1': <django.forms.fields.CharField object at 0x7f49174e2790>, 'new_password2': <django.forms.fields.CharField object at 0x7f49174e2940>}
but it doesn't render anything. What am I doing wrong?
SetPasswordForm class needs user instance
form = SetPasswordForm(request.user)
I have a template in which user can change his details like name, email and password. I am getting wrong messages after updating info ( if I change the password then I got message "Invalid" that is part of edit_profile) though I used extra_tags for message to identify two different messages,
But still having issue. I tried searching a lot, and found some relevant questions but was not helpful.
views.py
def edit_profile(request):
if request.user.is_authenticated:
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
messages.success(request, "Update successful!", extra_tags='edit_profile')
return redirect("accounts:edit_profile")
else:
messages.error(request, "Invalid", extra_tags='edit_profile')
return redirect("accounts:edit_profile")
else:
form = EditProfileForm(instance=request.user)
return render(request, "accounts/edit_profile.html", {'form': form})
else:
redirect('accounts:signin')
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
messages.success(request, "Update successful!", extra_tags='change_password')
update_session_auth_hash(request, form.user)
return redirect("accounts:change_password")
else:
messages.error(request, "Password Error", extra_tags='change_password')
return redirect("accounts:change_password")
else:
form = PasswordChangeForm(user=request.user)
return render(request, "accounts/edit_profile.html", {'form': form})
template
<h2 class="font-weight-bolder">Account Details</h2>
<!-- edit_profile form -->
<form action="{% url 'accounts:edit_profile' %}" method="post" class="row g-3 needs-validation"
novalidate>
{% csrf_token %}
<!-- 1 Username -->
<div class="offset-md-2 col-md-4 ">
<label for="username" class="form-label">Username</label><br>
<input type="text" name="username" class="form-control" id="username"
value="{{ form.username.value }}" required>
<div class="invalid-feedback">
Please provide name.
</div>
</div>
<!-- 2 Email -->
<div class="offset-md-1 col-md-4">
<label for="email" class="form-label">Email</label>
<input type="email" name="email" class="form-control" id="email"
value="{{ form.email.value }}" required>
<div class="invalid-feedback">
Please provide a valid email.
</div>
</div>
{% for message in messages %}
{% if 'edit_profile' in message.tags %}
<div class="offset-md-2 col-md-6 pt-2">
<h4 class="text-success font-weight-bolder">{{ message }}</h4>
</div>
{% endif %}
{% endfor %}
<div class="offset-md-2 col-md-4 pt-2 pb-2">
<input type="submit" value="Save" class="btn btn-outline-primary btn-lg">
</div>
</form>
<!-- Password section -->
<div class="offset-md-2 pt-3 pb-2">
<h4 class="font-weight-bold">Password</h4>
</div>
<form action="{% url 'accounts:change_password' %}" method="post" class="row g-3 needs-validation"
novalidate>
{% csrf_token %}
<div class="offset-md-2 col-md-3">
<label for="old_password" class="form-label">Current password</label>
<input type="password" name="old_password" value="" class="form-control" id="old_password" required>
<div class="invalid-feedback">
Please provide a valid password.
</div>
</div>
<div class="col-md-3">
<label for="new_password1" class="form-label">New password</label>
<input type="password" name="new_password1" value="" class="form-control" id="new_password1"
required>
<div class="invalid-feedback">
Please provide a valid password.
</div>
</div>
<div class="col-md-3">
<label for="new_password2" class="form-label">Confirm password</label>
<input type="password" name="new_password2" value="" class="form-control" id="new_password2"
required>
<div class="invalid-feedback">
Please provide a valid password.
</div>
</div>
{% for message in messages %}
{% if "change_password" in message %}
<div class="offset-md-2 col-md-6 pt-2">
<h4 class="text-success font-weight-bolder">{{ message }}</h4>
</div>
{% endif %}
{% endfor %}
<div class="offset-md-2 col-md-4 pt-2">
<input type="submit" value="Change Password" class="btn btn-outline-primary btn-lg">
</div>
</form>
I am still new to django. Playing around with a leadmanager app and I don't know why my form is not validating.
views
def index(request):
lead=LeadForm()
if request.method == 'POST':
lead=LeadForm(request.POST)
if lead.is_valid():
messages.success(request, f'Thank you for registering. Someone will be contacting you soon.')
return redirect('index')
else:
lead=LeadForm()
messages.error(request, f'Something went wrong. Please try again later.')
return render(request, "frontend/index.html", {'lead':lead})
in index.html
<form action="" method="POST" class="lead-form">
{% csrf_token %}
<fieldset class="lead-info">
<div class="form-control">
<label for="">Full Name</label>
{{ lead.fullname }}
</div>
<div class="form-control">
<label for="">Email</label>
{{ lead.email }}
</div>
<div class="form-control">
<label for="">Phone</label>
{{ lead.phone }}
</div>
<div class="form-control">
<label for="">City</label>
{{ lead.city }}
</div>
</fieldset>
<button type="submit" class="btn-pill">Submit</button>
</form>
in forms.py
class LeadForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = Lead
fields = ['fullname', 'email', 'phone', 'city', 'contact_preference']
widgets = {'contact_preference': forms.RadioSelect }
Any help is appreciated. contact_preference is rendering FYI, I just cut the code to keep this question not that long.
I need to know how I raise ValidationError of a validators in django.
First I tried the methode on form in simple page and forms and it works perfectly.
but the problems appear when I use modal fade class in a page works with pk
for example(127.0.0.1:8000/wsheets/AMA2/).
the message is
(The view Home.views.wellsets didn't return an HttpResponse object. It returned None instead.)
and mt views.wellsets is
def wellsets(request, WeelN):
serchedWl = WellSheets.objects.filter(WellID__exact=WeelN)
form= WelshetForm()
context ={
'title': 'SearchWS',
'Wellslistsh':serchedWl,
'WeelN':WeelN,
'form':form,
}
if request.method == 'POST':
form =WelshetForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellSheetg', WeelN)
else:
return render(request,'Home/WELLINFO/W_TchD/wellshts.html', context)
and my form + validator is:
from django.core.exceptions import ValidationError
class WelshetForm(forms.ModelForm):
WellID = forms.CharField(label='Well Name',max_length=15)
FileNm = forms.CharField(label='File Name',max_length=15)
def clean_SHRPath(self):
SHRPath = self.cleaned_data.get('SHRPath')
size= SHRPath._size
if SHRPath._size > 1024*1024*10:
raise forms.ValidationError('Size is bigger than allowed')
return SHRPath
and at last this is my html form
<button type="button" class="btn button1 btn-outline-success mb-2 btn-block" data-toggle="modal" data-target="#myModal" >
<p class="thicker">Add new Well-Sheet</p></button>
<div class="modal fade" id="myModal" role="dialog" >
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><p class="thicker">Upload Well-sheet</p></h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<p class="thicker">Check your file before uploading ({{WeelN}})</p>
<div class="w3-panel w3-light-grey w3-round-large solid"">
<form method="POST" id="formOne" enctype= multipart/form-data>
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.WellID|as_crispy_field }} </div></div>
<div class="form-row">
<div class="form-group col-md-8 mb-0">
{{ form.SHRPath }}</div></div>
<p style="color:red;">Maximum upload size is 10Mb</p>
<br>
<input class="btn btn-success mb-6" name="form_uplod" type="submit" value="AddSheet">
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>
</div>
</div>
Modal form
As #IainShelvington said, you need to remove else block to get a response. You can try like this:
def wellsets(request, WeelN):
serchedWl = WellSheets.objects.filter(WellID__exact=WeelN)
form= WelshetForm()
if request.method == 'POST':
form =WelshetForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellSheetg', WeelN)
context ={
'title': 'SearchWS',
'Wellslistsh':serchedWl,
'WeelN':WeelN,
'form':form,
}
return render(request,'Home/WELLINFO/W_TchD/wellshts.html', context)
So that, even if the validation fails, you will get a response with form containing error data. To show form errors in template, try like this:
<div class="form-group col-md-8 mb-0">
{{ form.SHRPath }}</div>
{% if form.SHRPath.errors|length > 0 %}
<p style="color:red;">{{ form.SHRPath.errors.0 }}</p>
<br>
{% endfor %}
More information can be found in documenation.
Hi In fact I did it by other way
no error message appear in the bootstrap modal at the moment of submitting but it works fine.
in my views.py I created a new form (form_error):
def wellsets(request, WeelN):
serchedWl = WellSheets.objects.filter(WellID__exact=WeelN)
form= WelshetForm()
form_error = False
if request.method == 'POST':
form =WelshetForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellSheetg', WeelN)
else:
form_error = 'Check your file Name, type and size <10Mb'
context ={
'title': 'SearchWS',
'Wellslistsh':serchedWl,
'WeelN':WeelN,
'form':form,
'form_error': form_error,
}
return render(request,'Home/WELLINFO/W_TchD/wellshts.html', context)
and in my Html :
{% if form %}
<div class="w3-panel w3-light-grey w3-round-large solid"">
<form method="POST" id="formOne" enctype= multipart/form-data>
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.WellID|as_crispy_field }}</div></div>
{% if form_error %}
<li style="color:red;"><strong>Check the Well if it does exist</strong></li>
{% endif %}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.FileNm|as_crispy_field }}</div></div>
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.Folio|as_crispy_field }}</div></div>
<div class="form-row">
<div class="form-group col-md-8 mb-0">
{{ form.SHRPath }}</div></div>
{% if form_error %}
<li style="color:red;"><strong>{{form_error}}</strong></li>
<li style="color:red;"><strong>File type (pdf, jpg ,xls..) only accepted</strong></li>
{% endif %}
<p style="color:red;">Maximum upload size is 10Mb</p>
<br>
<input class="btn btn-success mb-6" data-target="#myModal" name="form_uplod" type="submit" value="AddSheet">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>
{% endif %}
and I creted a validators.py and in it:
def validate_file_size(value):
filesize= value.size
print('very nice',filesize/(1024*1024))
if filesize > 1024*1024*10:
raise ValidationError(_("The maximum file size that can be uploaded is 10MB"), code='invalid')
return value
def validate_text(value):
from Home.models import Wellinfo
WELDATA= Wellinfo.objects.filter(WellID=value)
print(value, WELDATA)
if Wellinfo.objects.filter(WellID=value).exists():
return value
raise ValidationError("The Well does't exists!")
and at last in the model.py i called the decorator as;
class WellSheets(models.Model):
WellID = models.CharField(max_length=15, validators= [validate_text])
FileNm = models.CharField(max_length=15)
Folio = models.PositiveIntegerField(blank=True, null=True)
SHRPath = models.FileField(upload_to='Well_sheets/', validators= [validate_file_size])
at the end the file will not added or uploaded and when I cambak to my modal window I see that
Description of modal window
Sometimes form is validating but sometimes form is not validating and shows value error
views.py
def hai(request):
if request.method == 'POST':
obj1 = hello(request.FILES, request.POST)
if obj1.is_valid():
return HttpResponse("success")
does form need to be cleaned every time submiting?
forms.py
class hello(forms.Form):
uname = forms.CharField(max_length=100)
img = forms.FileField()
template
<html>
<head></head>
<body>
<form action= {% url 'hai' %} method="POST" enctype="multipart/form-data ">
{% csrf_token %}
<div class="d-flex">
<div class="form-group mr-2">
<label for="" class="label">Pick-up date</label>
<input type="text" name="uname" class="form-control"
placeholder="Date">
</div><br>
<div class="form-group ml-2">
<label for="" class="label">Drop-off date</label>
<input type="file" name="img" class="form-control"
placeholder="Date">
</div><br>
<input type="submit" value="Book Now" class="btn btn-primary py-3 px4">
</div>
</form>
</body>
</html>
This is the error:
The problem here is that you should always return HttpResponse (or subclass), whether yourr form is valid or not; So basically you should have:
def hai(request):
if request.method == 'POST':
obj1 = hello(request.FILES, request.POST)
if obj1.is_valid():
return HttpResponse("success")
else:
return HttpResponse("error")
or you can send back the form with it's errors in the template, if you wish.