If I include paginator, then its printing multiple paginator on same page. because I am including in forloop. How do I solve this problem? please help
----------------------
{% autopaginate recipes %}
{% for recipe in recipes %}
{{ forloop.counter }}
{% endfor %}
-----------
here is my full code.
{% with followers=current_user.get_profile.get_following.all %}
{% for follower in followers %}
{% with recipes=follower.recipe_set.all %}
{% for recipe in recipes %}
{{ forloop.counter }}
{% endfor %}
{% endwith %}
{% endfor %}
{% endwith %}
Result - > 1 2 3 1 2 3 ...... 50. It should be 53. So I can easily use paginator
thanks
the doc string in the setup.py file of django-pagination mentions the below,
Decide on a variable that you would like to paginate, and use the autopaginate tag on that variable before iterating over it. This
could take one of two forms (using the canonical object_list
as an example variable):
{% autopaginate object_list %}
This assumes that you would like to have the default 20 results per page. If you would like to specify your own amount of
results per page, you can specify that like so:
`{% autopaginate object_list 10 %}`
Note that this replaces object_list with the list for the current page, so you can iterate over the object_list like you normally would.
Now you want to display the current page and the available pages, so somewhere after having used autopaginate, use the paginate
inclusion tag:
{% paginate %}
This does not take any arguments, but does assume that you have already called autopaginate, so make sure to do so first.
That's it! You have now paginated object_list and given users of
the site a way to navigate between the different pages--all without
touching your views.
So, where are you using paginate tag after the autopaginate? You actually need not loop through recipes, autopaginate should do that for you wherever you call paginate.
Related
I have ListBlock called imagesin Wagtail. It works well. If I put
{{ page.images }}
in a template, it render the html code like:
<ul>
<li>item1</li>
<li>item2</li>
</ul>
But I am unable to find out how to get the first item of the list isolated. Or at least how to iterate over the list manually.
I am pretty sure the solution is simple, however I am unable to google it, find in the docs, or understand from the wagtail source.
You haven't shared your model definition, but I'm going to guess it's something like:
class MyPage(Page):
images = StreamField([
('image_list', blocks.ListBlock(blocks.ImageChooserBlock)),
])
Using the standard pattern for manually looping over a StreamField value as shown in the Wagtail docs, this would be:
{% for block in page.images %}
{% if block.block_type == 'image_list' %}
{# at this point block.value gives you the images as an ordinary Python list #}
{# Output the first image using block.value.0: #}
{% image block.value.0 width-800 %}
{# Or loop over block.value manually with a 'for' loop #}
<ul>
{% for img in block.value %}
<li>{% image img width-800 %}</li>
{% endfor %}
</ul>
{% elif block.block_type == 'some_other_block' %}
...
{% else %}
...
{% endif %}
{% endfor %}
In this case, you probably only have one block type defined (image_list), so the if block.block_type == 'image_list' can be left out; but you'll still need the outer {% for block in page.images %}, because StreamField is still defined as a list of blocks, even if you only have one item in that list.
Doing this works
{% for comment in comments %}
{{ comment.user }}
{% endfor %}
However, I want to get all the comment.user values in the dictionary without using a for loop. Is this possible?
I ask because I need to do this check
{% if name in comment.user %} # check if name is in any one of the comments
# do something
{% endif %}
Basically, you need to get all the distinct users from comments. You have to do it in the view and pass users queryset back into the template:
users = User.objects.filter(comment__in=comments).distinct()
Here's what I'm trying to achieve in "pseudo code":
{% for page in pages %}
{% if 'can_access_page_{{page.name}}' in perms %}
<li>
{{ page.name }}
</li>
{% endif %}
{% endfor %}
How to do this? Permission names I can customize — but still can't figure out this one.
Simplest way is to slightly abuse Django's existing add template filter (intended for numbers but works for strings), as in this answer:
https://stackoverflow.com/a/4524851/202168
You'll need a custom filter. Something like:
#register.filter
def check_page_perms(page, perms):
return 'can_access_page_%s' % page.name in perms
and use it:
{% if page|check_page_perms:perms %}
Are there any performance differences between handcoding forms in django (as well as all the validations in the views.py) and using django's form library? If they are roughly the same, in which scenarios would one handcode a form over using the built-in ones?
Also, What about handcoding the HTML templates and using the django block tags, etc. to re-use certain areas?
Do you have insane, zero-tolerance performance requirements? As in: will people actually die or come to harm or you be fired if a page takes an extra few milliseconds to render?
I doubt it, so just let the framework do the lifting up to the point where you need more control over the HTML output -- that's actually far more likely a scenario than you needing to avoid executing some Python to save (at an utter guess) 15ms.
When you do need more control, that's when it's best to splice in some handmade HTML, or - even better - create an include/partial for form fields that you can reuse everywhere, to save you the time of manually writing more than you need to, but still giving you a lot more flexibility than myform.as_p etc
Here's a rough snippet I use and adapt a lot, to give me lots of control over form fields and also let me leverage the Django templating framework to save me time:
In my template:
{% for form_field in myform %}
{% include "path/to/partials/form_field_as_p.html" %}
{% endfor %}
And in that form_field_as_p.html, something like:
{% if not form_field.is_hidden %}
<p>
{% if form_field.errors %}
{% for error in form_field.errors %}
<span class="errorlist">{{error}}</span>
{% endfor %}
{% endif %}
{{ form_field.label_tag }}
{% if form_field.field.required %}
<span class="required">*</span>
{% endif %}
{{ form_field }}
{% if form_field.help_text %}
<span class="form-help-text">{{ form_field.help_text }}</span>
{% endif %}
</p>
{% else %}
<div>{{ form_field }}</div> {# hidden field #}
{% endif %}
Django templates offer the builtin tag cycle for alternating between several values at different points in a template (or for loop in a template) but this tag does not reset when it is accessed in a scope outside of the cycles definition. I.e., if you have two or more lists in your template, the rows of all of which you'd like to use some css definitions odd and even, the first row of a list will pick up where the last left off, not with a fresh iteration from the choices (odd and even)
E.g., in the following code, if the first blog has an odd number of entries, then the first entry in a second blog will start as even, when I want it to start at odd.
{% for blog in blogs %}
{% for entry in blog.entries %}
<div class="{% cycle 'odd' 'even' %}" id="{{entry.id}}">
{{entry.text}}
</div>
{% endfor %}
{% endfor %}
I've tried obviating this by patching with the resetcycle tag offered here:
Django ticket: Cycle tag should reset after it steps out of scope
to no avail. (The code didn't work for me.)
I've also tried moving my inner loop into a custom tag, but this also did not work, perhaps because the compile/render cycle moves the loop back into the outer loop? (Regardless of why, it didn't work for me.)
How can I accomplish this simple task!? I'd prefer not to create a data structure in my view with this information pre-compiled; that seems unnecessary. Thanks in advance.
The easiest workaround (until the resetcycle patch gets fixed up and applied) is to use the built-in "divisibleby" filter with forloop.counter:
{% for entry in blog.entries %}
<div class="{% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}" id="{{ entry.id }}">
{{ entry.text }}
</div>
{% endfor %}
A little more verbose, but not hard to understand and it works great.
https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#cycle
{% for o in some_list %}
<tr class="{% cycle 'row1' 'row2' %}">
...
</tr>
{% endfor %}
Give up and use Jinja2 Template System
I gave up on django template language, it's very restricted in what you can do with it.
Jinja2 uses the same syntax that the django template uses, but adds many enhancements over it.
EDIT/NOTE ( I know it sounds like a big switch for just a minor issue, but in reality I bet you always find yourself fighting the default template system in django, so it really is worthwhile and I believe it will make you more productive in the long run. )
You can read this article written by its author, although it's technical, he mentions the problem of the {% cycle %} tag in django.
Jinja doesn't have a cycle tag, it has a cycle method on the loop:
{% for user in users %}
<li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
{% endfor %}
A major advantage of Jinja2 is that it allows you to use logic for the presentation, so if you have a list of pictures, you can put them in a table, because you can start a new row inside a table every N elements, see, you can do for example:
{% if loop.index is divisibleby(5) %}
</tr>
{% if not loop.last %}
<tr>
{% endif %}
{% endif %}
you can also use mathematical expressions:
{% if x > 10 %}
and you can access your python functions directly (but some setup is required to specify which functions should be exposed for the template)
{% for item in normal_python_function_that_returns_a_query_or_a_list() %}
even set variables ..
{% set variable_name = function_that_returns_an_object_or_something() %}
You can use tagged cycle and resetcycle (new in Django 1.11) calls (from https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-resetcycle ):
{% for blog in blogs %}
{% cycle 'odd' 'even' as rowcolors silent %}
{% resetcycle rowcolors %}
{% for entry in blog.entries %}
{% cycle rowcolors %}
<div class="{{ rowcolors }}" id="{{entry.id}}">
{{ entry.text }}
</div>
{% endfor %}
{% endfor %}
I end up doing so, with the forloop.counter0 - It works great!
{% for product in products %}
{% if forloop.counter0|divisibleby:4 %}<div class="clear"></div>{% endif %}
<div class="product {% if forloop.counter0|divisibleby:4 %}col{% else %}col20{% endif %}">
Lorem Ipsum is simply dummy text
</div>
{% endfor %}
The easiest answer might be: "give up and use jQuery." If that's acceptable it's probably easier than fighting with Django's templates over something so simple.
There's a way to do it server-side with an iterator that doesn't keep a simultaneous copy of all the entries:
import itertools
return render_to_response('template.html',
{
"flattened_entries": itertools.chain(*(blog.entries for blog in blogs)),
})