Django Dictionary/Tuple iteration - python

I am working on a project for school, and am having a lot of trouble with Templates in Django.
My code is below, the first block is Python in a function, bear in mind I removed a lot for easy viewing.
amounts = [('None ',), ('1 1/2 oz',), ('1 oz',), ('1/2 oz',), ('1/2 ml ',), ('15 ml',), ('35 ml',), ('splash',), ('6 splashes',), ('10 dashes',), ('25 ml',), ('3 slices',)]
data = {
'amounts': amounts,
'ingredients': ingredients,
}
amount1 = request.GET.get('amount1')
print(amount1)
return render(request, 'addcocktail.html', {'data': data})
This block is my HTML file:
<select name="amount1" id="amount1">
{% for key, value in data.items %}
{% if key == 'amounts' %}
{% for amount in value %}
<option value = {{amount}}> {{ amount.0 }}</option>
{% endfor %}
{% endif %}
{% endfor %}
</select>
When I select 1 oz on the website, amount1 is printed as:
1
which is the first half of the string in the tuple: '1 oz'.
I was wondering if anyone knew what the problem here is.

Thank you Chillie, I solved it by removing the value = {{ amount }}, so it then takes the content that is displayed to the user as the value, the final HTML is:
<select name="amount1" id="amount1">
{% for key, value in data.items %}
{% if key == 'amounts' %}
{% for amount in value %}
<option> {{ amount.0 }}</option>
{% endfor %}
{% endif %}
{% endfor %}
</select>
I assume the value attribute only takes strings as an answer, so it was only taking the first half of the string.

Related

Django template: How to use variables in an {% if x == y %} statement?

In a Djgano template I want to include a {% if x == y %} statement where both x and y are variables as follows:
<title>Category: {{category_id}}</title>
<select name="category_id">
{% for category in categories %}
<option value="{{category.id}}"
{% if category.id is category_id %} selected {% endif %}>{{category.id}} : {{category.name}}</option>
{% endfor %}
The {{category_id}} variable is set and in the context. It displays correctly if places outside of the {% if %}, but inside the {% if %} bracket does not work.
{% if category.id == category_id %}
does not work. I assume that in this case category_id is simply read as a non-variable.
{% if category.id is {{category_id}} %}
{% if category.id == {{category_id}} %}
Gives an error:
"Could not parse the remainder: '{{category_id}}' from '{{category_id}}'"
{% if category.id is category.id %}
Works, of course, but of course that means that everything in the loop will become "selected".

Django display a value from a dictionary within dictionary

I'm trying to display values from a dictionary within a dictionary in a template using django.
I have a dictionary like this in my views:
characters = {
"char1": {'name': "David",
'stars': 4,
'series': "All star"},
"char2": {'name': "Patrick",
'stars': 3,
'series': "Demi god"}
}
I can display the whole dictionary on the page, however I want to display only the 'name' and 'David' key:value pairs. I wrote the following in the template:
{% for char in characters %}
{% for key, value in char %}
{{ key }}: {{ value }}
{% endfor %}
{% endfor %}
However this doesn't show me anything. What is wrong with this double loop?
Thanks
You have to add .items when you loop through key value pairs.
See below (Python 3):
{% for char in characters.items %}
{% for c in char %}
name: {{ c.name }}
{% endfor %}
{% endfor %}
In Python 2 it would be .iteritems
{% for char in characters.iteritems %}
{% for c in char %}
name: {{ c.name }}
{% endfor %}
Thanks to kfarnell's help I finally managed to get this:
{% for character, params in characters.items %}
{{ params.name }}: {{ params.stars }}
{% endfor %}

django sort dict after query

have a table with websites and a many to one table with descriptions
trying to get a list, firstly getting the latest descriptions and then displaying them ordered by the content of the descriptions...
have the following in views.py
def category(request, category_name_slug):
"""Category Page"""
context_dict = {}
try:
category = Category.objects.get(slug=category_name_slug)
subcategory = SubCategory.objects.filter(category=category)
websites = Website.objects.filter(sub_categories=subcategory, online=True, banned=False)
sites = websites
descriptions = WebsiteDescription.objects.prefetch_related("about")
descriptions = descriptions.filter(about__in=sites)
descriptions = descriptions.order_by('about', '-updated')
descs = []
last_site = "" # The latest site selected
# Select the first (the latest) from each site group
for desc in descriptions:
if last_site != desc.about.id:
last_site = desc.about.id
desc.url = desc.about.url
desc.hs_id = desc.about.id
desc.banned = desc.about.banned
desc.referral = desc.about.referral
descs.append(desc)
context_dict['descs'] = descs
context_dict['websites'] = websites
context_dict['subcategory'] = subcategory
context_dict['category'] = category
except SubCategory.DoesNotExist:
pass
return render(request, 'category.html', context_dict)
this gives me a list with sites and their latest descriptions, so i have the following in category.html
{% if category %}
<h1>{{ category.name }}</h1>
{% for subcategory in category.subcategory_set.all %}
{{ subcategory.name }} ({{ subcategory.website_set.all|length }})
{% endfor %}
{% if descs %}
{% load endless %}
{% paginate descs %}
{% for desc in descs|dictsortreversed:"description"|dictsortreversed:"officialInfo" %}
<ul id='list' class='linksteps'>
<a href="/{{ desc.about_id }}" rel="nofollow" target="_blank">
<img src="/static/screenshots/{{ desc.about_id }}.png" />
</a>
<li><h3>{{ desc.about_id }}{% if desc.title %} - {{ desc.title }} {% endif %}</h3>
{% if desc.description %}<b>Description: </b>{{ desc.description }}
<br />{% endif %} {% if desc.subject %}<b>Keywords: </b>{{ desc.subject }}
<br />{% endif %} {% if desc.type %}<b>Type: </b>{{ desc.type }}
<br />{% endif %} {% if desc.officialInfo %} {% if desc.language %}<b>Language: </b>{{ desc.language }}
<br />{% endif %} {% if desc.contactInformation %}<b>Contact info: </b>{{ desc.contactInformation }}
<br />{% endif %}
{% else %}
{% endif %}
</li>
</ul>
</div>
{% endfor %}
{% show_pages %}
{% else %}
<strong>No websites currently in category.</strong>
{% endif %}
{% else %}
The specified subcategory {{ category_name }} does not exist!
{% endif %}
Initially i used dictsort
{% for desc in descs|dictsortreversed:"description"|dictsortreversed:"officialInfo"|dictsortreversed:"referral" %}
to give me the list in the desired order, so i was all happy ;)
Then however i decided i needed some pagination because the lists became too long.
django-endless-pagination works fine and does what its supposed too, however it splits up my list before the dictsort kicks in.
is there a way to sort before pagination happens and after i ordered_by at the initial query to have the latest descriptions selected?
much obliged
EDIT:
not getting any answers so my question might not be clear.
as far as i understand i need to sort the values in context_dict at the end in views.py replacing the dictsort as in the template
SOLVED:::
doing this did the trick for me to replace the dictsort.
descs1 = sorted(descs, key=operator.attrgetter('referral', 'officialInfo', 'description'), reverse=True)
context_dict['descs'] = descs1
SOLVED:::
doing this did the trick for me to replace the dictsort.
descs1 = sorted(descs, key=operator.attrgetter('referral', 'officialInfo', 'description'), reverse=True)
context_dict['descs'] = descs1

Django store information in one variable

I have different pages with items, each item has its own price which I would like to store in one variable and then send all of them to paypal payment form.
So question is,how can I store information about price from different pages? I tried sessions but nothing happens.
<article>
{% block content %}
<span>Kuriame mieste registruojiesi</span>
<select>
{% for item in upsell.skaidyti_miestus %}
<option value="{{item}}">{{ item }}</option>
{% endfor %}
</select>
{%if upsell.prideti_upsell_nr_2_taip%}
<button onclick="location.href='/upselliai/{{upsell.upsell_nr2_taip.id}}/pirkti/'">Taip, pridÄ—ti prie bendros sumos</button>
<!-- {#prideti kaina paimti ID} -->
{% else %}
<button onclick="location.href='/pirkejas/apmoketi'">Taip, pridÄ—ti prie bendros sumos</button>
{%endif%}
{%if upsell.prideti_upsell_nr_2_ne%}
{{ upsell.atsisakymo_tekstas }}
<!-- {#prideti kaina paimti ID} -->
{% else %}
{{ upsell.atsisakymo_tekstas }}
{%endif%}
{% endblock %}
</article>
my views.py
def pirkti_upsell(request, upsellis_id = 1):
#if 'pirkejas_id' in request.session:
session_pirkejas_id = request.session['pirkejas_id']
Upsellis.objects.get(id = upsellis_id).sum(session_pirkejas_id)
return render_to_response("upsell_template.html", {"upsell": Upsellis.objects.get(id = upsellis_id)})

How to increment a variable on a for loop in jinja template?

I would like to do something like:
variable p is from test.py which is a list ['a','b','c','d']
{% for i in p %}
{{variable++}}
{{variable}}
result output is:
1 2 3 4
You could use loop.index:
{% for i in p %}
{{ loop.index }}
{% endfor %}
Check the template designer documentation.
In more recent versions, due to scoping rules, the following would not work:
{% set count = 1 %}
{% for i in p %}
{{ count }}
{% set count = count + 1 %}
{% endfor %}
After 2.10, to solve the scope problem, you can do something like this:
{% set count = namespace(value=0) %}
{% for i in p %}
{{ count.value }}
{% set count.value = count.value + 1 %}
{% endfor %}
As Jeroen says there are scoping issues: if you set 'count' outside the loop, you can't modify it inside the loop.
You can defeat this behavior by using an object rather than a scalar for 'count':
{% set count = [1] %}
You can now manipulate count inside a forloop or even an %include%. Here's how I increment count (yes, it's kludgy but oh well):
{% if count.append(count.pop() + 1) %}{% endif %} {# increment count by 1 #}
Or...
{% set count = [] %}
{% for something-that-loops %}
{% set __ = count.append(1) %}
<div> Lorem ipsum meepzip dolor...
{{ count|length }}
</div>
{% endfor %}
(From comments by #eyettea and #PYB)
Here's my solution:
Put all the counters in a dictionary:
{% set counter = {
'counter1': 0,
'counter2': 0,
'etc': 0,
} %}
Define a macro to increment them easily:
{% macro increment(dct, key, inc=1)%}
{% if dct.update({key: dct[key] + inc}) %} {% endif %}
{% endmacro %}
Now, whenever you want to increment the 'counter1' counter, just do:
{{ increment(counter, 'counter1') }}
if anyone want to add a value inside loop then you can use this its working 100%
{% set ftotal= {'total': 0} %}
{%- for pe in payment_entry -%}
{% if ftotal.update({'total': ftotal.total + 5}) %}{% endif %}
{%- endfor -%}
{{ftotal.total}}
output = 5
Came searching for Django's way of doing this and found this post. Maybe someone else need the django solution who come here.
{% for item in item_list %}
{{ forloop.counter }} {# starting index 1 #}
{{ forloop.counter0 }} {# starting index 0 #}
{# do your stuff #}
{% endfor %}
Read more here:
https://docs.djangoproject.com/en/1.11/ref/templates/builtins/
I was struggle with this behavior too. I wanted to change div class in jinja based on counter. I was surprised that pythonic way did not work. Following code was reseting my counter on each iteration, so I had only red class.
{% if sloupec3: %}
{% set counter = 1 %}
{% for row in sloupec3: %}
{% if counter == 3 %}
{% set counter = 1 %}
{% endif %}
{% if counter == 1: %}
<div class="red"> some red div </div>
{% endif %}
{% if counter == 2: %}
<div class="gray"> some gray div </div>
{% endif %}
{% set counter = counter + 1 %}
{% endfor %}
{% endif %}
I used loop.index like this and it works:
{% if sloupec3: %}
{% for row in sloupec3: %}
{% if loop.index % 2 == 1: %}
<div class="red"> some red div </div>
{% endif %}
{% if loop.index % 2 == 0: %}
<div class="gray"> some gray div </div>
{% endif %}
{% endfor %}
{% endif %}
Just to shed more light into this problem.
Jinja2 variables behaves differently from that of conventional scripting languages, you can't modify the variable in a for loop.Hence to bypass this behaviour you can use a dictionary, since you can change the value of the dictionary.
**{% set margin={"margin_value":0} %}**
{% for lang in language %}
<ul>
<li style="margin-right: {{ margin.margin_value}}px">{{ lang }}</li>
</ul>
**{% if margin.update({"margin_value":margin.margin_value + 2}) %}
{% endif %}**
{% endfor %}
In the above code the value of the dictionary is being modified.

Categories

Resources