Moved autoregistration code to init and merged related changes from hyperweek's branch at github . This eliminates the need for hooking into urls.py.

This commit is contained in:
Dirk Eschler 2012-07-11 09:52:49 +00:00
parent 1af6f6de8a
commit 4afb04b75a
5 changed files with 98 additions and 76 deletions

View file

@ -4,16 +4,11 @@ v0.4.0-alpha1
CHANGED: Use app-level translation files in favour of a single project-level
one. Adds an autoregister feature similiar to the one provided by
Django's admin. A new setting MODELTRANSLATION_TRANSLATION_FILES keeps
backwards compatibility with older versions. This is basically a merge
from django-modeltranslation-wrapper with a few changes regarding how
registration is triggered. See documentation for details.
(thanks to Jacek Tomaszewski, the author of modeltranslation-wrapper,
resolves issues 58 and 71)
NOTE: If you are upgrading from an older version of modeltranslation
and upgrade directly from svn, make sure to delete a possible
models.pyc leftover in the modeltranslation directory. Otherwise you
might get a weird TypeError from Django trying to use the old file:
__import__() argument 1 must be string, not None.
backwards compatibility with older versions. See documentation for
details. This is basically a merge from both
django-modeltranslation-wrapper and hyperweek's branch at github.
(thanks to Jacek Tomaszewski, hyperweek and haineault)
resolves issues 19, 58 and 71)
CHANGED: Moved tests to separate folder and added tests for TranslationAdmin.
To run the tests the settings provided in model.tests.modeltranslation
have to be used (settings.LANGUAGES override doesn't work for

View file

@ -49,9 +49,7 @@ in detail in the following sections:
4. Configure the ``MODELTRANSLATION_TRANSLATION_FILES`` variable in your
``settings.py``.
5. Add ``translator.autoregister()`` to your project's ``urls.py``.
6. Sync the database using ``manage.py syncdb`` (note that this only applies
5. Sync the database using ``manage.py syncdb`` (note that this only applies
if the models registered in the ``translations.py`` did not have been
synced to the database before. If they did - read further down what to do
in that case.
@ -212,27 +210,6 @@ translation will have been added some auto-magical fields. The next section
explains how things are working under the hood.
Autoregister translation files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Similiar to Django's admin, modeltranslation provides a mechanism to
automatically register your translation files. It has to be hooked into your
project's urls.py.
::
from modeltranslation import translator
translator.autodiscover()
# ...
# Must be in in front of:
from django.contrib import admin
admin.autodiscover()
.. note:: This step is basically optional if you prefer to register your models
programmatically.
Changes automatically applied to the model class
------------------------------------------------
After registering the ``News`` model for transaltion an SQL dump of the

View file

@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
# FIXME: autodiscover runs twice
def autodiscover():
"""
Auto-discover INSTALLED_APPS translation.py modules and fail silently when
not present. This forces an import on them to register.
Also import explicit modules.
"""
import sys
import copy
from django.conf import settings
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
from modeltranslation.translator import translator
from modeltranslation.settings import TRANSLATION_FILES
for app in settings.INSTALLED_APPS:
mod = import_module(app)
# Attempt to import the app's translation module.
module = '%s.translation' % app
before_import_registry = copy.copy(translator._registry)
try:
import_module(module)
except:
# Reset the model registry to the state before the last import as
# this import will have to reoccur on the next request and this
# could raise NotRegistered and AlreadyRegistered exceptions
translator._registry = before_import_registry
# Decide whether to bubble up this error. If the app just
# doesn't have an translation module, we can ignore the error
# attempting to import it, otherwise we want it to bubble up.
if module_has_submodule(mod, 'translation'):
raise
for module in TRANSLATION_FILES:
import_module(module)
# In debug mode, print a list of registered models to stdout
if settings.DEBUG:
try:
if sys.argv[1] in ('runserver', 'runserver_plus'):
translated_model_names = ', '.join(
t.__name__ for t in translator._registry.keys())
print('modeltranslation: Registered %d models for '
'translation (%s).' % (len(translator._registry),
translated_model_names))
except IndexError:
pass
def handle_translation_registrations(*args, **kwargs):
"""
Ensures that any configuration of the TranslationOption(s) are handled when
importing modeltranslation.
This makes it possible for scripts/management commands that affect models
but know nothing of modeltranslation.
"""
import inspect
from django.conf import settings
from modeltranslation.settings import ENABLE_REGISTRATIONS
if not ENABLE_REGISTRATIONS:
# If the user really wants to disable this, they can, possibly at their
# own expense. This is generally only required in cases where other
# apps generate import errors and requires extra work on the user's
# part to make things work.
return
# This is a little dirty but we need to run the code that follows only
# once, no matter how many times the main modeltranslation module is
# imported. We'll look through the stack to see if we appear anywhere and
# simply return if we do, allowing the original call to finish.
stack = inspect.stack()
for stack_info in stack[1:]:
if 'handle_translation_registrations' in stack_info[3] \
and __file__ == stack_info[2]:
return
# Trigger autodiscover, causing any TranslationOption initialization
# code to execute.
autodiscover()
handle_translation_registrations()

View file

@ -34,3 +34,7 @@ try:
settings, 'MODELTRANSLATION_CUSTOM_FIELDS', ('BooleanField',))
except IndexError:
pass
# Don't change this setting unless you really know what you are doing
ENABLE_REGISTRATIONS = getattr(
settings, 'MODELTRANSLATION_ENABLE_REGISTRATIONS', settings.USE_I18N)

View file

@ -232,47 +232,5 @@ class Translator(object):
'translation' % model.__name__)
def autodiscover():
"""
Auto-discover INSTALLED_APPS translation.py modules and fail silently when
not present. This forces an import on them to register.
Also import explicit modules.
"""
import sys
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
from modeltranslation.settings import TRANSLATION_FILES
project_translations = TRANSLATION_FILES
for app in settings.INSTALLED_APPS:
mod = import_module(app)
# Attempt to import the app's translation module.
module = '%s.translation' % app
try:
import_module(module)
except:
# Decide whether to bubble up this error. If the app just
# doesn't have an translation module, we can ignore the error
# attempting to import it, otherwise we want it to bubble up.
if module_has_submodule(mod, 'translation'):
raise
for module in project_translations:
import_module(module)
# In debug mode, print a list of registered models to stdout
if settings.DEBUG:
try:
if sys.argv[1] in ('runserver', 'runserver_plus'):
translated_model_names = ', '.join(
t.__name__ for t in translator._registry.keys())
print('modeltranslation: Registered %d models for '
'translation (%s).' % (len(translator._registry),
translated_model_names))
except IndexError:
pass
# This global object represents the singleton translator object
translator = Translator()