I have an error in django template for loop - html

I have an error in django template for loop.
My code:
<div class="form-group col-md-4 form-field">
<label>Year</label>
<select name="year" id="year" name="year">
{% for y in range(1980, (datetime.datetime.now().year + 1)) %}
<option value="{{ y }}">{{ y }}</option>
{% endfor %}
</select>
</div>
My error:
'for' statements should use the format 'for x in y': for x in y
range(1980, (datetime.datetime.now().year + 1))

You cannot use standard Python logic in templates.
Read DOCS about that topic.
The easiest way seems to create custom template tag filter:
import datetime
from django import template
register = template.Library()
#register.filter
def get_year_range(starting_year):
return range(int(starting_year), (datetime.datetime.now().year + 1))
And use it in template:
{% load custom_tags %}
...
{% for y in "1980"|get_year_range %}
<option value="{{ y }}">{{ y }}</option>
{% endfor %}
MORE ABOUT TEMPLATE TAGS

I solve my issue using following code:
import datetime
today = datetime.date.today()
year = today.year
year_dropdown = []
for y in range(year,1899,-1):
year_dropdown.append(y)
Pass key in render
return render(request, "add-ad.html",
{'year_dropdown': year_dropdown })
My html form django template code:
<div class="form-group col-md-4 form-field">
<label>Year</label>
<select name="year" id="year" name="year" class="form-control basic-select">
<option value="">Choose...</option>
{% for y in year_dropdown %}
<option value="{{ y }}">{{ y }}</option>
{% endfor %}
</select>
</div>

Related

How can I do to display all the name?

Hello I would like to create a select using Django I have a model :
class Test(models.Model):
name = models.CharField(null=True, default=None)
And I would like to create a select with option of name from the table Test.
How can I do this ?
I tried this :
<select class="form-control">
<option value=""></option>
{{ for name in Test }}
<option value="{{ name.id }}">{{ name.name }}</option>
{% endfor %}
</select>
But it does not work...
Could you help me please ?
just change {{ for name in Test }} to {{ for name in Test.all }}
I recommend you to pass the list of Test using the context.
app/view.py
def my_view(request):
context = {
tests: Test.objects.all()
}
return render(request, 'my_html_with_the_select.html', context)
app/templates/my_html_with_the_select.html
<select class="form-control">
<option value=""></option>
{% for test in tests %}
<option value="{{ test.id }}">{{ test.name }}</option>
{% endfor %}
</select>

Efficient way of adding attributes to HTML using Flask with fewer lines of code to select element?

I have a select element which I would like to populate from a database if this information already exists. For example, this is what I did for gender:
<select class="form-control" id="gender">
<option value="-5">Not Selected</option>
{% if current_user.gender == 0 %}
<option value="0" selected>Male</option>
{% else %}
<option value="0">Male</option>
{% endif %}
{% if current_user.gender == 1 %}
<option value="1" selected>Female</option>
{% else %}
<option value="1">Female</option>
{% endif %}
</select>
Now I have another select element with 6 different options (all with integer values 0, 1, 2 ... 5). Is there a way to make it more concise instead of writing 30 lines of code like this with if statement for each one?
Yes, there is for loop in jinja2 templating.
If you have for example a python list which contain all of select options:
options = ['option1', 'option2', 'option3', ...]
<select class="form-control" id="gender">
{% for option in options %}
<option value="{{ loop.index }}"
{% if current_user.gender == loop.index %}
selected
{% endif %}
>{{ option }}</option>
{% endfor %}
<option value="-5">Not Selected</option>
</select>
loop.index represent the current iteration of the loop. (1 indexed)
This is one example, but there is other when you iterating through objects which you've gotten from a database:
objects = [object1, object2, object3, ...]
<select class="form-control" id="gender">
{% for object in objects %}
<option value="{{ object.value }}"
{% if object.value == current_user.gender %}
selected
{% endif %}
>{{ object.name }}</option>
{% endfor %}
<option value="-5">Not Selected</option>
</select>

How do I retain selected option after submit?

Is there a way to retain the selected option from a drop down list that is using a for loop?
views.py:
...
queryC = request.GET.get('clientList', '')
queryT = request.GET.get('topicList', '')
topicList = Topic.objects.all().order_by('Name')
clientList = ClientDetail.objects.all().order_by('Client_name')
...
return render(request, 'app/search_es20.html', {
"responses": responses,
"query": q,
"queryR": queryR,
"noOfResults": resultsCount,
"username": username,
"topicList": topicList,
"clientList": clientList,
"queryC": queryC,
"queryT": queryT,
})
html:
Topic
<select name="topicList">
<option value="empty"></option>
{% for element in topicList %}
<option value={{element.Name}}>{{ element.Name }}</option>
{% endfor %}
</select>
Client
<select name="clientList">
<option value="empty"></option>
{% for element in clientList %}
<option value={{element.Client_name}}>{{ element.Client_name }}</option>
{% endfor %}
</select>
I have tried using IF statements but it's not doing it properly
If you have access on context (or on request) to the selected value, then you can do something like this:
<option value={{element.Client_name}} {% if element.Client_name == some_var %} selected {% endif %}>{{ element.Client_name }}</option>

show selected option when render posted form in django

I have tried to render a form with a ChoiceField like bellow :
<div class="col-25">
<label for="category">Subcategory</label>
</div>
<div class="col-75">
<select name="category" id="id_category">
{% for x in FilterbyCategory.fields.category.choices %}
<option value="{{ x.0 }}"{% if FilterbyCategory.fields.category.value == x.0 %}selected{% endif %}>
{{ x.1 }}
</option>
{% endfor %}
</select>
</div>
When I submit the form, I don't get the initial option selected.
DO I have a problem here ?
in the view function, I use the request.POST to create an instance :
filterbycategory = FilterbyCategory(request.POST)
I then print the form instance, I get this :
<tr><th><label for="id_category">Category:</label></th><td>
<select name="category" id="id_category">
<option value="">---------</option>
<option value="1" selected>BMW</option>
</select></td></tr>
but the option is not selected in the template rendered manually.
I found the solution. I had to get field value directly and to use safe like bellow :
<option value="{{ x.0 }}"{% if FilterbyCategory.category.value|safe == x.0|safe %} selected{% endif %}> {{ x.1 }} </option>
It works like a charm now.

Jinja2 templating boolean variables cleanly

The following code selects all 3 of the options (though only perhaps one is desirable).
<select id="example-getting-started" name="test" multiple="multiple">
<option value="cheese" selected="NO">Cheese</option>
<option value="tomatoes" selected>Tomatoes</option>
<option value="mozarella" selected="maybe">Mozzarella</option>
<option value="mushrooms">Mushrooms</option>
<option value="pepperoni">Pepperoni</option>
<option value="onions">Onions</option>
</select>
It's not hard to convert this to a Jinja2 template correctly, but it's verbose, and its size grows exponentially with the number of boolean tags. Is there a cleaner solution here? In the example below, pizza_dict is a python dict that associates each topping to the boolean value of whether it is on the pizza.
<select id="example-getting-started" name="test" multiple="multiple">
{% for k in pizza_dict %}
{% if pizza_dict[k] %}
<option value="{{ k }}">{{ k }}</option>
{% else %}
<option value="{{ k }}" selected>{{ k }}</option>
{% endif %}
{% endfor %}
</select>
Could you not simplify this to something like:
<select id="example-getting-started" name="test" multiple="multiple">
{% for k in pizza_dict %}
<option value="{{ k }}" {% if pizza_dict[k] %}selected{% endif %}>{{ k }}</option>
{% endfor %}
</select>