Can you check the internet protocol from Django's template? - django

Right now, if I want to check whether the current page is accessed through http:// or https://, I will use the following Javascript in my templates and write html from document.write:
<script type="text/javascript">
var protocol = document.location.protocol;
if (protocol == "http:")
document.write("regular");
else
document.write("secured");
</script>
Is there another way to achieve the above in Django's template without using Javascript?

if you use a RequestContext, you can do the following:
<p>You used: {% if request.is_secure %}HTTPS{% else %}HTTP{% endif %}
See the relevant part of the Django documentation.

Since Django 1.10, you can use:
request.scheme
in a view, or in a template:
{{ request.scheme }}
From the docs
A string representing the scheme of the request (http or https usually).

You need to enable the appropriate request context processor in your setting.py file:
TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.request',)
The template will now have a variable named request that contains the current HttpRequest. You can use it to find the protocol:
{{ request.is_secure }}

Try using RequestContext and request.is_secure in your template.
One caveat, the process of detecting HTTPS can differ from one server setup to the next so you may have to do a little work to get request.is_secure working. You can get it working either by ensuring that your front end / reverse proxy sets 'HTTP_X_FORWARDED_HOST' or by writing a middleware class that is custom to your setup.
Use the deprecated SetRemoteAddrFromForwardedFor code as a starting point, if you go the custom middleware route.

Related

Django: How to return to previous URL

Novice here who learned to develop a web app with python using Flask. Now I'm trying to learn django 1.9 by redoing the same app with django.
Right now I am stuck at trying to get the current URL and pass it as an argument so that the user can come back once the action on the next page is completed.
In Flask, to return to a previous URL, I would use the 'next' parameter and the request.url to get the current url before changing page.
In the template you would find something like this:
Buy punchcard :
and in the view:
redirect(request.args.get("next"))
I thought it would be about the same with django, but I cannot make it work. I did find some suggestions, but they are for older django version(older than 1.5) and do not work anymore(and they are pretty convulsed as solutions goes!)
Right now, in my view I am using
return redirect(next)
Note: The use of return redirect in django seems very recent itself if I judge by solutions on the web that always seem to use return HttpResponse(..., so I take it alot of changes happened lately in how to do things.
and in the template I have
<a href="{% url 'main:buy_punchcard' member.id next={{ request.path }} %}">Buy punchcard</p>
but this actually return an error
Could not parse the remainder: '{{' from '{{'
I did add the context_processors in settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
)
But this is only the last error in a very long streak of errors. Bottom line is, I can't make it work.
As such, anyone could point me in the right direction as to what is the way to do this in django 1.9? It look like a pretty basic function so I thought it would be easier somehow.
If you want next to be included in the query string, then move it outside of the url tag:
<a href="{% url 'main:buy_punchcard' member.id %}?next={{ request.path }}">Buy punchcard</p>
In your view, you can fetch next from request.GET, and return the redirect response using either HttpResponseRedirect or the redirect shortcut.
from django.utils.http import is_safe_url
next = request.GET.get('next', '/default/url/')
# check that next is safe
if not is_safe_url(next):
next = '/default/url/'
return redirect(next)
Note that it might not be safe to redirect to a url fetched from the query string. For example, it could link to a different domain. Django has a method is_safe_url that it uses to check next urls when logging in or out.
You don't need {{ }} there, just:
<a href="{% url 'main:buy_punchcard' member.id next=request.path %}">Buy punchcard</p>

How to pass current request params to Symfony2 route

I'm trying to create language/locale switch urls using Symfony2 and twig which will allow to switch language for route without resetting url:
http://example.com/en/cat/test
http://example.com/it/cat/test
http://example.com/sp/cat/test
...
and so on
Here is revelant part of my twig template:
English
My problem is that for example using category url(http://example.com/en/cat/test) gives me exception:
The "_category" route has some missing mandatory parameters ("category").
Which is all okay and understandable since for switcher urls I'm passing only _locale param.
How to pass all current url params?
You can get all request attributes from app.request and override part of them.
<a href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale':'en'}))}}">

Getting the root url in Django

In my view, I want to make a request to mine.com/more/stuff/ from an arbitrary page such as mine.com/lots/of/stuff/to/use or from mine.com. Thus, I can't make this a relative request using ./ or ./../ type things. Do I have to use a context processor to do {{URL_BASE}}more/stuff/? Is there a set way to do this in Django or a best way?
why don't you use named urls? it's always works.
for example {% url 'admin:index' %} always printed as url to admin(in case if you using default django.contrib.admin app).
if you'll have in urls.py smth like
url(r'^lots/', Lots.as_view(), name='lots'),
then just use smth like
{% url 'lots' %}
Don't hardcode your urls!
Instead of a relative url, use an absolute url: /
If you're on mine.com/lots/of/stuff/to/use or mine.com, hitting a link with url: /foo/ will both go to mine.com/foo/

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.

Django: Check if connection is secure from template?

I want to check if my site is running under HTTPS from within my template so that I can conditionally add S's to the HTTPs of my external javascript libraries (namely, jQuery). How can I do that?
If your resources are hosted on the same machine as you are serving requests from, it may not need to specify a url scheme at all:
<script src="/static/js/myfile.js" type="text/javascript"></script>
This will use the same protocol (http or https) and server as the request to the original page.
Edit 2 (2016):
If you're accessing a resource on another server, the best solution now (as pointed out by mpen below) is to use the relative URL scheme:
<script src="//media.example.com/static/js/myfile.js" type="text/javascript"></script>
This will automatically connect to the server using http or https depending on the connection to the current page.
Note that this may cause some problems if you need to support old browsers.
Edit: Alternatively, if you really need the info in your template for some reason, you can add the request context processor, and use a RequestContext in your views. This places a request variable in your template context, which gives you access to the HttpRequest object. You can then test if the request is secure by checking the value of request.is_secure
For example:
<script src="http{% if request.is_secure %}s{% endif %}://media.example.com/static/js/myfile.js" type="text/javascript"></script>
I'm not sure if Google did this at the time I asked this question, but they now recommend you add the library via
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
The // will use whatever scheme you are currently using -- no extra code or conditionals required.
Check the request in the View with is_secure(), and send it to the template.
Please consider using the {% static %} template tag (in Django >= 1.4) which can be configured to host media files on a separate domain or server. This will do away with your is_secure problem.
https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:templatetag-staticfiles-static
for checking the connection scheme, you can use the request.scheme attribute
{% if request.scheme == "http" %}
{% elif request.scheme == "https" %}
{% endif %}