django admin language changes randomly - django

I have recently started working with django internationalization.
There is only one view and matching template for which I added translatable strings and made translations for 3 languages.
Now I notice that the django admin language changes in what seems to be random. It changes to more languages than the ones I translated to (english, french and german).
Anyone know what might have caused it?

Seems like this is cause by a weird behaviour of django's translation module.
translation.activate() changes the language for the whole process.
What I had to do is call translation.deactivate() after rendering the template.

Related

Django project applications division

I'm currently writing django project and got confused when it came to separation into apps. Project consists of posts and categories which are kept in one app, also there is a 'main' app which handles user profile view, login, logout and registration. Now I'm trying to implement user-to-user messages and I'm wondering if it should be kept as separate app.
If Message model is kept in application 'messages' how do I realize show_messages view?
1) It seems that it should be stored in 'main' app since it's linked by my_profile view. It would just get all Message instances form 'messages' app and render template extending profile.html or including from 'messages' app a partial template responsible only for messages listing. But why would I then need separate application just to hold one model there with some helper functions?
2) Secondly I wonder about placing show_messages view in 'messages' app but then I would need to use template which extends template from other application which again seems to be violation of self-containment rule. Also all "accounts/" urls are currently kept in main.urls so I feel wrong about adding "accounts/profile/messages" rule to messages.url.
3) Finally I think about moving Message model with all helpers and templates to 'main' app since messages are designed to work with User models and views therefore forcing additional separation seems useless.
Thanks for reading my thoughts, I'll appreciate all clues and explanations.
When I first started working with Django, I found the answers on this SO question to be particularly helpful, regarding app/project layout: Projects vs Apps
Many of the answers are useful, but this one is particularly pithy:
Try to answer question: "What does my application do?". If you cannot answer in single sentence, then maybe you can split it to several apps with cleaner logic?
I've read this thought somewhere soon after I've stared to work with django and I find that I ask this question my self quite often and it helps me.
Your apps don't have to be reusable, they can depend on each other, but they should do one thing.
Interdependence of apps isn't always problematic. For example, in a lot of my projects I have a separate app that is used solely for creating dynamic menus. In order to work properly, I need to import the specific models of that site into that app -- so I couldn't just drop it into another site, unaltered, and expected it to work. Nonetheless, the other 90% of the code in that app is completely reusable, and it's easier for me to move the relevant code to a new project if its already spun out into a separate app -- even though that app only holds a templatetag and a template.
Ultimately, a django site would technically run just fine with ALL models/views/etc in one big, unwieldy app. But by breaking your project down into "this app performs this specific function" you're probably going make managing your code a lot easier for yourself.
Regarding the 'url' point in 2, there's no reason not to subspace URLs. You are already doing this in a django project already -- mostly likely your main urls.py has an include() to another app, such as your main.urls. There's no reason your main.urls can't also have an include() to your messages app.

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!

Disabling localization for specific apps in 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.

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.