I'm having a peculiar problem with a django template I'm setting up: I have a {{ name }} variable that I'm passing to my template, and at the same time, I have a notes list coming from a client-side api that has both a {{ name }} and a {{ body }}.
Whenever I try to print out the name of the note, the other {{ name }} shows up. Which is odd. Here's my code for the notes:
<div class="notes">
{% for note in notes %}
<p><strong>{{ name }}</strong></p>
<p>{{ body }}</p>
{% endfor %}
</div>
Am I doing something wrong? Is there a context operator I can use or something?
<div class="notes">
{% for note in notes %}
<p><strong>{{ note.name }}</strong></p>
<p>{{ note.body }}</p>
{% endfor %}
</div>
This is a common mistake that is made when working with Handlebars alongside Django since Handlebars changes scope automatically for you. All you need to do is refer to the note variable you created with the for loop:
<div class="notes">
{% for note in notes %}
<p><strong>{{ note.name }}</strong></p>
<p>{{ note.body }}</p>
{% endfor %}
</div>
More info here: https://docs.djangoproject.com/en/1.5/ref/templates/builtins/#std:templatetag-for
Related
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.
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 %}
for implementation of django-likes i need objects that's gonna use in {% like object %}. if i am using object = Article.objects.get(pk=1) then the like system for particular article working fine. But i am using filter because i need particular filed values for template language. From filter or any other method can i get object so my like system will work ?
views
settings = Article.objects.filter().values('title','content', ..).order_by('-creation_date')
template_var['settings'] = settings
html
{% for x in settings %}
<h2 class="blog-post-title">{{ x.title }}</h2>
<p>{% likes object %} </p>
<p class="blog-post">{{ x.created }} by {{ x.user__username }}</p>
<p>{{ x.content }}.</p>
</div>
{% endfor %}
This is the question how can i get each object out of from settings currently i am getting list because of filter api
If you just use filter(), and don't use values(), then you'll get a queryset of articles
articles = Article.objects.filter().order_by('-creation_date')
If you then loop through articles in your template, you will have article objects that you can use with the template tag. You can still use access attributes like {{ article.created }} as before.
{% for article in articles %}
<h2 class="blog-post-title">{{ article.title }}</h2>
<p>{% likes article %} </p>
<p class="blog-post">{{ article.created }} by {{ article.user.username }}</p>
<p>{{ article.content }}.</p>
</div>
{% endfor %}
I'm not able to determine whether a variable is empty when used in the template.
I've iterated through the whole collection and in each I'm looking for a variable narrative_text.
I tested the empty variable by
{% ifnotequal narratives.narrative_text '' %}
I notice the control enters this block, but prints nothing/blank when the
{{ narratives.narrative_text }}
is encountered.
So, how do I precisely check if the variable is empty?
I read the docs and found out that invalid/empty template variables are replaced by ''.
The doc says that
the template system inserts the value of the TEMPLATE_STRING_IF_INVALID setting.
Do we have to explicitly enter that into the settings.py? I tried doing so but still I haven't been able to make it work.
c=Context({
"narratives_list":all_narratives,
"patient_name":care_seeker_name
})
all_narratives is returned by a pymongo database call.
{% for narratives in narratives_list %}
<tr>
<td class = "date_col">
7 Aug, 2012
</td>
{% ifnotequal narratives.narrative_text '' %}
<td>
<div class = "narrative">
( text narrative )
<b>
{{ narratives.about }}
</b>
<br><br>
{{ narratives.narrative_text }}
</div>
</td>
{% else %}
<td>
<div class="scans">
<div class="gallery">
<b> {{ narratives.about }}</b>
<br><br>
<a href="https://udhc1-nodejstest.rhcloud.com/my_image/{{ narratives.file_id }}">
<img src="https://udhc1-nodejstest.rhcloud.com/my_image/{{ narratives.file_id }}" width="72" height="72" alt="" />
</a>
</div>
</div>
</td>
{% endifnotequal %}
Pipe through length and do your test against that value.
{% if narratives.narrative_text|length > 0 %}
{{ narratives.narrative_text }}
{% else %}
None
{% endif %}
Just use {% if narratives.narrative_text %}, I think. It will use Python's implicit false, which applies for empty strings, empty arrays, empty dicts, None, False, 0 etc..
Just confirmed via my own code using django 2.1.3 and python 3.5 and 3.7 that the following works:
{% if narratives.narrative_text %}
# do something
{{ narratives.narrative_text }}
{% else %}
# do something else
None # displays "None"
{% endif %}
I think that the best and obvious solution would be, in Django Template language:
{% if objects is not None %}
{% for obj in objects %}
{{obj}} // Do your stuff here
{% empty %}
No results. // No results case
{% endfor %}
{% endif %}
In case the variable objects is not set, nothing will be printed out.
I had similar difficulties.
Hope it helps.
You can write Custom template filter, is_empty to check. Return false if variable is empty and true if value exists.
{% if narratives.narrative_text|is_empty %}
# dosomthing
{% else %}
# dosomthing
{% endif %}
I've used jijnja which is a lot similar and simpler and I think it would work if you do
{% if not narratives.narrative_text %}
// do something
{% else %}
// do something else with or without {{ narratives.narrative_text }}
{% endif %}
It uses python implicit True/False,None, etc to do the job.
In simplest terms use python variables inside {{ }} and conditionals,etc inside {% %}
I have very simple contact form and I would like to hide the label somehow so that it doesn't show Csrf Token. I am using Flask and Flask-WTForms and am rendering the form like this:
{% for field in form %}
{{ field.label }}
{{ field }}
{% endfor %}
So basically this shows my inputs correctly and the csrf oen is hidden but the label isn't hidden? Should I get over it and implicitly say form.field_name instead of looping through the form or is there a way to handle this "corner case".
I was thinking about doing a logical check in either the for loop declaration or the label declaration but so far I haven't found anything in the documentation that has worked.
Thanks
EDIT: I have "fixed" the problem by doing this but it feels kinda dirty and hacky which I don't like I am still open to a better solution:
{% if not loop.first %}
{{ field.label }}
{% endif %}
If you want a more general solution that works for all hidden fields instead of just the CSRF token:
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{{ field.label }}
{{ field }}
{% endfor %}
form.hidden_tag() is supplied by Flask-WTF.
Just to add to JD's excellent answer...
For those stumbling across this question: You can avoid losing the (csrf) hidden field (and thus protection) by adding the condition "if field.widget.input_type!='hidden' " specifically to the label instead of to the form iterator.
i.e.:
not
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{{ field.label }}
{{ field }}
{% endfor %}
but
{{ form.hidden_tag() }}
{% for field in form %}
{% if field.widget.input_type != 'hidden' %} {{ field.label }} {% endif %}
{{ field }}
{% endfor %}
I think this should work too:
{% for field in form if field.id != 'csrf_token' %}
{{ field.label }}
{{ field }}
{% endfor %}
I have found the way to do it like this:
{% if field.id != 'csrf_token' %}
I believe this to be less hacky. I found this from modifying the example here in the docs.
I made a macro recently to submit forms through ajax in order to not reload the webpage and send it to the api directly.
{% macro render_fields3(form, form_name, method) %}
<form class="ajax" name={{ form_name }} method={{ method }}>
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
<dt>{{ field.label }}
<dd>{{field(id=field.name + method)|safe}}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endfor %}
</form>
{% endmacro %}