TemplateSyntaxError: Could not parse the remainder - python

I'm receiving this error each time I try to access a list within a Django template. I have checked the answers to similar questions, but the problem is usually a lack of % or some other character somewhere. As long as I can see, this is not the case:
Here I'm passing a dict containing a a list of item id as keys and list of URLs to images as a value for each id. I know I should integrate this into the item model, but since I'm still at development with SQLite3 I cannot store lists easily. And anyway I am intrigued by this problem. So:
<a href="{% url 'details_view' item_id=item.id %}"><img class="hover-image" src="{{ img_gallery[item.id][0] }}" alt="">
Exception Value:
Could not parse the remainder: '['item.id'][0]' from 'img_gallery['item.id'][0]'
Also, yesterday I tried using bootstrap4 flex-grid to easily achieve 5 columns. Since I'm using pagination to retrieve 20 items, my idea was slicing the list of items (model) for each row, like:
{% for item in items[0:5] %}
And I also received the same error, even when this was the recommended aproach in related answers aboput slicing data passed with a view.
In both cases I cannot find the problem, and I think both are somehow related.
I'm using latest Django 1.11.6 with Python 3.5.2.

You seem to be confused between Jinja2 syntax and the Django template syntax. Jinja2 is a separate project, inspired by Django, but not used by Django itself.
In the Django template syntax, variables in {{...}} always use dot notation, [...] subscriptions are not supported. Out of the box, the language does not support dictionary key lookups.
You can write a custom filter to achieve this, like the following, written by culebrón:
from django.template.defaulttags import register
#register.filter
def get_item(dictionary, key):
return dictionary.get(key)
then in the template:
{{ img_gallery|get_item:item.id|first }}
Alternatively, you could switch to using Jinja2 in your Django project, replacing the built-in template language: How to use jinja2 as a templating engine in Django 1.8

Related

"abc" is not a registered tag library. must be one of: "efg" | django

I was actually trying to find a way to sort a queryset in my template and saw that we can create our custom filter and use it.
let's not to mention the function I put into my tag but I created the tag in the same directory as all other tags...
I created my tag name sort_tags.py under templatetags
*weird I cannot upload image, was going to show my directories`
Anyways, that's where all other tags are.
I got this piece of code and want to try it..so I paste it into my sort_tags.py
from django import template
register = template.Library()
#register.filter
def sort_by(queryset, order):
return queryset.order_by(order)
then in my template.html I used {% load sort_tags %} also, there are other tags being loaded too.
Then when I load the page...is not a registered tag library. must be one of shows up. in the list of MUST BE, I see all the tags in the same directory as me.
I tried something like filter_function, register_filter('sort_by',sort_by)
or something similar, found a few different ways, so I tried them all and none of them work.
Does anyone has any idea what might be wrong?
Thanks in advance
If you want to do this inside a template (which is a bit wrong actually), you should be using the regroup tag — https://docs.djangoproject.com/en/1.10/ref/templates/builtins/#regroup
But actually, you should move the logic to the view as much as possible.

Django-Tables column templates with django permissions

So, I'm using Django-Tables to generate my project datatables, but now I'm facing a new problem.
I've got this Table Class to generate my Model datatables, using the DjangoTables app. Then I use the TemplateColumn to create a new column for base operations just like Edit, Copy, Delete... This stuff goes into the template that is loaded into the column of each row.
class ReservationTable(tables.Table):
operations = tables.TemplateColumn(template_name='base_table_operations_btn.html', verbose_name= _('Operations'))
So inside the template i've got this:
{% if perms.reservation.add_reservation %}
<span class="glyphicon glyphicon-paperclip"></span>
{% endif %}
So, using the django templates perms tags, is not working here but it does in to the normal django template.
Any tips on how can I handle those perms into this kind of template? I'm kinda losen.
Thanks in advance!
So, its not just like a "perfect answer" for this problem, but here is how I managed to solve this:
Instead of using in Template django permisions, I managed to setup the permissions in the route url config. Just by adding:
permission_required('permision_name',raise_exception=True)
Function in the url.py. So here comes the full url line:
url(r'^reservation/flight/add/$', permission_required('reservation.add_reservation',raise_exception=True)(FlightReservationCreate.as_view()), name='reservation-flight-create'),
This allow me to add perms to the View instead of filtering into the themplate view.
That's not a perfect solution, because its a different way to manage permissions, and the problem with the django-tables2 column template is still there.
By the way, the final result is the same for me, so its OK.

Iterate over XML in Django Temnplate

I have a block of XML that is returned from an API call.
It contains lots of results - person elements like below.
<root><person><name>mark</name><age>18</age></person><person><name>alan</name><age>10</age></person></root>
I want to pass this data structure (or some iterable version if it) to a django template to iterate over.
In my template I want to say
{% for r in results %}
{{ r.name }}
{{ r.age }}
{% endfor %}
I thought this would have been straight forward but its posing problems.
Django templates cannot handle it out-of-the-box. And it doesn't actually sound correct - to pass an XML structure into HTML template to process.
Making custom template tags or filters that would help to iterate over the XML structure could be a possible solution, but in this case you may find yourself overcomplicating things, template layer was made for presentation, don't put too much logic into it:
We see a template system as a tool that controls presentation and
presentation-related logic – and that’s it. The template system
shouldn’t support functionality that goes beyond this basic goal.
Parse the XML in the view, make a list of dictionaries and pass it to the template inside the context.
For example, use xmltodict tool:
persons = xmltodict.parse(data)['root']['person']
where data is your XML structure.

Is there any way to restrict the use of tags and filters in Django templates?

I know Django has already a good templating system for designers but I wonder if it is possible to limit the usage of certain template tags and filters.
We are building a Django plugin for designers to make template developing more open, but we want to hide some logic of django template system and expose just the necessary to the designer.
In example: How can I prevent the use of {% load %} template tag and preload only the tags that I want?
Try this decorator: Safe template decorator
From author description:
A decorator that restricts the tags and filters available to template
loading and parsing within a function.
This is mainly meant to be used when granting users the power of the
DTL. You obviously don't want users to be able to do things that could
be potentially malicious.
The {% ssi %} tag, for example, could be used to display sensitive
data if improperly configured.
{% load %} gives them access to all the unlimited python code you
wrote in your templatetags. {% load sudo %}{% sudo rm -rf / %} o_0
Note that the "load" tag (among others) is not listed in the default
tag whitelist. If you parse a template (however indirectly) in a
function decorated with this, unlisted builtin tags will behave like
undefined tags (ie, they will result in a TemplateSyntaxError).
Since {% load %} is not whitelisted, you may want to include some
custom tags or filters as "builtins" for convenience. Simply put the
module paths to the libraries to include in the extra kwarg or the
extra_libraries list. Generally, this is not recommended, as these
libraries need to be carefully and defensively programmed.
NOTE: This does not do anything about cleaning your rendering context!
That's completely up to you! This merely restricts what tags and
filters are allowed in the templates.
Examples:
from django.template.loader import get_template
safe_get_template = use_safe_templates(get_template)
tmpl = safe_get_template('myapp/some_template.html')
from django.template import Template
use_safe_templates(Template)('{% load sudo %}')
# TemplateSyntaxError: Invalid block tag 'load'
An easy way would be to implement your own template loader similar to Django's file system loader and strip certain tags out of the text (guess you could event turn into a template/template nodes when doing so to be able to parse it correctly) before giving the template to Django for further processing.

Reversing complex Admin URLs from templates

I find myself needing a bit more flexibility than what I understand I can do based on the Django documentation for reversing Admin URLs. I'm doing things like:
{% url admin:billing_creditcardtoken_add %}?customer={{ user.id }}
This works, but it feels like I should be able to do it without leaving the template tags.
If I want to find all CreditCardToken objects from the billing application that belong to the current user, I find myself doing:
{% url admin:billing_creditcardtoken %}?customer={{ user.id }}
...but this fails altogether. Is there a more elegant way of getting these URLs?
I was looking at this the wrong way. While:
{% url admin:billing_creditcardtoken_add %}?customer={{ user.id }}
...might be somewhat ugly, the only thing added syntax would serve to do is try to construct a query string, which isn't something one reverses URLs to do normally anyway. So this is an acceptable method of accomplishing this task.
What I was looking for in the second turned out to be:
{% url admin:billing_creditcardtoken_changelist %}?customer={{ user.id }}
...changelist, as it turns out, does not show a history of changes, but creates a list of possible items to change. Adding the query string applies the proper filter I needed.

Categories

Resources