Safe built-in inside for loop Django CKEditor - python

I'm using CKEditor with Django and when i need show some RTF code in my template, usually, I use the safe built in filter (autoscape).
Example:
<p class="card-text">{{ questao.enunciado|safe }}</p>
But, how to use safe built-in inside a for loop?
{% for field in form %}
<div class="fieldWrapper">
<strong>{{ field.label_tag }}</strong>
{{ field|safe }}
{% if field.help_text %}
<p class="help">{{ field.help_text }}</p>
{% endif %}
</div>
{% endfor %}
This way above is not working for me, and in the template it ends up showing me HTML codes in text format.

You need not use the safe for the field.
Try:
{% 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 %}
Also refer django documentation

You are applying safe filter to the wrong value. You have to apply it to field.label or field.help_text instead, e.g.:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
<label for="{{ field.id_for_label }}">{{ field.label|safe }}</label>
{{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}

Related

Display error if there is error in fields

Im trying to raise error for empty fields or fields which are not validating in form
so Im doing this method below but I know this is not the best way...
views.py :
'KnowledgeForm': form,
'errors': str(form.errors),
but then in Django-template I have to use if for each field and im adding custom name for each field , i dont know why i cant use Verbose_name...
Template :
{% if errors %}
<div class="alert alert-danger">
<p>
{% if KnowledgeForm.errors.KnowledgeTitle %}
عنوان دانش: {{ KnowledgeForm.errors.KnowledgeTitle }}
{% endif %}
{% if KnowledgeForm.errors.KnowledgeTextSummary %}
Summary: {{ KnowledgeForm.errors.KnowledgeTextSummary }}
{% endif %}
{% if KnowledgeForm.errors.KnowledgeFromDate %}
from Date: {{ KnowledgeForm.errors.KnowledgeFromDate }}
{% endif %}
{% if KnowledgeForm.errors.KnowledgetoDate %}
To date : {{ KnowledgeForm.errors.KnowledgetoDate }}
{% endif %}
{% if KnowledgeForm.errors.KnowledgeProcess %}
Chart: {{ KnowledgeForm.errors.KnowledgeProcess }}
{% endif %}
{% endif %}
</p>
</div>
{% endif %}
Second method :
{% if KnowledgeForm.errors %}
<ul class="alert alert-danger">
{% for key,value in KnowledgeForm.errors.items %}
<li>{{ key|escape }} : {{ value|escape }}</li>
{% endfor %}
</ul>
{% endif %}
in this method i get the name based on whats used in models.py how can i change it?
The most clear and concise way is to use a forloop
Try replacing your entire if block in your HTML with the below code
{% for field in KnowledgeForm %}
{% if field.errors %}
<div class="alert alert-danger">
{{ field.label_tag }} {{ field.errors }}
</div>
{% endf %}
{% endfor %}
I don't think you need 'errors': str(form.errors),
It is because you convert errors to str and you don't need to separate this.
In your template:
# if you want to use verbose_name just use label_tag.
# label_tag is equal to your verbose name.
{% for field in KnowledgeForm %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
So you have the error top of input

How to place django form fields side by side

I have a UserCreationForm which I want the first_name and last_name to be side by side, When I try the whole fields are side to side, I want the other fields to have their own line.
form.html:
{% csrf_token %}
{% for field in form %}
<p>
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{{ field.label_tag }}
{{ field }}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
forms.py:
class AccountCreationForm(UserCreationForm):
class Meta:
model = Account
fields = ('first_name','last_name', 'email')
Since you are surrounding each field with a <p> tag, they all go into a separate line each. You can render your fields individually to style them as you like. Also check out this article for some examples.
I wrote a quick snippet for your exact case. Note that I render the fields individually and have both name fields in the same <p> (Paragraph) tag.
<p>
{% if form.first_name.help_text %}
<small style="color: grey">{{ form.first_name.help_text }}</small>
{% endif %}
{{ form.first_name.label_tag }}
{{ form.first_name }}
{% for error in form.first_name.errors %}
<span style="color: red">{{ error }}</span>
{% endfor %}
{% if form.last_name.help_text %}
<small style="color: grey">{{ form.last_name.help_text }}</small>
{% endif %}
{{ form.last_name.label_tag }}
{{ form.last_name }}
{% for error in form.last_name.errors %}
<span style="color: red">{{ error }}</span>
{% endfor %}
</p>
<p>
{% if form.email.help_text %}
<small style="color: grey">{{ form.email.help_text }}</small>
{% endif %}
{{ form.email.label_tag }}
{{ form.email }}
{% for error in form.email.errors %}
<span style="color: red">{{ error }}</span>
{% endfor %}
</p>

How to display just for example 100 words of an post?

I have made something like this. If the reader clicks on "Weiterlesen" then it should display the whole text. But first i want to display an range of words (for example 100)
Can i set range[:100] into {{ post.text|linebreaksbr }} ??
Thanks for your answers
{% block content %}
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaksbr }}</p>
Weiterlesen
</div>
{% endfor %}
{% endblock %}
The built-in truncatewords filter does exactly what you want.
<p>{{ post.text|truncatewords:200|linebreaksbr }}</p>

Flask-security and Bootstrap

How can I style my Flask-security login site with Bootstrap? The html form looks like this:
<form action="{{ url_for_security('login') }}" method="POST" name="login_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email) }}
{{ render_field_with_errors(login_user_form.password) }}
{{ render_field_with_errors(login_user_form.remember) }}
{{ render_field(login_user_form.next) }}
{{ render_field(login_user_form.submit) }}
</form>
Bootstrap is implemented, but I dont know how to edit the fields and the submit button..
The render_field_* functions accepts a class_ parameter, which will add HTML classes to the field. Add in bootstrap styling classes as you want.
render_field_with_errors(login_user_form.email, class_="form-control") }}
{{ render_field(login_user_form.submit, class_="btn btn-default") }}
And so on.
Flask-Security uses Flask-WTForms to render and validate forms. In Flask-Security 1.7.5, the default render_field_with_errors and render_field macros defined in "security/_macros.html" are
{% macro render_field_with_errors(field) %}
<p>
{{ field.label }} {{ field(**kwargs)|safe }}
{% if field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
{% endmacro %}
{% macro render_field(field) %}
<p>{{ field(**kwargs)|safe }}</p>
{% endmacro %}
According to the Flask-WTForms 0.10 docs, both of the above macro functions accept ...
... keyword arguments that are forwarded to WTForm’s field function that renders the field for us. The keyword arguments will be inserted as HTML attributes.
Specifically, the lines {{ field(**kwargs)|safe }} pass the HTML escaped keyword arguments to the field function. Therefore, you can add classes,
{{ render_field_with_errors(login_user_form.email, class="form-control") }}
and can also overwrite default HTML attributes,
{{ render_field_with_errors(login_user_form.email,
class="form-control", type="email", placeholder="Enter email") }}
{{ render_field(login_user_form.submit, class="btn btn-default", value="Submit" ) }}
Additionally, you can define your own macros by modifying the macros above. For example, if you wanted to use Bootstrap alerts to render form validation errors, you could define the macro function render_field_with_bootstrap_errors
{% macro render_field_with_bootstrap_errors(field) %}
<p>
{{ field.label }} {{ field(**kwargs)|safe }}
{% if field.errors %}
{% for error in field.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
{% endif %}
</p>
{% endmacro %}
Adding your own macro is pretty simple. For example, you can put custom macros in a "custom_macros.html" file within the templates directory and then load the functions into templates with
{% from "custom_macros.html" import render_field_with_bootstrap_errors %}
This way, it is easy to modify the macros to use different Bootstrap features.

Render field errors in for loop with Flask-WTF

I would like to iterate over form's fields in a template and display fields with errors like this:
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{% if form.errors.field %}
<div class="has-error"> {{ field.label }} {{ field(size=80, class_='form-control') }}</div>
<span style="color: red;">{{ form.errors.field.0 }}</span>
{% else %}
{{ field.label }} {{ field(size=80, class_='form-control') }}
{% endif %}
{% endfor %}
But that doesn't work for some reason- the form renders but the errors are not displayed.
I've already checked solutions here, and here, and also here and none of those have helped.
Could someone please advise how to fix my form to correctly render the errors?
The issue is in using form.errors.field. This would only be accurate in jinja if you had a field named field and not for any other names.
Fortunately, you're already iterating fields, and every field has a .errors property so the shortest solution is to simply use that property
Your code should look something like:
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{% if field.errors %}
<div class="has-error"> {{ field.label }} {{ field(size=80, class_='form-control') }}</div>
<span style="color: red;">{% for error in field.errors %}{{ error }}{% if not loop.last %}<br />{% endif %}{% endfor %}</span>
{% else %}
{{ field.label }} {{ field(size=80, class_='form-control') }}
{% endif %}
{% endfor %}

Categories

Resources