I'm having problems displaying nested blocks in a template.
eg.
{% for category in categories %}
//code to display category info
{% products = products.object.filter(category = category) %}
{% for product in products%}
//code to display product info
{% endfor %}
{% endfor %}
I'm getting a "Invalid block tag: 'endfor'" error.
Any ideas?
You cannot assign to variables in the Django template system. Your two attempts:
{% products = products.object.filter(category = category) %}
and
{% products = category.get_products %}
are both invalid Django syntax.
Some Python templating systems are PHP-like: they let you embed Python code into HTML files. Django doesn't work this way. Django defines its own simplified syntax, and that syntax does not include assignment.
You can do this:
{% for category in categories %}
//code to display category info
{% for product in category.get_products %}
//code to display product info
{% endfor %}
{% endfor %}
I think you cannot use arguemnts for methods. You have to modify your categories object, so that you kann use:
{% for product in category.products %}
{% products = products.object.filter(category = category) %}
is not recognized as a valid tag in the django template system. Therefore django complains about the missing endfor, although the {% for x in y %) is not the error.
This should work
{% for category in categories %}
{% for product in products.object.all %}
//code to display product info
{% endfor %}
{% endfor %}
But this is not that, what you want to achieve. Simply you are not able to filter on product.objects with the argument category.
You have to write your own tag which takes arguments on filtering or rethink your problem.
Related
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?
I'm using a list to populate / generate some html code dynamically as shown below,
<ul>
{% if results %}
{% for result in results %}
<li><a href="/accounts/evalpage/" ><strong>{{result.0}}</strong>{{result.1}}</a></li>
{% endfor %}
{% else %}
<li><strong>No Evaluations to Perform</strong></li>
{% endif %}
</ul>
I'm running into an issue with that if one of the list items is clicked, i need to be able to retrieve the information stored in that list item, e.g if item one is clicked i need to retrieve {{result.0}} and {{result.1}} is there a way i can retrieve this information?
List is shown below :
[['User1', 'InProgress'], ['User2'], ['User3'], ['User3'], ['User4']]
For instance, if the row containing User1 and InProgress is clicked by the end user, i want to be able to have the information User1 and InProgress within Django such that operations can be performed with them
It should be clear that in order for the backend to know what object you clicked on, you need to pass that value in the URL. So, you'll need to change the definition of your "evalpage" URL to accept a parameter:
url(r'^accounts/evalpage/(?P<user>\w+)/$', views.evalpage, name='evalpage')
and the view signature:
def evalpage(request, user):
...
and now you can do:
...
try this:
<ul>
{% if results %}
{% for result in results %}
<li>
<a href="/accounts/evalpage/" >
{% for item in result %}
<strong>{{item}}</strong>
{% endfor %}
</a>
</li>
{% endfor %}
{% else %}
<li><strong>No Evaluations to Perform</strong></li>
{% endif %}
</ul>
I want to filter a result of a field in django in an html file.
Something like this
{{ model.field where id = 2 }}
I've been looking for in django docs but i only could find a way to do it on the views.py.
I also so something like javascript when u write a "|" simbol after the request but i still couldnt archieve it
You can use the {% if %} template tag. So:
{% if model.field == 2 %}
# do something
{% endif %}
Here is the official documentation:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#operator
Edit:
If model.field has a value of 2 then it just needs to be the above.
Edit 2:
Without seeing your code, it is hard to tell, but here is how to filter for Users based on Gender in a template:
{% for user in users %}
{% if user.gender == "male" %}
# do something
user.username
{% endif %}
{% endfor %}
I got a problem with iteration on zinnia tag outcome. Let's say that that tag returns a list of some categories, I tried to manage it in few ways:
{% with categories=get_plain_categories %}
{% for category in categories %}
<h1>{{ category }}</h1>
{% endfor %}
{% endwith %}
or simply:
{% for category in get_plain_categories %}
<h1>{{ category }}</h1>
{% endfor %}
But in both ways, it seems to not even run get_plain_categories tag (I made few prints in it), but when I write : {% get_plain_categories %}, it returns list as it's supposed to.
How should I get that working?
Unfortunatelly with tag is not that powerful, you can't use it with output of other tags. You'll have to create your own tag.
As an example you can have a look at the static. It lets you insert a path to a static file with {% static "images/hi.jpg" %} but you can't easily save it to a variable for later use. That's why in Django 1.5 it got a new syntax {% static "images/hi.jpg" as myphoto %} and this way you can later use {{ myphoto }}. This can't be achieved with with.
That said, I can't find any mentions of get_plain_categories in Google, which is weird.
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 %}