Why is my loop terminating before all items are looped through? - python

So I'm using Django and trying to dynamically add a users gists to the page using githubs embedded gists.
this is the loop
{% for i in snippets %}
<div class="tile is-4">
<div style="height:25vh;"><script src="https://gist.github.com/{{i.owner.login}}/{{i.id}}.js"/></div>
</div>
{% endfor %}
the list im looping through contains two items, however only the first is added.
if I do something along these lines however it correctly displays the two different id's
{% for i in snippets %}
{{i.id}}
{% endfor %}
I read that the github script calls document.write(), I have a gut feeling this is where my issue lies.
Would document.write() break my loop?

Related

Nested for loop with if statement in Jinja fails to work

enter image description hereenter code here`
<div class="container">
{% for bookmark_title in bookmarks_titles %}
<div class="container-head">
<h2>{{ bookmark_title.title }}</h2>
<span>{{bookmark_title.description}}</span>
</div>
{% for bookmark in bookmarks %}
{% if bookmark.tag == bookmark_title.title %}
<div class="container-body">
<img src="{{bookmark.favicon}}" alt="icon" /> {{ bookmark["title"]}}
</div>
{% endif %}
{% endfor %}
{% endfor %}
</div>
When I run the HTML the first for loop works as expected however, the second nested for loop and if statement only runs after the parent for loop ends.
But I want to return the "Bookmark" saved under each Bookmark_title.title.
As you can see in the attached image for nested for loop works only after the parent for loop ends.
Any suggestion, please.
In the process of filtering all the bookmarks before passing them to the HTML page. Instead of appending the filtered data from the database.db I was replacing with the new results so only the bookmarks, I filtered using the last title tag in this case Entertainment only passed into the HTML page which caused the issue.
To fix it I filtered all the bookmarks from the database.db since the 'Bookmarks' sheet only has the bookmarks, so I don't need to filter by tag.)
# Previously
for tag in tags:
bookmarks = db.session.query(Bookmarks).filter_by(tag=tag)
Fix
bookmarks = db.session.query(Bookmarks).all()

HubL template language list logic

I'm working in a cms called Hubspot using a templating language called HubL. Hubspot is written in python and HubL closely resembles Jinja2 or Django templates. Usually when I need to find an answer I can search for the answer in jinja2 and find what I need. I have been trying to figure this out for a few weeks now though but I think the issue is to specific.
Hubspot hosts blogs. These blogs accessible under the "contents" variable in a blog template or by using a pre-defined function on any other template type:
{% for content in contents %}
{# output blog list #}
{% endfor %}
or
{% set test_list = blog_recent_posts('default', 250) %}
{% for post in test_list %}
{# output blog list #}
{% endfor %}
Each blog post has a topics_list variable. this variable contains a list of topics set to a specific blog. you would use it inside the blog list loop by looping through it.
{% for content in contents %}
{% for topic in content.topic_list %}
{{ topic.name }}
{% endfor %}
{% endfor %}
If you just call topic_list:
{% for content in contents %}
{{ content.topic_list }}
{% endfor %}
it outputs:
[topic1, topic2]
The issue I am having is that I need to exclude posts with specific topics from the main list. I can use a nested for loop and a condition to exclude then from output:
{% for content in contents %}
{% for topic in content.topic_list %}
{% unless topic.name = 'topic 1' %}
{# ouput if condition is not met #}
{% endunless %}
{% endfor %}
{% endfor %}
This is messy. It loops through the blogs and at each index loops through the topics. if a topic matches the defined topic then it is omitted from output. This works, except that it doesn't omit the blog from contents. The blogs that are block from output still exist at their index. If I limit the output to 3 blogs, for instance, and one of the three blogs has a topic that matches 'topic 1', the space isn't filled with the next blog in line, the space is just left blank.
Actually what this is doing is outputting the markup for a list item for each topic of each blog as long as that topic doesn't match the blocked topic so it will duplicate posts if more than one topic is present.
I thought about using the predefined function, which you can use to define a specific topic you want posts for, so I looped through a global list of topics tied to the blog, and if the topic doesn't equal blocked topics it runs the topic specific function:
{% set mlist = [] %}
{% set global_topics = blog_topics('default', 250) %}
{% for gtopic in global_topics %}
{% unless gtopic == 'topic1' %}
{% set wlist = blog_recent_posts('default', 250, gtopic.slug) %}
{% set mlist2 = mlist.append(wlist) %}
{% endunless %}
{% endfor %}
{% for post in mlist[0] %}
<strong>{{post.name }}</strong><br>
{% for topic in post.topic_list %}
{{topic.name}}<br>
{% endfor %}<br> <br>
{% endfor %}
I'm honestly surprised I got this to work period but it combines the list created from each topic and outputs them. The only issue is that because multiple topics are applied to the topic lists, while it doesn't include a list created from the blocked topic, it still includes blogs containing the blocked topic from lists created using the second or third (etc.) topic on the blog post.
The simplest solution would be to create a new list by filtering post by if the topic is IN the topic_list but this doesn't work.
{% set mlist = [] %}
{% for content in contents %}
{% unless 'topic-1' is in content.topic_list %}
{% set mlist2 = mlist.append(content) %}
{% endunless %}
{% endfor %}
but I guess you can't use 'in' like this? it doesn't work.
Please keep in mind that I understand that this would be a non-issue if I did this filtering in python directly instead of in the template, and I understand that logic shouldn't be handled in the template, but Hubspot doesn't allow custom python scripting or any back end capability so this is what I have to work with. Can anyone think of a creative solution?

Need to print the statement inside for loop only once - Django

SO in my template i need to print a statement only once inside the for loop even it iterates many times. my code is :
{% for interview in scheduledinterviews %}
{% if interview.slot.start.date == today.date %}
<div class="row">
<div class="col-xs-12 profile-dash">
<h4>Today's Interviews</h4>
</div>
</div>
I need to Print Todays Interview only once as it satisfies the if condition inside the loop. What Should i do?
You can use the ifchanged tag.
{% ifchanged interview.slot.start.date %}<h4>Today's Interviews</h4>{% endifchanged %}
Sorry to disappoint you but there is no break tag in django template. For me the easiest way to go is to prepare your context data better in the respective view prior to rendering the data.

django philosophy: when to include templates and when to have code generate html?

When using Django templates, should I have some templates that act like "subroutines", so to speak, or should I generate HTML from within my code in these cases?
For example, I have a template with several lists of names, each of which I want to turn into a select. Should I have a template that renders the name_list variable into a select, and do something like this:
#in the view:
return {'name_list_1': name_list_1,
'name_list_2': name_list_2,
'name_list_3': name_list_3}
#in the template:
{% with name_list_1 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_2 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_3 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
Or should I have a function in my code, name_list_to_select_html, which does the same job, and do this:
return {'name_list_1_html': name_list_to_select_html(name_list_1),
'name_list_2_html': name_list_to_select_html(name_list_2),
'name_list_3_html': name_list_to_select_html(name_list_3)}
#in the template:
{{ name_list_1_html|safe }}
{{ name_list_2_html|safe }}
{{ name_list_3_html|safe }}
Or are both of these wrong and I am getting the philosophy totally wrong?
Additional question: in terms of speed, is it slow to constantly include templates? Is that a bonus point for the in-code html generation?
Generally, HTML should only be generated in the templating system or directly related code. That keeps the view of the data completely separate from the business and functional logic. I feel that's a proper separation of concerns. Go with your first solution.
As for performance, Django should probably take around the same amount of time running either code. But it has built-in view and template fragment caching if you know those segments of code don't need to be regenerated on every request.

Question on Django: Displaying many to many fields

I seem to have a problem with Django when it comes Rendering ManyToManyField in a template. I can make it work partially, but I cannot make it work properly as I want it.
Firstly I have an invoice template which displays Invoice details from my data base
#invoice_details.html
{% extends "base.html" %}
{% block content %}
<h2>Invoice Details</h2>
<div id="horizontalnav">
Add an Invoice
Add a Work Order
Add Payment
</div>
<ul>
<div id="list">
{% for invoice in invoices_list %}
{{invoice.client}}<br/>
{{invoice.invoice_no}}<br/>
{{invoice.contract_info}}<br/>
{{invoice.date}}<br/>
{{invoice.work_orders}}<br/>
{% endfor %}
</div>
</ul>
{% endblock %}
In my database, {{invoice.work_orders}} was displayed like the following below. This is because {{invoice.work_orders}} uses a manytomanyfield
<django.db.models.fields.related.ManyRelatedManager object at 0x8a811ec>
Now I tried to change {{invoice.work_orders}} to {{invoice.work_orders.all}} and I got this.
[<Work_Order: Assurance Support Service >]
This sort of works, but I want it to display "Assurance Support Service" only. So I am wondering how I can do this change if possible.
The content of {{invoice.work_orders.all} is a list of Work_Order objects.
If you want to print them, you should iterate the list:
{% for invoice in invoice.work_orders.all %}
{{invoice}}<br />
{% endfor %}

Categories

Resources