How to iterate a dynamic variable in a Django template - python

Some slightly related questions have been asked about this, but the answers did not really help me. When I tried to implement a potential good hint suggested elsewhere (custom templates), I did not get the desired results.
In my template, I am iterating over a set of keys from a dictionary. The dictionary itself originates from submitting a Django formset.
XML Template snippet: (I am rendering to an XML file)
{% for x in range %}
<file type="{{ form-'x'-type }}" viewpath="{{ form-'x'-file }}"/>
{% endfor %}
The above obviously does not work. The iteration works. The rangevariable is a python argument corresponding to range(int(request.POST['form-TOTAL_FORM'])) passed from the view to the XML template.
At every iteration in the template, I need {{ form-0-type }}, {{ form-1-type}}, {{ form-2-type }}, etc.
How do I do that? If I really need to use a custom filter for this, how do I do this?
I hope this question (and the answers) will help many having the same problem.
Thanks.
Edit:(Dictionary posted)
<QueryDict:
{
u'form-MAX_NUM_FORMS': [u'1000'],
u'form-INITIAL_FORMS': [u'0'],
u'form-TOTAL_FORMS': [u'2'],
u'form-0-type': [u'1'],
u'form-1-type': [u'2'],
u'csrfmiddlewaretoken': [u'LpkjdDcqRCL4VPM0SAuU7efgZjgeubTN']
}>
Additional note:
In a second view, I lookup the values for the foreign keys and put the values in another dictionary, which I send to my XML template.
Snippet of the code that does this:
detailed_request = {}
for x in range(0, int(request.POST['form-TOTAL_FORMS'])):
detailed_request['form-'+str(x)+'-type'] = Upload_Type.objects.get(pk=request.POST['form-'+ str(x)+'-type'])
detailed_request['form-'+str(x)+'-file'] = request.FILES['form-'+str(x)+'-file']
The above is a working snippet. When I trace detailed_request, I have all the information I need:
{
'form-1-type': <Upload_Type: malib>,
'form-0-type': <Upload_Type: axf_file>
}

Just in case somebody has the same problem, I actually changed the way I do things.
I do not iterate the formset in the template. Instead, I implemented the solution from Paolo Bergantino here:
Dynamically adding a form to a Django formset with Ajax
Then in my views, I simply get every data I need from request.FILES
I hope that helps anybody who started with the same wrong approach.

You can access the for loop helper variables through the following variables
forloop.counter The current iteration of the loop (1-indexed)
forloop.counter0 The current iteration of the loop (0-indexed)
More at: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#for
So you'd do...
{{ form }}-{{ forloop.counter }}-{{ type }}

Related

How to render Kwargs in For Loop with Flask/Jinja

I'm trying to print a simple list of strings that I gathered from a sqlite database. I tested the query result and the list is just fine, but to print it with python (inside a for loop) I would need to do print(*element) as printing kwargs.
The problem comes when trying to print it inside a for loop in the Flask template with jinja2. This would print something like <sqlite3.Row at 0x7fe42f0a5710> for every element, and I can't seem to find anywhere which is the right way to do it.
This is my code:
<select>
{% for element in my_list %}
<option value="my_class">{{ element }}</option>
{% endfor %}
</select>
This is the function that sends the list_from_db to the template.
def index():
list_from_db = get_my_list_of_strings()
return render_template('index.html', my_list=list_from_db )
I'll appreciate any help on the matter.
I found a solution for this in another SO answer related with Sqlite .fetchall().
Python's sqlite3 module returns a list of tuples even when querying a single column. This can be prevented applaying the row_factory attribute to the db cursor.
Here is the link to the original answer.
Edit: Although this was really useful and it sent me to the right path, I ended up using the attribute make_dicts.

Django search - populate template with search results

I'm completely newbie in Django-phython.
I'm trying to populate the results of a search inside an html form input tag. with the register that the search returns.
I have a view that renders an html code, passing a dictionary. And I would like to display that dictionary, containing the search results, inside the html form fields that corresponds to that dictionary.
The question is if it's possible to do such a thing.
You will get all the information at django template documentation
Specifically, if you want to iterate through the dictionary in your template, you need the for loop.
From the documentation:
This can also be useful if you need to access the items in a
dictionary. For example, if your context contained a dictionary data,
the following would display the keys and values of the dictionary:
{% for key, value in data.items %}
{{ key }}: {{ value }}
{% endfor %}
You'll have to use ajax and a typehead pulgin for that.

Django templating - accessing dictionary value using a template variable

This is the data coming from my views.py:
gradebook_data = {
'G5A': [...],
'G5B': [...],
...
}
sections = [
('G5A': '5-Einstein'),
('G5B': '5-Bohr'),
...
]
In my template, I want to iterate the sections and display gradebook data inside a for loop like this...
{% for code, section in sections %}
<td>{{ gradebook_data.code }}</td>
{% endfor %}
This doesn't work since in Django it tries to do a dictionary lookup for gradebook_data['code'] when what I want to do is to get gradebook_data['G5A'].
Does anybody know a workaround or can point to my mistake? I have spent a whole day just for this already.
This was quite easy to do with PHP's Twig templating library.
If you're using the Django templating system you can register a custom filter, which has been documented several times on SO for exactly this purpose. For example, here.

two or more dots in a django template after the variable

In a django template, is it possible to have two (or more) dots after a variable? For example, say I have a list of objects that I first want to use a list-index lookup for and then once I have the object, I want to call its method for getting the absolute url, should that work?
For example:
{% for entry in myList %}
{{ entry.0.get_absolute_url }}
{% endfor %}
So the 0 is asking for the first item in the list which is an object, then I want to get the absolute url. It doesn't work when I try it but it doesn't return an error either. Is there a better way to accomplish what I'm trying to do?
To clarify it, what's strange is that:
This works:
{{ singleObject.get_absolute_url }}
In that case if I just try {{ singleObject }}, I get the unicode value of that object so something like: John Smith
This doesn't work:
{% for object in objectList %}
{{ object.get_absolute_url }}
{% endfor %}
But in this case, if I put in {{ object }}, I no longer get the unicode value. I get: [<Name: John Smith>] (name being the name of the model)
Basically, the method works when it's outside of a loop. Could there be any reason for that?
more than one dot absolutely works.
based on your comment, there is no entry.0 because entry IS the first item in the list cause you are already looping through `myList'
just use entry.get_absolute_url instead
but if you only want to print out the url for the first entry, forgo the for loop and just use myList.0.get_absolute_url
UPDATE:
there's a tip from 'the pragmatic programmer' that says:
``select’’ Isn’t Broken
It is rare to find a bug in the OS or the
compiler, or even a third-party product or library. The bug is most
likely in the application.
i think you assumed that django templates were behaving weird, when the truth is you were not building your list correctly. don't be afraid to show some of your actual code, by abstracting the problem for us, you removed the part that included the problem
I got it. I had brackets around each item in my list like so:
objectList = [['John Smith'], ['Jim Jones'], ['Bill White']]
Silly me! Thanks so much for your all your input
What you are doing is perfectly acceptable in Django templates. There is no better way to accomplish what you're trying to do.

form index in inlineformset

I have a formset created using inlineformset_factory. It doesn't matter what it looks like to answer this question. In the template I am looping through it with for form in forms.formset:
I want to be able to display the form index of the form in my template. By form index, I mean the number associated with that form in all of the formfields. Is there a variable that does this? I tried form.index and form.form_id and form.id is a field.
No, objects in a collection don't generally have access to their index or key.
However if you're outputting the formset in a template, you're presumably looping through the forms. So you can use {% forloop.counter %} to get the index of the iteration.
Although it is not pretty, based on the formset source and the comment by #yuji-tomita-tomita above, you could do something like this in your template:
{{ form.prefix|cut:formset.prefix|cut:'-' }}
This just takes the form prefix string, which includes the form index, then removes the irrelevant parts. In the view you could simply do e.g. form.prefix.split('-')[1].

Categories