How to iterate over a queryset in django template? - django

I am aware that this is very likely a duplicate but solutions provided in alike questions did not help.
This is at first glance very straightforward issue, it should work by all means but for some reason, it does not.
In a Django template, I am filtering a queryset of records based on the current user. Then I loop through it and want to display each result separately. Nothing complicated. The code goes:
{% if user.is_authenticated %}
{% if user.quick_links.all %}
{{ user.quick_links.all }}
<h2>Moje rychlé přístupy:</h2>
{% for link in user.quick_liks.all %}
<div class="col-md-2">
<button class="btn btn-info">{{ link.link_name }</button>
</div>
{% endfor %}
{% endif %}
{% endif %}
the {{ user.quick_links.all }} displays
<QuerySet [<UserQuickAccessLink: Link uživatele david#email.eu: Google>, <UserQuickAccessLink: Link uživatele david#email.eu: Coding Music>]>
but then the program never enters the for loop even though the iterable is clearly there.
{% for link in user.quick_liks.all %}
<div class="col-md-2">
<button class="btn btn-info">{{ link.link_name }} </button>
</div>
{% endfor %}
The above is never executed.
What is the trick here?

If that is your actual code, in your for loop you have a typo;
It's supposed to be
{% for link in user.quick_links.all %}
and not
{% for link in user.quick_liks.all %}

Related

Django template: condition check with previous object

I need check the condition with previous object in loop.
(previous_object) is for illustration only.
{% for object in objects %}
{% if (previous_object).clicks == 0 %} #this reference must be based on the loop's previous object.
<button type="submit"> OK </button>
{% endif %}
{% endfor %}
Does anyone have any ideas?
Thanks!
You might be interested in using {% ifchanged %} filter. This condition is true only when a feature of an item is different from previous item in the list.
{% for item in items %}
{% ifchanged item.clicks %}
<button type="submit"> OK </button>
{% endifchanged %}
{% endfor %}

ListField is showing <ul> instead of <input> in edit/create post

I am using Flask, mongoengine for a project and I am trying to get basic stuff working from http://docs.mongodb.org/manual/tutorial/write-a-tumblelog-application-with-flask-mongoengine/
After implementing everything from above link I added a new field for "tags" in Post and when I try to create a post, my tags doesn't show a input box.
Any help is appreciated.
My code and screenshot below
class Post(db.DynamicDocument):
created_at = db.DateTimeField(default=datetime.datetime.now, required=True)
title = db.StringField(max_length=255, required=True)
slug = db.StringField(max_length=255, required=True)
comments = db.ListField(db.EmbeddedDocumentField('Comment'))
tags = db.ListField(db.StringField(max_length=30)) # New field I added
template form
{% macro render(form) -%}
<fieldset>
{% for field in form %}
{% if field.type in ['CSRFTokenField', 'HiddenField'] %}
{{ field() }}
{% else %}
<div class="clearfix {% if field.errors %}error{% endif %}">
{{ field.label }}
<div class="input">
{% if field.name == "body" %}
{{ field(rows=10, cols=40) }}
{% else %}
{{ field() }}
{% endif %}
{% if field.errors or field.help_text %}
<span class="help-inline">
{% if field.errors %}
{{ field.errors|join(' ') }}
{% else %}
{{ field.help_text }}
{% endif %}
</span>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</fieldset>
{% endmacro %}
rendering form code
{% extends "admin/base.html" %}
{% import "_forms.html" as forms %}
{% block content %}
<h2>
{% if create %}
Add new Post
{% else %}
Edit Post
{% endif %}
</h2>
<form action="?{{ request.query_string }}" method="post">
{{ forms.render(form) }}
<div class="actions">
<input type="submit" class="btn primary" value="save">
Cancel
</div>
</form>
{% endblock %}
From what I can gather, your problem is you're telling WTF to render the tags field, but WTForms doesn't know how to handle that information.
From looking at the Flask-MongoEngine documentation, it seems the ListField is just a FieldList as WTForms refers to it.
Currently you're not actually defining the form independently in WTForms, you're just using the magic included in Flask-MongoEngine, so my first attempt would be to add some more logic to your macro, add a {% elif field.type == 'ListField' %} and try and discover what's contained in there to iterate through to produce your form. From having a quick look at the source-code, something like the following might work.
{% elif field.type == 'ListField %}
{# render_the_group_label #}
{% for subfield in field.entries %}
{% if subfield.type == 'StringField' %}
{# render_the_subfield #}
{% endif %}
{% endfor %}
...
That code will need to be worked on, but hopefully it'll point you in the right direction. Otherwise, I'd actually define the form seperately in WTForms to give you a bit more control on the code-side. Luckily they provide a csv tag example which should help you if you need to go that route. I wrote a guide that takes a different route using #property decorators to achieve a similar effect, which again, might at least point you towards the finish line.

Django form wizard - customized form layout for each step

At the moment I'm experimenting with django form wizard. The basic set-up works now and I'm able to call different templates for each step showing variable text.
Now I want to take it a step further and create a customized form layout for each step. The documentation of Django shows a generic way to show the form, always with vertical alignment.
In my experiment I have two steps:
step 1: email and password (just two fields needing vertical alignment)
step 2: personal data: address, profession, ...
So for the step 2 I want to use a complete different form layout then step 1: using fieldsets, horizontal alignment of field (eg address: street and number), ...
Starting from the django documentation I suppose that the below can work (did not test it yet):
{% block content %}
# block step: variable text for each step
{% block step %}{% endblock %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
# block form_if: shows a complete customized form layout for each step
{% block form_if %}{% endblock %}
{% endfor %}
{% else %}
# block form_else: shows a complete customized form layout for each step
{% block form_else %}{% endblock %}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "first step" %}</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button>
{% endif %}
<input type="submit" value="{% trans "submit" %}"/>
</form>
{% endblock %}
But the problem I have here is that I have two blocks: form_if and form_else calling the same form layout. So then I have double maintenance of my form layout.
Are there better ways to accomplish what I want to achieve?
Thanks!
Kind Regards
Based on the input of Rohan and following post, I found a working solution:
my base_wizard template looks as follows:
<form enctype="multipart/form-data" action="" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
<!-- block below accesses a customized form layout for each step -->
{% block form_if %}{% endblock %}
{% endfor %}
{% else %}
<!-- block below accesses a customized form layout for each step -->
<!-- using the with statement makes it possible to use the same layout used in the form_if block -->
{% with form=wizard.form %}
{% block form_else %}{% endblock %}
{% endwith %}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" value="{{ wizard.steps.first }}" class="button">{% trans "first step" %}</button>
<button name="wizard_goto_step" value="{{ wizard.steps.prev }}" class="button">{% trans "prev step" %}</button>
{% endif %}
<div>
<input type="submit" value="{% trans "submit" %}" class="button"/>
</div>
</form>
and in the template per step I use following code:
{% extends "base_wizard.html" %}
{% block form_if %}{% block form_else %}
<fieldset>
<legend>Title</legend>
<div>
<label>{{ form.field.label }}:<p class="note">{{ form.field.help_text }}</p></label> {{ form.field }}
<p class="error">
{% if form.field.errors %}
{% for error in form.field.errors %}
{{ error }}
{% endfor %}
{% endif %}
</p>
</div>
</fieldset>
{% endblock %}{% endblock %}
Using this makes it possible to maintain just one form layout per step instead of two.
You can create different templates for each steps. The templates can produce html as you want.
To tell django to use different form templates for steps, you can follow this...
class TestFormWizard(SessionWizardView):
def get_template_names(self):
if self.steps.current == 1:
return 'step1_form.html'
if self.steps.current == 2:
return 'step2_form.html'
return 'wz_form.html'
You can define step1_form.html, step2_form.html etc. as you want.
Tip: For common code in templates (ie. management form fields), create different templates and include them in per step forms.
May be in that case you can make use of 'with' statement in templates.
Something like: in your block_if and block_else refer form as myform.
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
# block form_if: shows a complete customized form layout for each step
{% with myform=form %}
{% block form_if %}{% endblock %}
{%e endwith %}
{% endfor %}
{% else %}
# block form_else: shows a complete customized form layout for each step
{% with myform=form %}
{% block form_else %}{% endblock %}
{% endwith %}
{% endif %}
Try giving crispy-forms a look. In a nutshell, you'll have a helper instance attribute set on your forms that can pretty much control most of what you'd ever want to accomplish with structuring a form without touching the template code.
In certain cases, customizing a form's presentation makes for unwieldy templates if you end up having to write the whole markup by hand yourself. Here you can isolate and structure the mess in a form_helpers.py module in the application.
If you can work with what crispy-forms provides in terms of creating the form layout, you'll see that about 10 lines of code you need to defined the form helper's layout rids you of dozens and dozens of lines of template code you'd otherwise have to maintain.
What you would end up in your case is having multiple forms, a form helper instance for each specific form and a single template that just calls a crispy-form tag to render the form the wizard supplied for each step.

Django, loop over all form errors

At my template, I want to iterate through all form errors, including the ones that are NOT belonging to a specific field. ( which means for form.errors, it should also display for __all__ errors aswell)
I have tried several versions, Ie:
<div id="msg">
{% if form.errors %}
<div class="error">
<p><span>ERROR</span></p>
<ul>
{% for key,value in form.errors %}
{% for error in value %}
<li>{{ error }}</li>
{% endfor %}
{% endfor %}
</ul>
</div>
{% endif %}
</div>
Still no achievement, I will be greatful for any suggestion.
Form errors in Django are implemented as an ErrorDict instance (which is just a subclass of dict with extras). Try a slight adjustment to your template for loop syntax:
{% for key, value in form.errors.items %}
Are you, by any chance, looking for form.non_field_errors? That is how you would get access to the errors that aren't associated with a particular field.
{% if form.non_field_errors %}
<ul>
{{ form.non_field_errors.as_ul }}
</ul>
{% endif %}
Check the forms.py test suite as well for another example. Search for form.non_field_errors

Django Paginated Comments .. is there any existing solutions?

is there any existing pagination solution for Django contrib.comments?
What I need is just a simple paginated django comments, for the Basic Blog application (from the Django Basic Apps) I used, using a simple has_previous and has_next
I have copied the django.contrib.comments and tried modify the code but with no success. The code is pretty hard to understand (django/contrib/comments/templatetags/comments.py) because it consists of Node and Parser
here is my comments.html template I used for the Blog application:
{% load comments markup %}
{% get_comment_list for object as comment_list %}
{% if comment_list %}
<div class="comments g_7 left">
<a name="comments"></a>
<div class="subtitle">Comments</div>
{% for comment in comment_list %}
{% if comment.is_public %}
<div class="comment g_6" id="c{{ comment.id }}">
<div class="comment_name g_6">
<div class="comment_count right">
<a name="c{{ comment.id }}" href="{{ comment.get_absolute_url }}" {% ifnotequal comment.person_name null %}title="Permalink to {{ comment.person_name }}'s comment"{% endifnotequal %} class="comment_count">{{ forloop.counter }}</a></div>
Wrote by <strong>{% if comment.user_url %}{{ comment.user_name }}{% else %}{{ comment.user_name }}{% endif %}</strong> on {{ comment.submit_date|date:"F j, Y" }} - {{ comment.submit_date|date:"P" }}
</div>
<div class="comment_body g_6">{{ comment.comment|urlizetrunc:"60"|safe }}</div>
</div>
{% endif %}
{% endfor %}
<div class="clear"></div>
</div>
{% else %}
No comments yet.
{% endif %}
I think the problem lies in the get_comment_list templatetags :)
Thanks in advance
I think django-pagination might be what you're looking for.
http://code.google.com/p/django-pagination/ (screencast available)
Django also has a built in Pagination system
https://docs.djangoproject.com/en/dev/topics/pagination/