This snippet is an extension of i18n base model for translatable content so all the same usage applies.
I have extended this module in several ways to make it more fully featured.
-
I18NMixin
can be an additional (via multiple inheritance) or alternative superclass for your models juxtaposed with anI18NModel
. -
Adds a property
_
to access the appropriate I18NModel.trans
aliases this (or rather vice versa) for template access. -
In a call to
.filter
you can query on translated fields by wrapping those fields in a call to i18nQ. I like to import this as _ if I haven't already used that import. -
A call to I18NFieldset will return an inline for use in the builtin admin app. I like to call this inline to the assignment to inlines.
-
If you need abstracted access to the I18N model from a model, I've added a property I18N referring to it.
I've been using this with great convenience and stability.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | from django.db.models.base import ModelBase, Model
from django.db.models import Field, Q
from django.db import models
from django.conf import settings
from django.utils.translation import get_language
# Returns class object from a specified module
def getclass(classname, modulename):
from_module = __import__(modulename, globals(), locals(), classname)
return getattr(from_module, classname)
class I18NBase(ModelBase):
def __new__(cls, name, bases, attrs):
try:
if I18NModel in bases:
attr_meta = attrs.pop('Meta', None)
# Find out if `i18n_common_model` is defined in `class Meta`,
# and use that. Otherwise, use this class name -4 chars:
common_classname = getattr(attr_meta, 'i18n_common_model',
name[:-4])
I18NCommonModel = getclass(common_classname, attrs['__module__'])
attrs['_fields'] = ('lang',) + tuple(attr for attr, value in attrs.items()
if isinstance(value, Field))
attrs['i18n_common'] = models.ForeignKey(I18NCommonModel,
related_name='translations')
attrs['lang'] = models.CharField(max_length = 5,
choices = settings.LANGUAGES)
except NameError:
I18NCommonModel = None
ret = ModelBase.__new__(cls, name, bases, attrs)
if I18NCommonModel: I18NCommonModel.I18N = ret
return ret
class I18NModel(Model):
__metaclass__ = I18NBase
class Meta:
abstract = True
class I18NMixin(Model):
"""To be added as an (optionally) additional superclass of models with
associated I18N models."""
class Meta(object):
abstract = True
def trans(self):
"""Returns the translation object for the user's language."""
qs = self.translations.filter(lang=get_language())
if not qs.exists():
qs = self.translations.filter(lang=get_language().split('-')[0])
return qs.get()
_ = property(trans)
def i18nQ(**kwargs):
def q(**kwargs):
return Q(**{'translations__'+key : val for key, val in kwargs.items()})
_ = get_language()
return (q(lang=_) | q(lang=_.split('-')[0])) & q(**kwargs)
from django.contrib.admin import TabularInline
def I18NFieldset(i18nModel):
class inner(TabularInline):
model = i18nModel
fields = i18nModel._fields
extra = 1
return inner
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.