I read a tutorial in Django site but I don't understand how to use the set_language() function. For example, I have a demo follow as:
index.html
{% trans "Hello World." %}
<form action="/i18n/setlang/" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="/next/page/" />
<select name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}">{{ language.name_local }} ({{ language.code}})</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
urls.py
urlpatterns = patterns('',
(r'^i18n/', include('django.conf.urls.i18n')),
)
views.py
What need I write to display the languages, which were chosen from user in this file?
Thanks,
Thinh
With the code you are using, you don't need to write your own views. The form will make a POST request to /i18n/setlang/, with the language code and (optional) the redirect-to (next) page as parameters.
The django view does the following (from the django documentation)
Django looks for a next parameter in the POST data.
- If that doesn't exist, or is empty, Django tries the URL in the Referrer header.
- If that's empty -- say, if a user's browser suppresses that header -- then the user will be - redirected to / (the site root) as a fallback.
So in essence, the user will be redirected after submitting the form, and the django view will set the language for that user according to what was submitted.
Hope this helps,
Hoff
Related
Registration fails silently with django-custom-user
I'm switching from using the default registration model to a custom model (to drop username and just authenticate with email address). An existing user can login, but creating a new user fails silently now. I call url 'registration_register', I get the user create form I expect, I fill it in and click the submit button, and...the form redisplays with email but not password, no error, no user creation.
registration_form.html
{% extends "..." %}
{% block content %}
<form method="post" action="{% url 'registration_register' %}">
{% csrf_token %}
{{ form.email.errors }}
<label for="{{ form.email.id_for_label }}">mail</label> {{ form.email }}
<br>
{{ form.password1.errors }}
<label for="{{ form.password1.id_for_label }}">password</label> {{ form.password1 }}
<br>
{{ form.password2.errors }}
<label for="{{ form.password2.id_for_label }}">password</label> {{ form.password2 }}
<br>
<input type="submit" value="Create" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
More background
I pip install django-custom-user and make the changes recommended here -- adding to INSTALLED_APPS, db sync (in fact, it's a new project, so db delete and create), and the couple code changes to use it. I've left 'registration' in INSTALLED_APPS.
Django (1.7.6)
django-custom-user (0.5)
My urls.py still points to registration.backends.default.urls.
url(r'^accounts/', include('registration.backends.default.urls')),
Well the problem you face is that django-registration expects a username as well as a password and an email address. As you can see in the source code of django-registration
https://bitbucket.org/ubernostrum/django-registration/src/8f242e35ef7c004e035e54b4bb093c32bf77c29f/registration/backends/default/views.py?at=default#cl-74
If I were you I would simply create a simple form and use a FormView from django. After, in order to match django-registration you could do more research and try to fit django-registration with django-custom-user.
It could be that you create a class that inherits django-custom-user, or that you change the form or anything like that. Otherwise you could even fork django-registration and update it according to django-custom-user and then use it for your project and make it available on github as django-registration-custom-user
Have you tried python manage.py makemigrations and python manage.py migrate?
Also try displaying the form as form.as_p in order to get all fields and all errors displayed automatically. Forget about CSS for now.
Also what package is registration.backends.default.urls ?
Because it is not django-custom-user
I hope this helps
As suggested, I'm wanting to show a language prefix in the URL and allow a visitor to my site to change the language using a form in the template. I've been using the sections on URL prefix and set_language redirect view from the "Translation" page of the Django docs as a guide so far. My code is largely copied from this source.
The Problem
Without using "i18n_pattern" (having both "url" calls in "pattern") in my URLconf, I manage to select language on the index.html page and have Django redirect me to the same page with the new language I have chosen. However, of course, the language URL prefix isn't shown.
When I use "i18n_pattern", the language prefix appears in the URL but seems to break the ability to change languages from the index.html form. For example, if I'm set on English and I change from "English (en)" to "Türkçe (tr)" in the form, the page essentially does a refresh without changing to Turkish (English is still shown). I can however change the language by changing my URL language prefix from "/en/" to "/tr/".
pages/templates/pages/index.html:
{% load i18n %}
<html>
<head>
...
</head>
<body>
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
...
</body>
</html>
[project_name]/urls.py:
from django.conf.urls import patterns, include, url
from django.conf.urls.i18n import i18n_patterns
urlpatterns = patterns('',
url(r'^i18n/', include('django.conf.urls.i18n')),
)
urlpatterns += i18n_patterns('',
url(r'', include('pages.urls', namespace='pages')),
)
Note: The templates I'm using are located in the app called "pages".
Any help on getting these to work together would be appreciated! I have so far been unable to find anything on stackoverflow relating to this issue. If any more information is needed, please ask!
This StackOverflow question contains further details and some possible answers to the problem. None of the solutions are really appealing; nor should really be required. Unfortunately, this seems to be a problem with Django where both desired "features" can't work together "out-of-the-box" with the desired effect. In my case, since my site is a single page site, I can get away with setting the context variable with "redirect_to" = '/' (in the view) to negate the problem.
I'm very new to Django and not super familiar with web programming in general, so it's very likely that there is an easy fix to my problem that I'm just unaware of.
My web app is a photo gallery. People can click on a photo to see an enlarged version with buttons on either side for older or newer pictures. In addition, the photos in the gallery can be sorted by tags, which are passed along as URL parameters.
My problem is that when I click on one of the submit buttons, Django replaces the parameters in my URL with the name of the button, thus destroying my reference to what tag I was using. For example, "127.0.0.1:8000/gallery/view/6/?tag=people" upon clicking next, gets converted to "127.0.0.1:8000/gallery/view/6/?older=Older" when it's trying to process the URL.
Code from my HTML:
<form action="/gallery/view/{{ photo.id }}/?tag={{ tag }}" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
In my view.py I pass in the tag plus other information in a render_to_response, but I'm not sure how to/if I can reclaim it while handling the buttons.
render_to_response('item/view.html', {'photo':photo, 'tag':tag, 'related_tags': related_tags, 'related_photos': related_photos, 'has_newer': has_newer, 'has_older': has_older}, context_instance=RequestContext(request))
Here's the view.py code for processing the buttons:
if 'newer' in request.GET:
if has_newer:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(newer[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
if 'older' in request.GET:
if has_older:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(older[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
<form action="/gallery/view/{{ photo.id }}/" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<!--This will append a tag parameter with given value to the querystring -->
<input type="hidden" name="tag" value="{{ tag }}">
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
Note that the query string is removed from action (as it won't be used) and the older and newer parameters will still be sent along.
request.LANGUAGE_CODE tell me what language the user has selected. such as en for English or de for German.
But how do I get the culture code? Such as GB for British English and us for American English?
Many Thanks,
There's request.META['HTTP_ACCEPT_LANGUAGE']. However, this is set by client (web browser, typically), so it may not be set or set properly in some cases. The only fool-proof method is to ask the user to select their preferred language, and then use that setting. However, if it's not crucial that the site be in the right language and you want it to "just work" for the user without intervention, then using the HTTP_ACCEPT_LANGUAGE header is fine. You can even combine the two approaches so the user can switch if they'd prefer a different language than what was detected.
The Django i18n context processor ("django.core.context_processors.i18n") adds your LANGUAGES setting to your context. Which let you do stuff like:
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}">{{ language.name_local }} ({{ language.code }})</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
https://docs.djangoproject.com/en/dev/topics/i18n/translation/#django.conf.urls.i18n.set_language
It's also valid to add dialect, e.g. have a look at this post:
Django: How to add Chinese support to the application
I am trying to translate a django app using the built in i18n. I have already marked the text to be translated and created and compiled the language files (.po/.mo) according to the tutorial and with out errors. I've also changed the USE_I18N to true in the settings file and added the following line into the urls.py as the tutorial instructed:
(r'^i18n/', include('django.conf.urls.i18n')),
I also defined a list of allowed languages in the settings.py, as instructed by the tutorial.
then i created a new page html template and copied in the code the tutorial gave for a language select page:
<form action="/i18n/setlang/" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}">{{ language.name_local }} ({{ language.code }})</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
that page works perfectly too, but when i click on "Go", it tells me there was an error loading the page:
Failed to load resource:http://localhost:8000/i18n/setlang/
the server responded with a status of 404 (NOT FOUND)
I tried changing the redirect by replacing the variable with the link, but that gave me the same result. I tried changing the form action path and the urls.py in case there was some double naming, which gave me the same error.
I have been reading through the tutorial and the readmes, as well as some of the i18n files and can't seem to find a reason for it not to work, and i would really appreciate an answer. thankyou
Are you sure you used the correct urls.py, i.e. the one in your project root, and not in a subdirectory?
What happens if you change it to:
from django.http import HttpResponse
...
(r'^i18n/', lambda x: HttpResponse("Test")),
Can you go to http://localhost:8000/i18n/ after that?