How to improve Django form errors? - python

If I have a django form, where I want it to provide a bootstrap error input (<input type="text" id="inputError">) to show an error instead of the bullet-list {{ form.title.error }}, how would I go about doing this? Right now I have:
{% if UF.title.errors %}
{{ UF.title }}
{{ UF.title.errors.as_text }}
{% else %}
{{ UF.title }}
{% endif %}
but instead of having UF.title in the first error, I would rather have UF.title but with the ERROR> how would I go about doing this?

You should use django-bootstrap3.
It does exactly what you want.
{% load bootstrap3 %}
{# Display a form #}
<form action="/url/to/submit/" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %} Submit
</button>
{% endbuttons %}
</form>

Here's what I do for my code:
<div class="form-group {% if form.username.errors %}has-error{% endif %}">
{{ form.username }}
{% if form.username.errors %}
<span class="help-block">{{ form.username.errors.0 }}</span>
{% endif %}
</div>
And my forms.py looks like:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(label='Username', max_length=32, widget=forms.TextInput(attrs={'placeholder': 'Username', 'class': 'form-control'}))

Related

removing __all__ from django form.errors

i want to render errors in each field
and remove the all from errors
{% csrf_token %}
{% if form.errors %}
<p><strong>{{form.errors}}</strong></p>
{% endif %}
<label>{{form.username.label}}</label>
{% render_field form.username class+='form-control border' %}
<br>
<label>{{form.password.label}}</label>
{% render_field form.password class+='form-control border' %}
<br>
<input class="btn btn-primary" type="submit" value="Login">
<p>don't have an account Register </p>
</form>
you can loop for each field in your form and put an if statement to check if there is an errors in your form or you can do it manually for each field
{% if form.username.errors %}
{{form.username.errors}}
{#to do error handling #}
{% endif %}
I'm presuming you want to enter errors for each field , if so you can check this out in the docs
https://docs.djangoproject.com/en/4.1/topics/forms/#looping-over-the-form-s-fields

Python, Django: Editing inlineformset_factory

inside my app I'm using an inlineformset_factory and right know it's working fine! But when displaying it inside my template the labels are always staying right above the input-field. Is there any way to display them side-by-side or even move the label as some sort of placeholder inside the input-field?
views.py
formset = inlineformset_factory(Model_A, Model_B, can_delete=False, extra=0, fields=('fields_01', 'fields_02', 'fields_03'))
template.html
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form }}
{% endfor %}
<button type="submit">Save</button>
</form>
Thanks for all your help and have a great weekend!
Try this:
<form action="" method="POST">
{% csrf_token %}
{{ form.management_form }}
{% for field in form %}
{{field.product.label}} - {{field.product}} #here product is my field name
<hr>
{% endfor %}
<input type="submit" name="Submit">
</form>
You have to do this for every field
#Changes
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.Field_name.label }} - {{form.Field_name}} #1st field
{{ form.Field_name.label }} - {{form.Field_name}} #2nd field
{% endfor %}
<button type="submit">Save</button>
</form>
I think the displaying was influenced by css。
Use F12 to check css in chrome to find the reason。
You can edit the css to change the displaying.
Or use django-widgets-improved and bootstrap to set class to the fields of form.
{% load widget_tweaks %}
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{% for field in form %}
{% render_field field class="form-control" %}
{% endfor %}
{% endfor %}
<button type="submit">Save</button>
</form>

Flask square brackets and single quotas at showing all validation message at once

I have created a very simple login form with flask
email = StringField('E-Mail:', validators=[validators.DataRequired(message='E-mail needed.'), validators.email(u'Provide e-mail.')])
password = StringField('Password:', [validators.required(u'Password can't be empty.')])
And the macro which will create the form inside the template:
{% macro render_field(field) %}
<fieldset>
<div class="form-group">
{{ field(**kwargs) | safe }}
</div>
</fieldset>
{% endmacro %}
As you can see it is very simple form. In the flask tutorial it was showing validation erors for individual fields. But I just want to show them all at once on the top of the form.
Here is my template for that:
<div class="panel-body">
{% if loginForm.errors %}
<div class="alert alert-danger">
<ul>
{% for error in loginForm.errors %}
<li>{{ loginForm.errors[error] }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<form role="form" method="post" action="{{ url_for('login') }}">
{% from "_formhelper.html" import render_field %}
<fieldset>
{{ render_field(loginForm.email, class="form-control", placeholder="E-Mail") }}
{{ render_field(loginForm.password, class="form-control", placeholder="Password") }}
<button class="btn btn-lg btn-success btn-block">Login</button>
</fieldset>
</form>
</div>
As you can see, i placed my error section on the top of the form. But when
I post empty form, it shows the error messages like this:
['Password can't be empty'] instead of Password can't be empty
Why does it append square brackets and single quotas, start and end of the message? I don't know.
I know that this is an old question but if anyone else has this problem you can fix it by adding a for loop for the messages, something like this:
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-warning my-5">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}

flask-admin: revise the button text

I haven't found similar questions on stackoverflow, I'd like to change the save button to submit or confirm on the edit form. I know this might not be easily changed. Thanks for any advise in advance.
After search in the code of flask-admin, I found the button is rendered with macro render_form, render_form_buttons, extra. The value of these buttons is hard code with {{ _gettext("blabla") }}.
As these buttons are not fields of data model, we can't use rendering rules to custom the value. I think there are two work arounds to get this done:
change the macro which render these buttons in the source of flask-admin(render_form_buttons, extra)
flask-admin use flask-babelex to do localization({{ _gettext("blabla") }}), you can 'translate' Save to submit or confirm with flask-babelex
UPDATE:
You can custom edit.html in your own template directory.
{% extends 'admin/model/edit.html' %}
{% from 'admin/lib.html' import extra with context %}
{% from 'admin/lib.html' import form_tag with context %}
{% from 'admin/lib.html' import render_form_fields with context %}
{% macro my_render_form_buttons(cancel_url, extra=None, is_modal=False) %}
<hr>
<div class="form-group">
<div class="col-md-offset-2 col-md-10 submit-row">
<input type="submit" class="btn btn-primary" value="{{ _gettext('Submit') }}" />
{% if extra %}
{{ extra }}
{% endif %}
{% if cancel_url %}
<a href="{{ cancel_url }}" class="btn btn-danger" role="button" {% if is_modal %}data-dismiss="modal"{% endif %}>{{ _gettext('Cancel') }}</a>
{% endif %}
</div>
</div>
{% endmacro %}
{% macro my_render_from(form, cancel_url, extra=None, form_opts=None, action=None, is_modal=False) -%}
{% call form_tag(action=action) %}
{{ render_form_fields(form, form_opts=form_opts) }}
{{ my_render_form_buttons(cancel_url, extra, is_modal) }}
{% endcall %}
{% endmacro %}
{% block edit_form %}
{{ my_render_form(form, return_url, extra(), form_opts) }}
{% endblock %}

How to get a certain field out of form in django template?

i wonder how i can add some extra html to a certain field in a template in Django
I have the following form (forms.py)
first_name = forms.CharField(widget=forms.TextInput(attrs={'required': 'required'}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'required': 'required'}))
street = forms.CharField(widget=forms.TextInput(attrs={'required': 'required'}))
In my template i get the fields with:
<form action="" method="post">{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<input type="submit" value="Submit" />
</form>
Now i want to add some extra html to the street field like this
<form action="" method="post">{% csrf_token %}
{% for field in form %}
{% if field.type =='street' %}
<div class="fieldWrapper otherclass">
<hr>
{% else %}
<div class="fieldWrapper">
{% endif %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<input type="submit" value="Submit" />
</form>
The whole thing fails:
Could not parse the remainder: '=='street'' from '=='street''
Template operators require a space before and after so replace
{% if field.type =='street' %}
with
{% if field.type == 'street' %}
or use the ifequal templatetag
{% ifequal field.type 'street' %}
Hello world.
{% else %}
Apocalypse
{% endifequal %}

Categories