Django如何自定义Field实现多语言[Django框架]

Django高级编程之自定义Field实现多语言

自定义数据库字段

扩展默认的models.CharField和models.TextField使之成为支持多语言的字段。可以轻松实现复用,无需配置多余选项。

from django.conf import settings

from django.db import models

from django.utils.translation import get_language

class MultilingualField(models.Field):

    SUPPORTED_FIELD_TYPES = [models.CharField, models.TextField]

    def __init__(self, verbose_name=None, **kwargs):

        self.localized_field_model = None

        for model in MultilingualField.SUPPORTED_FIELD_TYPES:

            if issubclass(self.__class__, model):

                self.localized_field_model = model

        self._blank = kwargs.get("blank", False)

        self._editable = kwargs.get("editable", True)

        super().__init__(verbose_name, **kwargs)

    @staticmethod

    def localized_field_name(name, lang_code):

        lang_code_safe = lang_code.replace("-", "_")

        return f"{name}_{lang_code_safe}"

    def get_localized_field(self, lang_code, lang_name):

        _blank = (self._blank

                  if lang_code == settings.LANGUAGE_CODE

                  else True)

        localized_field = self.localized_field_model(

            f"{self.verbose_name} ({lang_name})",

            name=self.name,

            primary_key=self.primary_key,

            max_length=self.max_length,

            unique=self.unique,

            blank=_blank,

            null=False, # we ignore the null argument!

            db_index=self.db_index,

            default=self.default or "",

            editable=self._editable,

            serialize=self.serialize,

            choices=self.choices,

            help_text=self.help_text,

            db_column=None,

            db_tablespace=self.db_tablespace)

        return localized_field

    def contribute_to_class(self, cls, name,

                            private_only=False):

        def translated_value(self):

            language = get_language()

            val = self.__dict__.get(

                MultilingualField.localized_field_name(

                        name, language))

            if not val:

                val = self.__dict__.get(

                    MultilingualField.localized_field_name(

                            name, settings.LANGUAGE_CODE))

            return val

        # generate language-specific fields dynamically

        if not cls._meta.abstract:

            if self.localized_field_model:

                for lang_code, lang_name in settings.LANGUAGES:

                    localized_field = self.get_localized_field(

                        lang_code, lang_name)

                    localized_field.contribute_to_class(

                            cls,

                            MultilingualField.localized_field_name(

                                    name, lang_code))

                setattr(cls, name, property(translated_value))

            else:

                super().contribute_to_class(

                    cls, name, private_only)

class MultilingualCharField(models.CharField, MultilingualField):

    pass

class MultilingualTextField(models.TextField, MultilingualField):

    pass

这里定义了 MultilingualCharField 和 MultilingualTextField字段。

相关推荐:《Python相关教程》

使用方法

settings.py中配置多语言

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

LANGUAGES = (

    ('en-us', 'US English'),

    ('zh-hans', 'Asia/Shanghai')

)

默认语言设置为中文,多语言为英语

models.py中使用字段

from django.db import models

from django.utils.translation import ugettext_lazy as _

from utils.fields import (

    MultilingualCharField,

    MultilingualTextField

)

class Item(models.Model):

    title = MultilingualCharField(_('Title'), max_length=200)

    description = MultilingualTextField(_('Description'), blank=True)

    content = MultilingualTextField(_('Content'))

    def __str__(self):

        return self.title

效果图

z.jpg

可以看到,数据库字段自动生成了相应语言的字段,当用户语言切换到其他,可以自动适配实现多语言。

以上是 Django如何自定义Field实现多语言[Django框架] 的全部内容, 来源链接: utcz.com/z/539602.html

回到顶部