Django setLang does not process "Next" parameter - django

I'm trying to implement on-fly language change with the following code:
{% for lang in LANGUAGES %}
<li>
<form name="setLang{{ lang.1}}" action="/i18n/setlang/" method="POST">{% csrf_token %}
<input name="next" type="hidden" value="http://google.com" />
<input type="hidden" name="language" value="{{ lang.0 }}" />
{{ lang.0 }}
</form>
</li>
{% endfor %}
It works great, the problem is that it doesn't return to URL specified in "next" field. I forced it to be "google.com" just to see how it works, but it keeps redirecting me back to my homepage.
Here is my urls.py:
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'izolyatsia.views.home', name='home'),
# url(r'^izolyatsia/', include('izolyatsia.foo.urls')),
url(r'^$', 'showcase.views.home', name='home'),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^project/(?P<project_name>[a-zA-Z0-9_.-]+)/$', 'izolyatsia.views.project'),
(r'^post/(?P<slug>[a-zA-Z0-9_.-]+)/$', 'izolyatsia.views.post'),
#Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
(r'^tinymce/', include('tinymce.urls')),
url(r'^wysiwyg_post/$', 'izolyatsia.views.wysiwyg_post', name='wysiwyg_post'),
url(r'', include('multiuploader.urls')),
(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^(.*)/$', 'pages.views.show_page', name='show_page'),
)
I've got no idea why it doesn't work, maybe someone here can help me?
thanks in advance,
m.

Redirecting to sites outside your domain is explicitly prevented by the code - the set_language view calls django.utils.is_safe_url(), which checks you're not trying to do exactly that.

Please take a look to the django doc here, where you can find that you should have the middlewares in this order in your settings.py file:
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
)
maybe it can be what is happen to you with, I think.

Related

Django translate refers to wrong URL

I am using Django (version 2.1.3) in one of my project and currently struggle with a weird bug. I use the build in internationalization module and included a language toggler in my main menu which is loaded on every page
{% get_current_language as LANGUAGE_CODE %}
<form id="form" action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ request.get_full_path|strip_lang }}" />
<input id="form_lang" name="language" type="hidden" value="{{ LANGUAGE_CODE }}"/>
</form>
<ul role="menu" class="dropdown-menu"id="lang-dropdown">
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<li>
<a href="#" onClick='(function(){
document.getElementById("form_lang").value = "{{ language.code }}";
document.getElementById("form").submit(); return false;})();return false;'>
{{ language.name_local }} ({{ language.code }})</a>
</li>
{% endfor %}
</ul>
I created a special tag "strip_lang" to strip the language identifier from the current URL.
#register.filter
#stringfilter
def strip_lang(value):
"""Removes all values of arg from the given string"""
lang = getattr(settings, "LANGUAGES", None)
url = value.split('/')
if url[1] in [l[0] for l in lang]:
return urllib.parse.unquote('/' + '/'.join(value.split('/')[2:]))
else:
return urllib.parse.unquote(value)
This all works well. However, for one of my apps, I always get rerouted to a different app.
ie if I am at path
/en/app1/mypage1
and toggle the language i suddenly end up at
/fr/app2/mypage1
*****EDIT*****
Referals for app2 work correctly. When entering a URL manually for app1 the pages load correctly.
My url.py in the main project looks like this
urlpatterns = [
path('admin/', admin.site.urls),
path('i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(
path('app1/', include('app1.urls')),
path('app2/', include('app2.urls')),
path('app3/', include('app3.urls')),
url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
url(r'^login/$', auth_views.LoginView.as_view(), {'template_name': 'login.html'}, name='login'),
url(r'^logout/$', auth_views.LogoutView.as_view(), {'template_name': 'logged_out.html'}, name='logout'),
url(r'^oauth/', include('social_django.urls', namespace='social')),
prefix_default_language=False)
ans urls.py of my apps look like this
urlpatterns = [
path('', views.index, name='index'),
path('surveys/', views.nrgt_surveys, name='nrgt_surveys'),
path('surveys/<str:survey_name>/', views.survey, name='survey'),
path('surveys/<str:survey_name>/<query_name>', views.survey_query, name='survey_query'),
path('landscapes/', views.landscapes, name='landscapes'),
path('landscapes/<str:landscape_name>/', views.landscape, name='landscape'),
path('landscapes/<str:landscape_name>/<query_name>', views.landscape_query, name='landscape_query'),
]
I do not specify the app name anywhere in my code. When I track my network requests I can also see that the correct URL is submitted in the POST request. Why does my url get modified?

Namespacing urls in django-registration

I want to keep a clean urls description in my projet, so I use namespaces:
project/urls.py:
urlpatterns = patterns('',
url(r'^contracts/', include('apps.contracts.urls', namespace='contracts')),
url(r'^accounts/', include('apps.registration_custom.backends.vince.urls', namespace='accounts')),
registration_custom/backends/vince/urls.py:
urlpatterns = patterns('',
url(r'^activate/complete/$',
TemplateView.as_view(template_name='registration/activation_complete.html'),
name='registration_activation_complete'),
# Activation keys get matched by \w+ instead of the more specific
# [a-fA-F0-9]{40} because a bad activation key should still get to the view;
# that way it can return a sensible "invalid key" message instead of a
# confusing 404.
url(r'^activate/(?P<activation_key>\w+)/$',
ActivationView.as_view(),
name='registration_activate'),
url(r'^register/$',
CustomRegistrationView.as_view(),
name='registration_register'),
url(r'^register/complete/$',
TemplateView.as_view(template_name='registration/registration_complete.html'),
name='registration_complete'),
url(r'^register/closed/$',
TemplateView.as_view(template_name='registration/registration_closed.html'),
name='registration_disallowed'),
(r'', include('registration.auth_urls')),
)
With this configuration, if I request /accounts/password/reset/ I get an error:
Reverse for 'django.contrib.auth.views.password_reset_done' with arguments '()' and keyword arguments '{}' not found
But if I'm not namespacing my urls, everything goes clean with my /accounts/password/reset/ request.
What I understand is that the django/contrib/auth/views/password_reset view is using reverse() on 'django.contrib.auth.views.password_reset_done'. And the urls dispatcher get lost because it should be asking for 'accounts:auth_password_reset_done'.
Am I guessing right?
Then what would be my options?
EDIT.
The template code that redirect to /accounts/password/reset :
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="{% trans 'Log in' %}" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
<p>{% trans "Forgot password" %}? {% trans "Reset it" %}!</p>
<p>{% trans "Not member" %}? {% trans "Register" %}!</p>
{% endblock %}
Wahaha, I've made a step in my Django's comprehension!
In fact, Django auth module is looking for a view when he asks for: reverse('django.contrib.auth.views.password_reset_done')
But my urls config is namespaces, so Django is lost (here I don't know exactly, maybe someone can explain better).
So I need to say to Django to look first for a non-namespaced url pattern first, just for it's core code.
So my trick is to add a line in the myproject/urls.py:
urlpatterns = patterns('',
url(r'^contracts/', include('apps.contracts.urls', namespace='contracts')),
# this is tricky
# the default auth module need to reverse some urls like reverse('django.contrib.auth.views.password_reset_done')
# but I want to keep a namespaced urls config
# then I need to supply a first url path to django when he look at non-namespaced urls
url(r'^accounts/', include('registration.auth_urls')),
url(r'^accounts/', include('apps.registration_custom.backends.vince.urls', namespace='accounts')),
And everything is working fine!
I admit that this is not an elegant solution, but it has the benefit to keep my namespaces right, so will be the templates.
Add correct namespace and app name for include('registration.auth_urls') (see last line)
urlpatterns = patterns('',
url(r'^activate/complete/$',
TemplateView.as_view(template_name='registration/activation_complete.html'),
name='registration_activation_complete'),
# Activation keys get matched by \w+ instead of the more specific
# [a-fA-F0-9]{40} because a bad activation key should still get to the view;
# that way it can return a sensible "invalid key" message instead of a
# confusing 404.
url(r'^activate/(?P<activation_key>\w+)/$',
ActivationView.as_view(),
name='registration_activate'),
url(r'^register/$',
CustomRegistrationView.as_view(),
name='registration_register'),
url(r'^register/complete/$',
TemplateView.as_view(template_name='registration/registration_complete.html'),
name='registration_complete'),
url(r'^register/closed/$',
TemplateView.as_view(template_name='registration/registration_closed.html'),
name='registration_disallowed'),
(r'', include('registration.auth_urls'), namespace='accounts', app_name='registration'),
)

Django - Linking to web sections with buttons in a home page

Hi everyone and thanks for reading!
I'm a very novel user of Django. I decided to move from my basic web to django for learning how to use a framework web. I did the django tutorial but with my project... the way is not being hassle-free at all.
Let me first describe briefly my project so you can get an overview of the whole thing. My basic web consists of a home page and sections where you can change different parameters (such as room temperature) or check sensors data.
By now, I have the home page and the temperature control section running (with few things to fix, but correctly rendered). I would like to link every section with a button in the home page. This is my home page template:
{% extends 'base.html' %}
{% block content %}
<h1>Here goes a title</h1>
<p>A welcome message here...</p>
<h2>please select an action</h2>
<div id="column_left" class="column">
{% for action in actions_list_left %}
<div id="action_box1{{ forloop.counter }}" class="action_box">
<input type="button" onclick= " HELP HERE!! "
id= "{{ action.action_name }}_sel" class="action_button">
<div id="{{ action.action_name }}_desc" class="action_desc">
{{ action.description }}
</div>
</div>
{% endfor %}
</div>
<!--I ommit the right column, containing more actions...-->
{% endblock %}
I would like to use my "action" model fields to link to other sections. My idea is to use the action name field as the url of that section (to do it in a generic "model" way). For instance, if my home page is at localhost:8000/ and an action name is "temp", i would like the associated button to link to localhost:8000/temp and render the suitable template.
As I think is an urls.py issue, I post here my urls files (without import lines)...
urls.py
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', include('principal.urls')),
url(r'^temp/', include('temp.urls')),
)
principal/urls.py
urlpatterns = patterns('',
url(r'^$', 'principal.views.home', name='home'),
)
temp/urls.py
urlpatterns = patterns('',
url(r'^$', 'temp.views.index', name='temp_index'),
url(r'^(?P<pk>\d+)/$',
DetailView.as_view(
model=Room,
template_name='temp/roomTemp.html')),
)
I have tried a few ideas that I've read in other threads...
{% url temp:index %}
This one threw a NoReverseMatch error... 'temp' is not a registered namespace. Then I googled how to get through this and I changed this line in urls.py:
url(r'^temp/', include('temp.urls', namespace='temp')),
Also in temp/urls.py I changed the line:
url(r'^$', 'temp.views.index', name='temp'),
Both pages are still rendered OK, but the button is not working (does nothing)... It must be quite simple, but all the url thing seems a bit tricky to me (by the way the syntax sometimes is like a makefile mordor file :P). I'm using Django 1.3
Any help would be really appreciated. Also, any "good django coder" comment or explanation would be very useful, just to not make the same mistake again!
Thanks in advance,
Juan
EDIT:
I post the fix in the code here just in case someone find it useful:
<form action="{% url action.action_url %}">
<input type="submit" id="{{ action.action_name }}_sel" value="" class="action_button">
<div id="{{ action.action_name }}_desc" class="action_desc">
{{ action.description }}
</div>
</form>
If you don't need to use url namespaces you can do this
urls.py
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', include('principal.urls')),
url(r'^temp/', include('temp.urls')),
)
temp/urls.py
urlpatterns = patterns('',
url(r'^$', 'temp.views.index', name='temp_index'),
url(r'^(?P<pk>\d+)/$',
DetailView.as_view(
model=Room,
template_name='temp/roomTemp.html')),
)
And then in template
{% url 'temp_index' %}
Hope it works for you.

Django - How to get a form template to run (getting ' namespace not registered error ')

I am a newbie at Django.
Got Django 1.4.2 working with Python 2.7
on Windows 7.
I am following a tutorial and I need to get a form template appear
with radio buttons. Selecting a button sends data and the page should
ask you if you want to 'vote again?'. Also, if you do not select a button
and submit the form it should show a message asking you to make a choice.
So far,
here's the HTML form:
<h1>{{ poll.question }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' poll.id %}" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
Now when I type http://localhost:8000/polls/1/ I should get the form, but instead I get the following error message:
NoReverseMatch at /polls/1/
u"'polls" is not a registered namespace
I registered polls as a namespace, see below in the project urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
)
To answer cathy's kind request, here's the vote url:
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
.. and below I include the project folder's urls if this could help:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
)
And I just noticed the following error message shown on the browser (because Debug = True):
Error during template rendering
In template C:\Python27\Scripts\mysite\mytemplates\polls\index.html, error at line 4
u"'polls" is not a registered namespace
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Any help to make that form run properly will be appreciated!
urlpatterns = patterns('polls.views',
url(r'^$', 'index', name='index'),
url(r'^(?P<poll_id>\d+)/$', 'detail', name='detail'),
url(r'^(?P<poll_id>\d+)/results/$', 'results', name='results'),
url(r'^(?P<poll_id>\d+)/vote/$', 'vote', name='vote'),
)
{% url polls:detail poll.id %}
Go to your settings.py file and check out your template loaders. You may need to switch their order.
The correct order should be:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
Hope this helps.
Try to put {% load url from future %} on the top of your html file. It should fix your problem.

django - set_language view giving me a "Page not found" error

Hi there
I've been following the docs on internationalization for django (using mezzanine on django 1.2.5) closely and everything is fine, except when i use a form like the one in the docs to switch language code
like this
<form action="/i18n/setlang/" method="post">
<input name="next" type="hidden" value="/whatever/" />
<select name="language">
{% for lang in LANGUAGES %}
<option value="{{ lang.0 }}">{{ lang.1 }}</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
with my urlconf looking like this
urlpatterns += patterns("",
("^admin/", include(admin.site.urls)),
("^", include("mezzanine.urls")),
(r'^i18n/', include('django.conf.urls.i18n')),
)
when i switch language and hit "go", i get a
Page Not Found (404)
Request Method: POST
Request URL: http://127.0.0.1:8000/i18n/setlang/
No Page matches the given query.
i added the i18n urls and the locale middleware alright.I tried it in a fresh project as well without luck.
Any clues?
Mezzanine's urlpatterns include a "catch all" for pages, so anything underneath it will never be found. To get your patterns working you simply need to swap the last two patterns in your urls.py to look like:
urlpatterns += patterns("",
("^admin/", include(admin.site.urls)),
(r'^i18n/', include('django.conf.urls.i18n')),
("^", include("mezzanine.urls")),
)