Django template browse a table with variable - html

I have a query result on my views and i drop to my template, on my template i want to display values of my table, so i use
{{myTable.0}} and {{myTable.1}}
and i have the result of my query, but i want to display this values with a variable like {{myTable.x}} where x =0 to use in a loop for.
But it doesn't work, so if you have any solution.

Seems like myTable is a list an you want to iterate through this list. If so then you can use the {% for %} template tag:
{% for val in myTable %}
{{ val }}
{% endfor %}

Related

Feed Jinja list with results of SQL query

I'm new to DBT and Jinja and wondering if it is possible to dynamically define a list using a SQL query. Instead of manually declaring the items of the list like:
{% set myOrders = [123,234, 345, 456, 567] %}
Define the list with a SQL query, something like this:
{% set myOrders = SELECT DISTINCT OrderNum FROM OrdersTable ORDER BY OrderNum %}
Is this possible?
Thanks!
Yes! Not quite as you've written it, but this is supported.
First, a note that this is inherently difficult because DBT typically runs in two phases:
templates are compiled to make actual SQL queries (i.e. all the Jinja gets executed)
the compiled SQL queries are executed
But there is a construction, {% if execute %}, that allows you to defer compilation to the execution stage.
Straightforwardly adapting the example in the docs for your use case:
{% set my_orders_query %}
SELECT DISTINCT OrderNum
FROM {{ ref('OrdersTable') }}
ORDER BY OrderNum
{% endset %}
{% set rows = run_query(my_orders_query) %}
{% if execute %}
{# Return the first column #}
{% set myOrders = rows.columns[0].values() %}
{% else %}
{% set myOrders = [] %}
{% endif %}

Looping through the length of a list in jinja2

I'm looking to populate something similar in jinja in html.
for i in range(len(my_list)):
for j in my_list:
print(i,j)
I need both the i, j value as well and to not just iterate through the list.
Don't know if there is something equivalent to range in jinja2
You can use loop.index0 for the purpose:
{% for i in my_list %}
{{loop.index0}} {{i}}
{% endfor %}

jinja2 - create href with variable from loop

I'm try to create a dynamic href for a website
I've tried this:
(where "gruppe" is a list of servers)
{%- for item in groups[gruppe] %}
{% set url = 'https://cmk.abc.local/abc/check_mk/view.py?host=' + {{ hostvars[item]['openstack']['name'] }} + '&site=abc&view_name=host' %}
{{ hostvars[item]['openstack']['name'] }}.abc.local
{% endfor %}
Expected result should be:
https://cmk.abc.local/abc/check_mk/view.py?host=server01&site=abc&view_name=host#
Does anyone have an idea what I'm doing wrong?
It's tough to say without knowing the shape of the data. If you can post what "groups" looks like (as JSON) that would be helpful.
The first thing that stands out to me is "gruppe". Is that supposed to be a key in the groups object or is that supposed to be dynamic?
Try:
{%- for item in groups["gruppe"] %}
...

dbt jinja returning the results of a query

I am trying to model the following situation:
given some query, return multi-column result-set (e.g. run_query or db_utils.get_query_results_as_dict
iterate over in a case/statment
for exmaple:
{% set conditions = dbt_utils.get_query_results_as_dict("select comment, criteria from "
~ ref('the_model') %}
...
select case
{% for condition in conditions %}
when {{ condition["criteria"] }}
then {{ condition["comment"] }}
{% endfor %}
Have not been able to get this to work, any guidance appreciated.
Some ideas I tried:
get_column_values x2 and zipping them into a new list of tuples. zip not recognised
get the count(*) from the_model then trying to iterate over the range - ran into issues with types
various for conditions {% for k, v in conditions.items() %}
Was able to self resolve with the following:
{% set conditions = dbt_utils.get_query_results_as_dict("select criteria, comment from " ~ ref('reference_data') ~ " order by sequence desc") %}
with main as (
select * from {{ ref('my_other_model') }}
),
-- [NEEDS_REVIEW] there's probably a cleaner way to do this iteration - however it's interpolated result. Could do with the zip function.
comments as (
select
*,
case
{# {{- log(conditions, info=True) -}} #}
{%- for comment in conditions.COMMENT -%}
when {{ conditions.CRITERIA[loop.index0] }}
then '{{ comment }}'
{% endfor %}
end as comment
from main
)
select * from comments
The gotchas:
this was on snowflake, so the keys returned by the function will be up-cased as that is how I loaded the data.
Using the loop.index0 to get the current iteration of the loop and index into the other collection of tuples (in this case CRITERIA).
i added a SEQUENCE key to my reference data just to ensure consistent rendering by using that to order. The criteria do overlap a-little bit so this was important.

Can I filter records I loop through in for loop? Python Template

Currently, I am using a for loop in my Django template like this:
{% for item in itemlist.items.all %}
<!-- do something -->
{% endfor %}
Now this works great for looping through all records in my itemlist, but I would like to add a filter, for example let's say that my items have a price and I would like to only loop through the items where the price is >5. How can I achieve this? Is there a way to slice like there is with if statements?
I tried something like this but that didn't work"
{% for item in itemlist.items.all|price > 5 %}
Thanks for the help!
You can do this in your models.
Define a model method.
class ItemList(models.Model):
field1 = models.CharField(...)
def get_items(self):
return self.items.filter(price__gt = 5)
In your template you can do something like this.
{% for item in itemlist.get_items %}
<!-- do something -->
{% endfor %}