Disabling localization for specific apps in Django - django

Is there a way to disable localization for specific apps in settings for Django?
There are two possible reasons for this:
Switch off localization in admin apps eg contrib/admin because admins would prefer to use English rather than the local language.
Some app default translations are really bad and confusing, and we would like to keep them off during development until we get to doing our own proper translation.
I know we can just delete the translation files or other hacks maybe, but having this in settings is more convenient when we're doing frequent upgrades.
Regards.

There is no such setting to disable translation for specific apps.
Regarding your first use-case, having admin in another language is easily achived with custom middleware, check this snippet:
http://source.mihelac.org/2009/11/12/django-set-language-for-admin/
If url scheme of 3rd party apps are simple, maybe you can use same approach to set different (default) language for them.

If you enable LocaleMiddleware, you can then set the appropriate cookie or session variable for that user. I usually implement a drop down with the available languages for the system. User selects the language, and based on that I set the session or cookie for that user. This allows the admin to remain in English while the other areas are translated.
Here is the order of lookup (from the docs):
First, it looks for a django_language key in the current user's session.
Failing that, it looks for a cookie.
The name of the cookie used is set by the LANGUAGE_COOKIE_NAME setting.
(The default name is django_language.)
Failing that, it looks at the Accept-Language HTTP header. This header is sent
by your browser and tells the server which language(s) you prefer, in order by
priority. Django tries each language in the header until it finds one with
available translations.
Failing that, it uses the global LANGUAGE_CODE setting.
EDIT:
It is not possible through settings; however depending on how you are using the app - you can "force" translation of only the language you want. This can cause problems if your languages are RTL (display problems).
The solution you hinted at (deleting the actual gettext translation files), is one way, but not recommended.
Since the displaying of translated text is a function of the template engine, simply overriding the templates of those applications and disabling the translation tags should do what you want, and is more portable.

Related

Changing language with React Native and django-modeltranslation

I would like to add option to mobile app to change language. Im using django on backend and RN as mobile. So I installed django-modeltranslation and added my model I want to translate. On mobile I display available languages. When user clicks on specific language I would like to get translated data. I have huge problem to create logic how to do it. I'm not asking about code just some hints and idea
EDIT:
For example: I added translation from django-modeltranslation to my model (i.e GameTask with field title, description etc). In my settings.py I have declared languages ('en','de','uk',etc) and added translations in database (for every field of GameTask, I added title(en), title(de) etc). When I change language in settings.py, values on mobile are changing too (so working as intended). So im not storing any translated text in app files, just in database (except of static errors and informations). Now I just want to send info from mobile with chosen language and activate this language on backend to return content in specific language
If you want to completely make your application multi-language, you need two things.
Translation system for your app
Translation system for your api.
First, use a pre-built context api or create your own to support changing language in-app. Something like this: https://medium.com/#ally_20818/multi-language-text-with-react-native-react-context-b76d5677346d
When user changes the language, store the language name or key in async-storage or some other database.
Change the texts in the react-native side based on the selected language.
When you're making a api call, send the selected language too. Get the selected language on api side and return appropriate texts based on language.
UPDATE:
Since you're not storing any text on react-native side, you only need to add a picker (react-native-picker/picker is a native picker) and store the selected language key (en, de, uk etc in your case) in a database like react-native-async-storage. When you're making api requests with react-native, include an additional header or post data which includes selected language key. And you can get and use that key in your django back-end.

Django multi-lingual site : how to?

I want to have my website in three languages and allow user to change preffered language somewhere in my template. My models will need translating. I found a few libraries perhaps I should use :
https://code.google.com/p/django-multilingual/ for traslating my models
https://pypi.python.org/pypi/django-localeurl/1.4 for language prefix in URL's
https://docs.djangoproject.com/en/dev/topics/i18n/ for translating static parts of my site
However I can't understand how these come together. Perhaps someone could give me a rundown of steps to translate my website.
You can use i18n_patterns instead of django-localeurl if you use Django 1.4. or later.
i18n_patterns will set active language based on URL prefix.
Django I18n will serve translated messages in python code and templates based on active language . (You will have to makemessages and compilemessages to create and compile translations).
For translations in model there are lot of libraries, majority of them use active language to serve field translation. I prefer django-modeltranslation, which allows translating of 3rd party app models without changing their code.
Hope this helps!

django view/template redirection for mobile browsers

Not sure if anyone has had experience with a good solution to rendering templates specifically for mobile devices using django.
I wrote a middleware request processor that uses regex to detect whether it is a mobile browser or not. I am currently setting a boolean attribute on the request so that I can use it further down the pipe. But really my business logic is the same I just want to use a different set of templates.
Is there a way for me to add a new template directory to settings.TEMPLATE_DIRS in the middleware processor, so that a mobile user would get the views I choose to rewrite, but everything else would fall back to the default template directories. But I need to make sure it doesn't persist between requests.
If i added a directory, would settings continue to hold onto it between requests?
..and if so, is this the right solution (checking the browser agent, adding an additional template folder, and then removing it at the end of each request)?
Dynamically modifying the template search path is a great way to handle this. It's not hard to define your own template loader and add it to the TEMPLATE_LOADERS in settings.py. The tricky part of this is handling the fact you may be running in a multi-threaded environment, and you don't have a way to pass your request directly to the template loader.
The way around it is to store the request, a flag, or simply the directories to add to the path in a thread local variable, and reference that thread local variable from a custom template loader. Here's a blog post about creating template loaders, I can vouch for the fact it's pretty easy and works. Here's an even better one about doing exactly what you need.
I guess i didn't specifically point out that you probably do not want to try to change settings.TEMPLATE_DIRS per request, you will get wierd results at best.

Django Localization: How to do functional test?

I've localized my site following the documentation.
Now, I've wanted to test this through the browser. But, I seem not to be able to figure out how this is done.
I am using FF and in preference / content / languages, added 'es'. I also moved it to the top of the languages list.
Then when I go to the site, I don't see anything translated.
What am I missing?
Thanks
Eric
Django stores the language code in the cookie for each user. You'll probably want to make use of Django's set_language view, perhaps at least in your development environment, because it's quicker than deleting cookie entries or destroying sessions. I used it to write a custom view that switches between the base language and another one to snoop through the site just to be 100% sure I'm translating everything.
If that still doesn't work, might want to make sure you've added it to the list of LANGUAGES and that you've added the django.middleware.locale.LocaleMiddleware to your list of middleware, because it's responsible for parsing Accept-Language from request headers.

Django: django-transmeta - sorting comments

I have created an article site, where articles are published in several languages. I am using transmeta (http://code.google.com/p/django-transmeta/) to support multiple languages in one model.
Also I am using generic comments framework, to make articles commentable. I wonder what will happen if the same article will be commented in one language and then in another. Looks like all comments will be displayed on both variants....
The question actually is:
Is there a possibility to display only comments submitted with current language of the article?
I tried the approach of transmeta for translation of dynamic texts and I had the following experience:
You want another language, you need to change the database model which is generally undesirable
You need every item in both languages, which is not flexible
You have problems linking with other objects (as you point out in your question)
If you take the way of transmeta you will need two solutions:
The transmeta solution for translating fields in a model
For objects connected to a model using transmeta you will need an additional field to determine the language, say CharField with "en", "de", "ru" etc.
These were major drawbacks that made me rethink the approach and switch to another solution: django.contrib.sites. Every model that needs internationalization inherits from a SiteModel:
class SiteModel(models.Model):
site = models.ForeignKey(Site)
Every object that would need transmeta translation is connected to a site. Every connected object can determine its language from the parent object's site attribute.
I basically ran the wikipedia approach and had a Site object for every language on a subdomain (en., de., ru.). For every site I started a server instance that had a custom settings file which would set the SITE_ID and the language of the site. I used django.contrib.sites.managers.CurrentSiteManagerto display only the items in the language of the current site. I also had a manager that would give you objects of every language. I constructed a model that connects objects of the same model from different languages denoting that they are semantically the same (think languages left column on wikipedia). The sites all use the same database and share the same untranslated User model, so users can switch between languages without any problem.
Advantages:
Your database schema doesn't need to change for additional languages
You are flexible: add languages easily, have objects in one language only etc.
Works with (generic) foreign keys, they connect to an object and know what language it is. You can display the comments of an object and they will be in one language. This solves your problem.
Disadvantages:
It's a greater deal to setup: you need a django server instance for every site and some more glue code
If you need e.g an article in different languages, you need another model to connect them
You may not need the django Site model and could implement something that does the same without the need of multiple django server instances.
I don't know what you are trying to build and what I described might not fit to your case, but it worked out perfectly for my project (internationalized community platform built upon pinax: http://www.bpmn-community.org/ ). So if you disclose some more about your project, I might be able to advise an approach.
To finally answer your question: No, the generic comments will not work out of the box with transmeta. As you realised you will have to display comments in both languages for the article that is displayed in one language. Or you will have to hack into the comments and change the model and do other dirty stuff (not recommended). The approach I described works with comments and any other pluggable app.
To answer your questions:
Two Django instances can share one database, no problem there.
If you don't want two Django instances, but one, you will have to do the following: A middleware checks the incoming request, extracts desired language from URL (en.example.com or example.com/en/ etc.) and saves the language preference in the request object. The view will have to take the request object with the language and take care of the filtering of objects accordingly. Since there is no dedicated server for the language (like in the sites approach where the language is stored in the settings.py file), you can only get the language from the request and you will have to pass attributes from the request object to Model managers to filter objects.
You could try to fake a global language state in the django application with an approach like threadlocals middleware, however I don't know if this plays out nicely with django I18N engine (which is also does some thread magic).
If you want to go big with your site in multiple languages, I recommend going for the sites-approach.