Login

Extended i18n base model

Author:
alcinnz
Posted:
April 8, 2013
Language:
Python
Version:
1.5
Score:
0 (after 0 ratings)

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 an I18NModel.

  • 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

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

Please login first before commenting.