Django templates - get list of multiple GET param - django

I have a url with multiple GET params (of the same name) - mycompany.com/?a=1&a=2
When i do in django template:
{{ request.GET }}
I get:
<QueryDict: {'a': ['1', '2']}>
When i do in django template:
{{ request.GET.a }}
I get:
2
When i try to loop:
{% for a in request.GET.a %}
{{ a }}
{% endfor %}
I get:
2
How to make behave multiple GET params as list in django templates? Thx!

Template filter:
from django import template
register = template.Library()
#register.filter
def get_list(dictionary, key):
return dictionary.getlist(key)
Templates:
{% for a in request.GET|get_list:'a' %}
{{ a }}
{% endfor %}

Template filter:
[app/templatetags/exampletag.py]
from django import template
register = template.Library()
#register.filter
def get_item(dictionary, key):
return dict(dictionary).get(key)
Templates:
{% load exampletag %}
{{ request.GET|get_item:'a' }}
How to: Custom template tags and filters

A bit wonky, but does the job:
{%for list_of_elements in request.GET.lists%}
{%for element in list_of_elements.1%}
{{ element }}
{%endfor%}
{%endfor%}
Or if you only want a specific list from the query:
{%for list_of_elements in request.GET.lists %}
{%if list_of_elements.0 == "a"%}
{%for element in list_of_elements.1%}
{{ element }}
{%endfor%}
{%endif%}
{%endfor%}

{% for name, values in request.GET.lists %}
{% if name == 'a' %}{{ values|join:", " }}{% endif %}
{% endfor %}
or
{% for name, values in request.GET.lists %}
{% if name == 'a' %}
{% for value in values %}{{ value }}{% endfor %}
{% endif %}
{% endfor %}

Related

Any efficient way to avoiding two forloops in django

Any better or efficient way to this in django
{% for list1item in list1 %}
{% for list2item in list2 %}
{% if forloop.counter == forloop.parentloop.counter %}
{{ list1item }} {{ list2item }}
{% endif %}
{% endfor %}
{% endfor %}
I want to do something like this, but not working.
{% for list1item in list1 %}
{% with forloop.counter as i %}
{{ list2.i }}
{% endwith %}
{% endfor %}
Updated! Actually here is the story!
this is my forms.py
from django import forms
from .models import MedicalRecords
class UpdateMedicalRecordForm(forms.ModelForm):
class Meta:
model = MedicalRecords
fields = ("title", "file", "doctor")
widgets = {
"title": forms.Textarea(attrs={"rows": "", "class": "form-control"}),
}
I want a list of each medicalrecord form with It's instance so I'm using [UpdateMedicalRecordForm(instance=x) for x in medicalrecords] to create form for each medicalrecord.
my view.py is as
...
medicalrecords = get_list_or_404(MedicalRecords,somefilterings..)
forms = [UpdateMedicalRecordForm(instance=x) for x in medicalrecords]
...
then in template to access each form of medical record I'm using
<form method="POST" enctype="" class="">
<div class="modal-body">
<div class="form-group">
{% csrf_token %}
{% for form in forms reversed %}
{% if forloop.counter == forloop.parentloop.counter %}
{{ form.as_p }}
{% endif %}
{% endfor %}
</div>
<div class="submit-section text-center">
<button type="submit" class="btn btn-primary submit-btn">Submit</button>
<button type="button" class="btn btn-secondary submit-btn" data-dismiss="modal">Cancel</button>
</div>
</div>
</form>
Actually you can create a custom template tag in order to make your solution working :
# templatetags/custom_tags.py
from django import template
register = template.Library()
#register.filter
def get_index(obj, index):
"""
Try to get value from a list object with an index given in parameter.
Return an empty string if index doesn't exist
"""
try:
return obj[index]
except IndexError:
return ""
Then in your template you can do :
{% load custom_tags %}
{% for list1item in list1 %}
{{ list2|get_index:forloop.counter }}
{% endfor %}
But after reading your update, I believe you can find something cleaner for your use case.

How to use {{ variable }} in {% if is_exist %} in Django template?

Like I asked in the title, I wanna do something like the below in Django.
{% for i in "xxxxx" %}
{% if store{{ forloop.counter }} %}
...
{% endif %}
{% endfor %}
I pass variables named 'store1', 'store2', and 'store3' from views.py
However, an error happens saying
"Could not parse the remainder: '{{' from 'store{{'"
, which seems like {{ }} can't be used inside {% %}
Does anyone know how to do this?
You can't do this in the Django template language.
A better approach would be to pass the stores to the template as a list,
def my_view(request):
stores = ['store1', 'store2', ...]
return render(request, 'mytemplate.html', {'stores': stores}
then loop through the list in the template:
{% for store in stores %}
{{ store }}
{% endfor %}

Django inclusion_tag contents not displaying

I cannot get the contents of an inclusion_tag to display. I am not getting an errors so i know that the tag is registering and I am almost certain that it is loading correctly. The tag is created in crudapp/templatetags/crudapp_tags.py
from django import template
register = template.Library()
#register.inclusion_tag("forum.html")
def results(poll):
form = 'blah'
return {'form': form}
templates/forum.html
{% extends 'index.html' %}
{% load crudapp_tags %}
{% results poll %}
<p>aaa</p>
{% block homepage %}
<p>bbb</p> <!-- Only this displays -->
{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}
<div>
<p>{% if user.is_authenticated %}Add a New Topic: <span class="glyphicon glyphicon-plus"></span>{% endif %}</p>
</div>
<div>
<p>{{ totalposts.count }} posts, {{ totaltopics.count }} topics, {{ totalusers.count }} users, {{ totalviews.numviews}} views</p>
</div>
{% endblock %}
The file set up is as follows,
If you are using an inclusion tag, then the tag renders another template. You need to move the code that uses form out of forum.html and into a new template, e.g. results.html
results.html
{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}
Then change your tag to use this template
#register.inclusion_tag("results.html")
def results(poll):
form = 'blah'
return {'form': form}
Finally, since you are extending a template, you need to move then tag into a block, otherwise the result won't be used.
{% block homepage %}
{% results poll %}
...
{% endblock %}
If you want to add an item to the template context instead of rendering another template, then you want a simple tag instead.
#register.simple_tag
def fetch_result():
result = ['foo', 'bar']
return result
Then in your template:
{% fetch_result as result %}
{% for item in result %}
<p>This is {{ item }}</p>
{% endfor %}
The {% fetch_result as result %} works for simple tags in Django 1.9+. In earlier versions, you want an assignment tag.

django templates: How to know form field type and add any buttons based on field type

I am displaying my django forms dynamically with below code.
{% for field in form %}
{% if field.field.required %}
<span class="red">*</span>
{% endif %}
{{ field.label }}:
{{ field }}
{% endfor %}
Now I want to know the datatype of fields.if field type is Datetimeinput then I want give one button beside to it to get JavaScript calender.
i want do like as below but I am not able get it
{% for field in form %}
{% if field.field.required %}
<span class="red">*</span>
{% endif %}
{% if field.field_type == 'Datetimeinput' %}
{{ field.label }}:
{{ field }}
<label>From :</label><input type="text" name="from1" class="txtbox"><input type="button" value="Cal" onclick="displayCalendar(document.forms[0].from1,'yyyy-mm-dd',this)">
{% else %}
{{ field.label }}:
{{ field }}
{% endif %}
{% endfor %}
Help me out thanks in advance.
Make a template tag. Depending on Get type of Django form widget from within template. I used this solution once or twice.
from django import template
register = template.Library()
#register.filter('klass')
def klass(ob):
return ob.__class__.__name__
In template:
{{ field.field.widget|klass }}
Will return field class name to be used in your if statements.
You could write a custom template filter for that.
#register.filter
def fieldtype(obj):
return obj.__class__.__name__
Docs on custom filters: link
However, why not just render fields without looping over them?
{{ form.birthdate }}
Then you'll know for sure what is what.

Why doesn't django like my dictionary?

I'm new to django, and desperately trying to figure out why I can't get a set of dictionary objects to render. Here is a snippet of the template--with some pprints for debugging:
<ul>
{% with req.requirement_id as reqid %}
req.requirement_id: {{ req.requirement_id|pprint }}<br />
reqid: {{ reqid|pprint }}<br />
e_quals: {{ e_quals|pprint }}<br />
e_quals.reqid: {{ e_quals.reqid|pprint }}<br />
{% for qual in e_quals.reqid %}
qual.qual_type: {{ qual.qual_type }}
{% if qual.qual_type == "self" %}
<li>Only self-endorsements.</li>
{% endif %}
{% if qual.qual_type == "other" %}
<li>No self-endoresements.</li>
{% endif %}
{% if qual.qual_type == "hasa" %}
<li>Endorser must hold an active {{ qual.qual_data }} badge.</li>
{% endif %}
{% endfor %}
{% endwith %}
</ul>
And here is what I get as an output:
req.requirement_id: u'man_keephead'
reqid: u'man_keephead'
e_quals: {u'man_keephead': [<EndorsementQual: man_keephead_others>, <EndorsementQual: man_keephead_man>], u'man_trustself': [<EndorsementQual: man_trustself_self>], u'man_waiting': [<EndorsementQual: man_waiting_other>]}
e_quals.reqid: ''
I really seems like--given that reqid and that e_quals dictionary, e_quals.reqid should produce that list of objects. I'm not sure what I'm missing.
You can't do this sort of indirect variable resolution in Django's template language. It will always interpret e_quals.req_id as e_quals["req_id"] - ie as a literal key.
You'll need to create a simple template filter:
#register.filter
def dict_get(my_dict, key):
return my_dict.get(key)
{{ e_quals|dict_get:req_id }}