How to get Substr of values - python

Hi I have the following query in my views.py
m = Request.objects.filter(Q(type__icontains='4'), Q(wt__in =['giga','mega']))
context['all_items'] = m.values('type1').order_by('type1')
Its giving values sasoo, masoo, pisoo, kusoo etc.
How can I implement the Django Substr in this case so that my html will display values as sa, ma, pi, ku, ..

You can annotate the model
from django.db.models.functions import Substr
m = Request.objects.filter(Q(type__icontains='4'), Q(wt__in =['giga','mega']))
context['all_items'] = m.annotate(mysubstring=Substr('type1',1,2)).order_by('type1')
In template:
{% for obj in all_items %}
{# Use obj.mysubstring #}
{% endfor %}

You can use slice filter in your template:
{% for item in all_items %}
{{ item.type1|slice:":2" }}
{% endfor %}

One liner
context['all_items'] = [i[:2] for i in context['all_items']]

Related

string in list of list

I have two lists like:
DevInDB = ['Dev1','Dev2','Dev3']
and
DevInMesh = [['Dev1',0,0],['Dev2',1,1]]
I want to know if, for any DevInDB string, there is the same string in DevInMesh.
I wrote this code that works (in python)
for dev in DevInDB:
if any(dev in DevMesh for DevMesh in DevInMesh ):
print(dev)
else:
print('no')
I try to ust this code in a HTML file using jinja, but the 'any' function doesn't work. How can I do it?
You need to compute this before sending it to jinja.
Ex:
DevInDB = ['Dev1','Dev2','Dev3']
DevInMesh = [['Dev1',0,0],['Dev2',1,1]]
DevInMesh = {k for k, *_ in DevInMesh}
DevInDB = [(i, i in DevInMesh) for i in DevInDB]
print(DevInDB)
I've done it this way:
{% for DevDB in DevInDB %}
{% set ns = namespace(foo=false) %}
{% for DevMesh in DevInMesh %}
{% if DevMesh [0] == DevDB %}
{% set ns.foo = True %}
{% endif %}
{% endfor %}
and later on:
{% if ns.foo %}
{% else %}
{% endif %}
You can replace the any expression with the simple list comprehension where non-empty list will be True:
[1 for DevMesh in DevInMesh if dev in DevMesh]
Or better is to remove the computational part from template because a template is the view part that works on presentation level of the context, such that all pre-computed expressions should be stored in the context and only printed in the template.

Get element of list by variable in Django template

I have line of code in Django template:
<h4>{{ totals.date.weekday }}</h4>
Totals is the Python list, how do i get item of this list by index stored in date.weekday?
This would look in Python like this:
totals[date.weekday]
Creating another variable, which stores date.weekday doesn't work
UPD:
I found a solution:
Just added element of totals list to template context in render
For example:
# ...
return render(request, 'template.html', context={'date_total'=totals[date.weekday()]})
You can access the array directly using
{{ totals.0.date.weekday}} where the 0 is the position that you want.
Also if you want to print all the elements in total you will need a for loop such as:
{% for d in totals %}
{{ d }}
{% endfor %}
about sorting, you can use the pipe order_by but I recommend you to pass the list already ordered from the views
You have to run the "for loop" for this.
{% with counts = 0 %}
{% while counts < totals.count %}
{% if counts == date.weekday %}
<h4>total.counts</h4>
{% endif %}
{% counts += 1 %}
{% endfor %}
I did not get your question completely but i think it might help.

How to iterate through multidimensional list/dict in a template

I try to rebuild this example:
https://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/
I have a model "Product" and a model "Order". Order has a foreignkey to "product". So for 1 Product I have N Orders
In my template I have to display a lot of information so I would like to avoid to do "for order in Product.order_set.all()" in my template
In my template, if I write :
{{ object_list.1.related_items }}
everything is fine and I get what I want
but if I write:
{% for i in object_list %}
{{ object_list.i.related_items }}
{% endfor %}
I don't get a result.
Can somebody tell me how I solve this problem?
My object_list is nearly the same as in the above example:
products = Product.objects.all()
i = 0
qs = Product.objects.all()
obj_dict = dict([(obj.id, obj) for obj in qs])
objects = Order.objects.filter(producttyp__in=qs)
relation_dict = {}
for obj in objects:
relation_dict.setdefault(obj.producttyp_id, []).append(obj)
for id, related_items in relation_dict.items():
obj_dict[id].related_items = related_items
def get(self,request,*args,**kwargs):
context = {'object_list':self.obj_dict}
return render(request,self.template_name,context)
the only change i did is from
obj_dict[id]._related_items to obj_dict[id].related_items because of the not allowed underscore?!
How do I print the list in my template like:
- Product A
- Order 1
- Order 2
- Order 5
- Product B
- Order 3
- Order 6
best regards
That is logical, since here Django interprets i not as the variable, but as the an identifier, so it aims to access object_list.i, or object_list['i'], not object_list.1 for example.
You however do not need i here, you can just access the related_items of the object, like:
{% for object in object_list %}
{{ object.related_items }}
{% endfor %}
If related_items is, as the name suggests, a collection as well, we can iterate over these items as well:
{% for object in object_list %}
{% for subitem in object.related_items %}
{{ subitem }}
{% endfor %}
{% endfor %}
for a dictionary, we can access the .values, like:
{% for object in object_dict.values %}
{{ object.related_items }}
{% endfor %}
EDIT: as for the specific case of the listview. You can use .prefetch_related to fetch all the relations with one extra query:
class MyListView(ListView):
queryset = Product.objects.prefetch_related('order_set')
template = 'my_template.html'
In the template you can then render this like:
<ul>
{% for product in object_list %}
<li>{{ product }}</li>
<ul>
{% for order in product.order_set %}
<li>{{ order }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>

Decode values of a tuple in django template

if(len(f1) > 0):
for qs in profile_map:
p = Profile.objects.get(pk=qs.emp.id)
t_name = p.first_name + p.last_name
t_arr.append((q.profile.id,emp_name))
response_dictionary.update({'tarr':t_arr})
render_to_response('project/profile_table.html',context_instance=RequestContext(request,{'response_dictionary': response_dictionary}))
In Django template How to deocode all the 1.values of the tuple 2.search the tuple for a certain value in q.profile.id
{% for ele in response_dictionary.tarr%}
alert('{{ele}}');
//Get this as alert (11L, u'Employee3.')
{% endfor %}
In your case, the generator will assign the tuple to ele, so you can access the first, last name with {{ ele.0 }} {{ ele.1 }}.
But this is also legal, to unpack the tuple into two vars:
{% for first_name, last_name in response_dictionary.tarr %}
if you are using django 0.96 you can't have multiple values in for loop. so this will not work:
{% for first_name, last_name in response_dictionary.tarr %}
instead use
{% for ele in response_dictionary.tarr %}
{{ ele.0 }} {{ ele.1 }}
{% endfor %}

Django - How to do tuple unpacking in a template 'for' loop

In my views.py, I'm building a list of two-tuples, where the second item in the tuple is another list, like this:
[ Product_Type_1, [ product_1, product_2 ],
Product_Type_2, [ product_3, product_4 ]]
In plain old Python, I could iteration the list like this:
for product_type, products in list:
print product_type
for product in products:
print product
I can't seem to do the same thing in my Django template:
{% for product_type, products in product_list %}
print product_type
{% for product in products %}
print product
{% endfor %}
{% endfor %}
I get this error from Django:
Caught an exception while rendering: zip argument #2 must support iteration
Of course, there is some HTML markup in the template, not print statements. Is tuple unpacking not supported in the Django template language? Or am I going about this the wrong way? All I am trying to do is display a simple hierarchy of objects - there are several product types, each with several products (in models.py, Product has a foreign key to Product_type, a simple one-to-many relationship).
Obviously, I am quite new to Django, so any input would be appreciated.
Another way is as follows.
If one has a list of tuples say:
mylst = [(a, b, c), (x, y, z), (l, m, n)]
then one can unpack this list in the template file in the following manner.
In my case I had a list of tuples which contained the URL, title, and summary of a document.
{% for item in mylst %}
{{ item.0 }} {{ item.1}} {{ item.2 }}
{% endfor %}
it would be best if you construct your data like {note the '(' and ')' can be exchanged for '[' and ']' repectively, one being for tuples, one for lists}
[ (Product_Type_1, ( product_1, product_2 )),
(Product_Type_2, ( product_3, product_4 )) ]
and have the template do this:
{% for product_type, products in product_type_list %}
{{ product_type }}
{% for product in products %}
{{ product }}
{% endfor %}
{% endfor %}
the way tuples/lists are unpacked in for loops is based on the item returned by the list iterator.
each iteration only one item was returned. the first time around the loop, Product_Type_1, the second your list of products...
You must used this way:
{% for product_type, products in product_list.items %}
{{ product_type }}
{% for product in products %}
{{ product }}
{% endfor %}
{% endfor %}
Don't forget the variable items in the dictionary data
If you have a fixed number in your tuples, you could just use indexing. I needed to mix a dictionary and the values were tuples, so I did this:
In the view:
my_dict = {'parrot': ('dead', 'stone'), 'lumberjack': ('sleep_all_night', 'work_all_day')}
In the template:
<select>
{% for key, tuple in my_dict.items %}
<option value="{{ key }}" important-attr="{{ tuple.0 }}">{{ tuple.1 }}</option>
{% endfor %}
</select>
Just send the template a list of product types and do something like:
{% for product_type in product_type_list %}
{{ product_type }}
{% for product in product_type.products.all %}
{{ product }}
{% endfor %}
{% endfor %}
It's been a little while so I can't remember exactly what the syntax is, let me know if that works. Check the documentation.

Categories