Django template vars and list indices - django

I have a strange problem.
I use paginator to display some data in each page, however, I do not see any possibility to add other attributes I need to the model, so I have created another list of dicts with additional data.
In template:
{% for x in p.object_list %}
{% with c=forloop.counter0 %}
{{ info.c }} <!-- prints nothing, while {{ info }} prints all the list of dicts and {{ c }} prints 0, for example. {{ info.0 }} prints everything as intended too. -->
{% endwith %}
{% endfor %}

{{ info.c }} accesses info['c'], info.c, etc. You want the slice filter instead.

Related

Accessing multiple dictionaries in list using for loop in Django Templates

I have been working on a project and it requires me to access dictionaries that are in a list. I am using Django 2.0. This is my code here.
{% if dictdata %}
{% for x in range %}
{{ "in loop" }}
{{ dictdata.x.name }}
{% endfor %}
{{ dictdata.0.name }}
{{ dictdata.1.name }}
{% endif %}
The two statement after the for loop are working fine. But the one in the loop is not returning anything but printing the message 'in loop'. dictdatais a list containing dictionaries.
It is not clear what the value of your range varable is. So assuming dictdata is close to the following:
dictdata = [
{'name': 'Bob'},
{'name': 'John'}
]
You can loop over them in your template as follows:
{% for d in dictdata %}
{{ d.name }}
{% endfor %}
Documentation about looping in a template can be found here.

Checking for widget attribute in Django templates

I'd need to pass some data from my manually generated form to the template, and would need to check the presence of that information there.
I'm generating my form as such (in the __init__ part):
for i in days_in_month:
self.fields["info_%s" % i] = forms.ChoiceField(label="%s" % i.strftime("%a %d-%m-%Y"),
required=False,
choices=Information._meta.get_field('info').choices,
widget=forms.Select(attrs={'something': 'test'}))
What I would like to do, is to check in the template whether the attribute something is set, and if so, display its value (in the example above: test).
Any idea?
I tried with {{ field.attribute }} as per Access form field attributes in templated Django and the below:
{% for field in form %}
{{ field.label_tag }} {{ field }}
{{ field.widget.attrs.something }}
{% endfor %}
... but that doesn't work (invalid).
Ultimately I want to do something similar to:
{% if field.widget.attrs.something %}{{ field.widget.attrs.something }}{% endif %}
That would be
{{ field.field.widget.attrs.something }}

Django DRY List iteration

As someone who is just starting to use Django in my scarce time, I appreciate in advance your time in helping me learn how to make my code cleaner and correct.
I have two lists comprised of two querysets as follows:
company_list = [Company_stats.objects.filter(period__exact=P, company_name__in=master_names)]
industry_list = [Industry_stats.objects.filter(period__exact=P, industry_name__in=master_names)]
I iterate through both lists in my template to create a small table.
{%for c in company_list%}
{%for z in c %}
{{ z.company_name }}
{{ z.nxt_m_ret_est }}
{{ z.nxt_m_ret_rat }}
{% endfor %}
{% endfor %}
{%for c in industry_list%}
{%for z in c %}
{{ z.industry_name }}
{{ z.nxt_m_ret_est }}
{{ z.nxt_m_ret_rat }}
{% endfor %}
{% endfor %}
This works fine, however, since I am using the same code except for z.industry_name vs. z.company_name I was wondering whether you could help me figure out a better way to do this.
I have tried combining the lists into one list with both querysets in it and that works except for the obvious issue that I don't know how to tell it to retrieve z.company_name or z.industry_name depending on the queryset where the data is coming from, because everything became part of the same list.
Once you've changed the field to name on both models you can put both querysets into the same list and then iterate over that.
master_list = [model.objects.filter(period__exact=P, name__in=master_names) for model in (Company_stats, Industry_stats)]
...
{% for l in master_list %}
{% for i in l %}
{{ i.name }}
{{ i.nxt_m_ret_est }}
{{ i.nxt_m_ret_rat }}
{% endfor %}
{% endfor %}
If you want to have the code be more generic, it would help to make your names more generic. Would it be possible for you to change industry_name and company_name to just name throughout your system?

Django: How to get selected text of DropDown in Template?

In the template I get the whole DropDown correctly shown with something like this:
{{form.deal_type}}
But what if I wanted just the text of the selected dropdown shown?
This shows me just a foreignkey.
{{form.deal_type.value}}
I don't know why you want to do this exactly, but try this.
TO LOOP:
{% for value, text in form.deal_type.field.choices %}
{{ value }}: {{ text }}
{% if value == form.deal_type.value %}
<strong>{{ text }}</strong> <!-- THIS IS THE SELECTED ONE... -->
{% endif %}
{% endfor %}
EDIT:
I meant the above code as an illustration, not that you should use it verbatim. This code will do more like what you want.
{{ form.deal_type.label_tag }}
{% for value, text in form.deal_type.field.choices %}
{% if value == form.deal_type.value %}
{{ text }}
<input type="hidden" name="deal_type" value="{{ value }}" />
{% endif %}
{% endfor %}
I had a similar issue. To solve it I just passed the value to the template directly from the view. So in your view you presumably have something in the way of
data = {'form' :form,}
return render_to_response('destination.html', data, context_instance = RequestContext)
In data you are passing the form that includes deal_type. Add to
data a variable deal_type set equal to Object.deal_type.display_value with
data = {'form' :form,}
if Object.deal_type: data['deal_type'] = Object.deal_type.display_value
return render_to_response('destination.html', data, context_instance = RequestContext)
Then on your template you can just use
{% if condition_to_show_just_text %}
{{deal_type}} {{form.deal_type.as_hidden}}
{% else %}
{{form.deal_type}}
{% endif %}
It may be insiginificant in this case, but it seemed to me that if the list was long, iterating with the for loop on the template would be less efficient than pulling directly from the object

django templates question

How can I get the value of form.field in template. I mean not the html input element of the field but the value inside the input?
To get the bound data (in 1.2.3)
{{ form.field.data }}
In the development version, it's {{ form.field.value }} which automatically pulls initial data OR bound data whereas it's an explicit call in the current release:
form.field.field.initial or form.field.data
Update: the admin forms work differently. First of all, the BoundField is {{ adminfield.field }} and not {{ adminfield }} in your comment, but we have bigger problems.
On the change form, the form is not bound so data can only be pulled from the initial dictionary passed into the form constructor. It's not accessible via the django template syntax.
Here's the relevant lines in BoundField:
if not self.form.is_bound:
data = self.form.initial.get(self.name, self.field.initial)
# you can't do this kind of lookup from the template.
The only way to access this type of info from the template without making a template tag (which you should!) is to loop through each key/value in the initial dictionary and comparing to the current fields name.
{% for line in fieldset %}
{% for adminfield in line %}
{% for k, v in adminfield.field.form.initial.items %}
{% if k == adminfield.field.name %}
{{ k }}:{{ v }}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}