How do I change the Django form.errors display text? - django

I want to remove the circled bit from being displayed. How would I be able to do this?
{% if form.errors %}
<div class="alert alert-warning alert-dismissible fade show"
role="alert">
<p class="m-0">{{ form.errors }}</p>
<button type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="Close">
</button>
</div>
{% endif %}
This always displays
property where the error is found
error message
error message ...
I want to remove the property where the error is found. How would I do this?

Django Form has two error handlers:
Form.errors are field errors. By default, a dict of key "field name" : value "field errors"
Form.non_field_errors are general errors that have no relation to a field name, mainly errors from the Form.clean(..) method.
So you are trying to do an anti-pattern and a distraction to the user experience. Therefore you can best achieve a better experience by mapping each field to its value without the need to render the field name in the error.
Form custom rendering will give you full access to the Form API, and allow you to display the error in the way you like without the default render, something like the following looping over form's fields:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
By doing the above, you will also need to render the non_field errors, and the complete HTML tags will be as follows:
{{ form.non_field_errors }}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
Django also offers manual render for each field something like the following:
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="{{ form.sender.id_for_label }}">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
{{ form.cc_myself }}
</div>
Choose the best fit for your needs.
There is still a hacky thing you can do which is not a best practice and will lead to conflicts between Field validation and non-field validation as follows Getting a list of errors in a Django form:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% endif %}

In Django 4.0 or high
{% if form.errors %}
{% for error in form.errors.as_data.values %}
{% for data in error.0 %}
{{ data }}
{% endfor %}
{% endfor %}
{% endif %}

Related

How to show validation errors in template using CreateView Django

I am using an extended User model and a generic CreateView.
class SignUp(CreateView):
form_class = forms.SignUpForm
success_url = '/accounts/login/'
template_name = 'accounts/signup.html'
How do I access the form validation errors in my template? They must be there because when I do {{ form.as_p }} the errors show up. I have tried {{ form.errors }} and {{ field.errors }} but there is nothing in them. Is there a simple tag I can call in my template to show the errors? Thanks.
you can do it manually if you like. Each field is available as an attribute of the form using {{ form.name_of_field }}, and in a Django template, will be rendered appropriately. For example:
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="{{ form.sender.id_for_label }}">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
{{ form.cc_myself }}
</div>
and if you want to loop all errors once on the top page.
{% if form.non_field_errors %}
<ul>
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
If you’re using the same HTML for each of your form fields, you can reduce duplicate code by looping through each field in turn using a {% for %} loop:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
you can check many methods to do that in Django documentation in the below URL
https://docs.djangoproject.com/en/4.0/topics/forms/#looping-over-the-form-s-fields

How to exclude specific field types in a template form loop

I am using django_widget_tweaks to loop over form fields:
{% for field in form.visible_fields %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
This displays a happy Bootstrap4 compliant interface, except when displaying fields like radio when I need to use a custom-control class not the form-control class.
How can I filter the form field loop to exclude radio inputs so I can write this code separately?
I need to understand how to filter the field loop and what the correct way to do this with the field type for radio is.

Flask WTForms - how to skip validation on fields in invisible div?

I have created a WTform in Python Flask, where I have a delivery form. If customer's billing address is different from delivery address then i am enabling div which contains fields for billing address. I am doing hiding and showing of div via jquery.
Originally i had all the fields in one Flaskform, but then i thought if i put billing fields in separate FlaskForm, and handle form.validate_on_submit() separately for 2nd form then may be i can skip validation for fields in Billing div.
But no, it is still performing validation on those fields, and because of that I am not able to move forward. If user has same addresses then billing fields will be empty and can't pass validation.
I am sure people must have encountered this situation but i can't find any answer regarding this.
Could someone guide me?
I am attaching code, to explain myself.
My Forms.py
class DeliveryForm(FlaskForm):
choices_billadd = [('1', 'Use delivery address'), ('2', 'Add a billing address')]
addressline1 = StringField('Address Line 1*',
validators=[DataRequired(), Length(min=1, max=100)])
addressline2 = StringField('Address Line 2',
validators=[Length(max=100)])
city = StringField('City*',
validators=[DataRequired(), Length(min=2, max=50)])
postcode = StringField('Postcode*',
validators=[DataRequired(), Length(min=2, max=50)])
billingaddress = SelectField('Billing Address*', choices = choices_billadd, validators = [DataRequired()])
submit = SubmitField('Submit')
class BillingForm(FlaskForm):
bill_addressline1 = StringField('Address Line 1*',
validators=[DataRequired(), Length(min=1, max=100)])
bill_addressline2 = StringField('Address Line 2',
validators=[Length(max=100)])
bill_city = StringField('City*',
validators=[DataRequired(), Length(min=2, max=50)])
bill_postcode = StringField('Postcode*',
validators=[DataRequired(), Length(min=2, max=50)])
<form method="POST" action="">
{{ form.csrf_token(id='login_csrf') }}
<fieldset class="form-group content-section">
<div class="row pt-3">
<div class="col-6">
{{ form.addressline1.label(class="form-control-label") }}
{% if form.addressline1.errors %}
{{ form.addressline1(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.addressline1.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.addressline1(class="form-control") }}
{% endif %}
</div>
<div class="col-6">
{{ form.addressline2.label(class="form-control-label") }}
{% if form.addressline2.errors %}
{{ form.addressline2(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.addressline2.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.addressline2(class="form-control") }}
{% endif %}
</div>
</div>
<div class="row pt-3">
<div class="col-6">
{{ form.city.label(class="form-control-label") }}
{% if form.city.errors %}
{{ form.city(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.city.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.city(class="form-control") }}
{% endif %}
</div>
<div class="col-6">
{{ form.postcode.label(class="form-control-label") }}
{% if form.postcode.errors %}
{{ form.postcode(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.postcode.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.postcode(class="form-control") }}
{% endif %}
</div>
</div>
<div class="row pt-3">
<div class="col-12">
{{ form.billingaddress.label(class="form-control-label") }}
{{ form.billingaddress(class="form-control") }}
</div>
</div>
<div id="div_billingaddress" class="">
<div class="row pt-3">
<div class="col-6">
{{ form_bill.bill_addressline1.label(class="form-control-label") }}
{% if form_bill.bill_addressline1.errors %}
{{ form_bill.bill_addressline1(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_bill.bill_addressline1.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form_bill.bill_addressline1(class="form-control") }}
{% endif %}
</div>
<div class="col-6">
{{ form_bill.bill_addressline2.label(class="form-control-label") }}
{% if form_bill.bill_addressline2.errors %}
{{ form_bill.bill_addressline2(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_bill.bill_addressline2.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form_bill.bill_addressline2(class="form-control") }}
{% endif %}
</div>
</div>
<div class="row pt-3">
<div class="col-6">
{{ form_bill.bill_city.label(class="form-control-label") }}
{% if form_bill.bill_city.errors %}
{{ form_bill.bill_city(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_bill.bill_city.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form_bill.bill_city(class="form-control") }}
{% endif %}
</div>
<div class="col-6">
{{ form_bill.bill_postcode.label(class="form-control-label") }}
{% if form_bill.bill_postcode.errors %}
{{ form_bill.bill_postcode(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_bill.bill_postcode.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form_bill.bill_postcode(class="form-control") }}
{% endif %}
</div>
</div>
</div>
</fieldset>
<div class="row py-4">
<div class="col-12">
{{ form.submit(class="btn btn-success btn-block") }}
</div>
</div>
</form>

django escape tag not escaping single quotation marks

I am using django 1.7.
When a user enters single and/or double quotation marks as part of their input, the form displaying their entered data is broken.
So I used django's escape tag, which should deal with this very easily.
However, the escape tag is only escaping the double quotation marks. The single quotation marks are not being escaped and are breaking the test form.
Here is an example of my code:
{{ field|escape }}
Does anyone know how to overcome this issue.
EDIT
Here is my form field template code (form_fields.html):
<div id="row_{{ field.auto_id }}" class="form-group {% if field.errors %}error{% endif %} {% if hide_row %}hidden{% endif %}">
<label for="{{ field.auto_id }}" class="control-label {{ field.css_classes }}">
{{ field.label }}{% if field.label %}:{% endif %}
</label>
<div class="controls {{ control_classes }}">
{{ field|escape }}
{% if field.errors %}
<span class="help-inline">
<strong>
{% for e in field.errors %}
{{ e }}<br/>
{% endfor %}
</strong>
</span>
{% endif %}
{% if field.help_text %}
<p class="help-block">
{{ field.help_text }}
</p>
{% endif %}
</div>
</div>
And here is the form template field code:
{% load form_fields %}
....
{% form_field form.name_details_prefix_title %}
I ultimately tracked th error to a js issue.
I used the following tag to solve the issue:
{{ field|escapejs }}
Hope that this helps some one.

Add unique styling to one form in a Django formset

I have a formset with four forms, and want to render the fourth one with different CSS from the others - unique color, styling, etc. Can I do this from my html page, or somewhere else?
I'm looking for something like this pseudo-code:
<form action="" method="post">{% csrf_token %}
{{ formset.management_form }}
{{ formset.non_form_errors }}
<div>
{% for form in formset except the last form %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
{% endfor %}
{% endfor %}
{% for the last form in the formset %}
{% for field in form %}
{{ field.errors }}
<div class="different style">
{{ field.label_tag }}:
<p class="another different style">{{ field }}</p>
</div>
{% endfor %}
{% endfor %}
</div>
<p><input type="submit" value="Submit" /></p>
</form>
See forloop.last in documentation -
<form action="" method="post">{% csrf_token %}
{{ formset.management_form }}
{{ formset.non_form_errors }}
<div>
{% for form in formset %}
{% if forloop.last %}
{% for field in form %}
{{ field.errors }}
<div class="different style">
{{ field.label_tag }}:
<p class="another different style">{{ field }}</p>
</div>
{% endfor %}
{% else %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
{% endfor %}
{% endif %}
</div>
<p><input type="submit" value="Submit" /></p>
</form>