What is "load url from future" in Django - django

When I read django code sometimes, I see in some templates "load url from future". I am not quite sure what this is but I do know it has something to do with URLs. How and when is this load url from future supposed to be used?

It's due to a change to the url tag enacted in 1.3:
Changes to url and ssi
Most template tags will allow you to pass in either constants or variables as arguments – for example:
{% extends "base.html" %}
allows you to specify a base template as a constant, but if you have a context variable templ that contains the value base.html:
{% extends templ %}
is also legal.
However, due to an accident of history, the url and ssi are different. These tags use the second, quoteless syntax, but interpret the argument as a constant. This means it isn’t possible to use a context variable as the target of a url and ssi tag.
Django 1.3 marks the start of the process to correct this historical accident. Django 1.3 adds a new template library – future – that provides alternate implementations of the url and ssi template tags. This future library implement behavior that makes the handling of the first argument consistent with the handling of all other variables. So, an existing template that contains:
{% url sample %}
should be replaced with:
{% load url from future %}
{% url 'sample' %}
The tags implementing the old behavior have been deprecated, and in Django 1.5, the old behavior will be replaced with the new behavior. To ensure compatibility with future versions of Django, existing templates should be modified to use the new future libraries and syntax.

I will put this in a separate answer due to the following salient Exception in connection with templates:
If you get a django.core.urlresolvers.NoReverseMatch Exception thrown from within a django template (Django version >1.4) parser, it may just be the usage of {% load url from future %} within the template.
In this case, simply quote the url that is passed to the url-tag. That is {% url someurl %} should become {% url 'someurl' %}. Thanks to Ignacio VA for pointing me in that direction.

Related

Django template nested include passing variables

I use django template index.html to render the frontpage. It includes another template to create a link icon. This template url_icon.html includes another template icon.html. When passing the arguments down the way, I face with an error. How to fix it?
index.html
.
.
.
{% include "url_icon.html" with name="return" url="/" %}
.
.
.
url_icon.html
{% include "icon.html" with icon={{ name }} %}
icon.html
<img src="/static/images/{{ name }}.png" />
Causing an error:
Could not parse the remainder: '{{' from '{{'
it looks like there are a few things you can do to improve/fix this. Addressing #1 and #2 should fix your issue. I've also added suggestions for best practices that would probably require refactoring (#3, #4).
It looks like you need to remove the curly-braces from name inside the {% include %} tag. Context variables can be used inside tags without extra syntax.
url_icon.html:
{% include "icon.html" with icon=name %}
icon.html will have access to name since you're not using the only keyword when updating its context, so your code might appear to work at first ({% include %} documentation). However, it looks like your intention is to refer to it as icon.
Use the variable icon in instead of name
icon.html:
<img src="/static/images/{{ icon }}.png" />
Optional suggestion: Use Django's staticfiles system
Try using the {% static %} tag for your icon. This will help make deployment easier, especially if you use a separate CDN from your webserver. There's lots of literature on how to set up staticfiles for Django projects in production, it's a large topic, but you'll be able to approach it more easily if you use the {% static %} tag from the beginning.
Optional suggestion: Django's URL routing system
Your route in index.html is hard-coded to be "/". Django has a powerful URL referencing system to leverage. If you've defined the root URL / using Django too, you can refer to it by name. Docs: {% url %}, and for the back-end, reverse().

How to assign value to a variable on Django template through jQuery

I have a Django template file working with a passed value like the below.
{% include 'boutique/rating.html' with score=[I want to put value here] %}
When I usually put value into the template, I could easily do it by doing like the below.
{% for store in stores %}
{% include 'boutique/rating.html' with score=store.review_score %}
{% endfor %}
However, as I get into more complex templates, I need to assign the value to the score parameter in the include section through jQuery. Is there a way that I can acheive this through jQuery?
What you need to understand is this: The part of the template between {% and %} is interpreted by Django. It is processed entirely on the server. In other words, it never shows up in the browser, but gets replaced by some sort of standard HTML.
On the other hand, jQuery is a Javascript library and operates entirely in the browser -- it doesn't know anything about the server or Django.
So, to modify the included template with jQuery, you have to find out what HTML it renders to. You can probably do that by looking at the included template file. Then, treat that HTML the way you would any other part of the page for manipulation with jQuery.

How django's template tag "include" work with None

I'm using an include tag in my templates like this:
{% include fragment_variable %}
where fragment_variable is a context variable that might not exist. I wonder if it will blow up when fragment_variable is not in context variables or is None.
NOTE: actually I tested this code in two different environments (both using Django 1.7) and got two different results (one blew up with some stack trace for templates lookups and the other just failed silently). So I'm curious if there's a setting in django that controls how template rendering behaves when "include" tag can't find a valid template.
{% if fragment_variable %}
{% include fragment_variable %}
{% else %}
<!-- something else -->
{% endif %}
Edit:
Since you are using django version prior to 1.8, take a look at the setting TEMPLATE_STRING_IF_INVALID, it sets the default value for invalid variables.
Also take a look at How invalid variables are handled:
Generally, if a variable doesn’t exist, the template system inserts
the value of the engine’s string_if_invalid configuration option,
which is set to '' (the empty string) by default.
This behavior is slightly different for the if, for and regroup
template tags. If an invalid variable is provided to one of these
template tags, the variable will be interpreted as None. Filters are
always applied to invalid variables within these template tags.
For that matter, I still consider using if is the best exercise.

URL template tag without locale in Django 1.4

I added locale specific URL-s to my Django app with i18n_patterns and it’s all working nicely, but in some cases I need to have an url pointing to a view without the locale information.
My current setup works so that english pages don’t have a locale in the path, e.g: www.foobar.com, but all other as www.foobar.com/et/ etc. This works nicely. Now, every user has a "public profile" page in www.foobar.com/u/123 etc.
If I just do a {% url user_profile_page %} in a template, I always get the locale also in the URL, but I’d like for it always show the non-locale version, because I want the public profiles to have a non-locale URL (and the fact that if someone is using a different language and then it redirects to the locale based URL, is fine).
There’s nothing the Django documentation that suggest that the {% url %} template tag is able to do this, but is there something?
In template code you should be able to use the {% language %} tag in the following manner to specify language for url reversing:
{% language en %}
User 1
{% endlanguage %}
Specifying the english language code in this case should result in url without prefix.

New url syntax from django 1.3/dev onwards

Why did the django core developers allow the url templatetag to point directly to a django view function? (reference - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#url)
{% load url from future %}
{# 1st method: pointing to a view function #}
{% url 'app_views.client' %}
{# 2nd method: pointing to a named url #}
{% url 'myapp:view-name' %}
One can already name the url in urls.py and hence use the 2nd method to point to a specific url. It doesn't feel right to allow developers to actually reference a view function directly from the template.
Does anyone know why this decision was made?
Passing a dotted view function name to the {% url %} template tag is simply the form the template tag took in the earlier days of Django, before you could name URLs. It's still supported, though as you point out, you probably wouldn't use it in a modern application.
URLs in Django are just mappings to views. Therefore, in the template, using a named URL is just indirectly referencing the view anyway.
The exception is where a single view is mapped to by multiple URLs.
Also note that they are planning to change the syntax of the url tag in 1.5. It will take a context variable as the parameter, rather than a string. It will still take views or named URLs though.