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


Posted in Python onJuly 02, 2019

自定义数据库字段

扩展默认的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字段

使用方法

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

效果图

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

可以看到,数据库字段自动生成了相应语言的字段

当用户语言切换到其他,可以自动适配实现多语言

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python读写Excel文件的实例
Nov 01 Python
Python max内置函数详细介绍
Nov 17 Python
Python之web模板应用
Dec 26 Python
使用EduBlock轻松学习Python编程
Oct 08 Python
Python 隐藏输入密码时屏幕回显的实例
Feb 19 Python
python内存动态分配过程详解
Jul 15 Python
Python面向对象编程基础实例分析
Jan 17 Python
python 实现字符串下标的输出功能
Feb 13 Python
使用python处理题库表格并转化为word形式的实现
Apr 14 Python
Python多线程实现支付模拟请求过程解析
Apr 21 Python
Python上下文管理器Content Manager
Jun 26 Python
浅谈Python3中datetime不同时区转换介绍与踩坑
Aug 02 Python
python 杀死自身进程的实现方法
Jul 01 #Python
python 判断linux进程,并杀死进程的实现方法
Jul 01 #Python
PyCharm-错误-找不到指定文件python.exe的解决方法
Jul 01 #Python
解决pycharm 工具栏Tool中找不到Run manager.py Task的问题
Jul 01 #Python
简单了解python中对象的取反运算符
Jul 01 #Python
python做反被爬保护的方法
Jul 01 #Python
python全栈知识点总结
Jul 01 #Python
You might like
支持中文的php加密解密类代码
2011/11/27 PHP
destoon供应信息title调用出公司名称的方法
2014/08/22 PHP
PHP获取一年中每个星期的开始和结束日期的方法
2015/02/12 PHP
PHP6新特性分析
2016/03/03 PHP
PHP中递归的实现实例详解
2017/11/14 PHP
Laravel中的chunk组块结果集处理与注意问题
2018/08/15 PHP
JQuery 操作select标签实现代码
2010/05/14 Javascript
jquery load()在firefox(火狐)下显示不正常的解决方法
2011/04/05 Javascript
$.get获取一个文件的内容示例代码
2013/09/11 Javascript
js实现文本框中焦点在最后位置
2014/03/04 Javascript
JQuery右键菜单插件ContextMenu使用指南
2014/12/19 Javascript
详解JavaScript中localStorage使用要点
2016/01/13 Javascript
JS使用JSON作为参数实例分析
2016/06/23 Javascript
jsTree使用记录实例
2016/12/01 Javascript
jQuery图片切换动画效果
2017/02/28 Javascript
Angularjs中的验证input输入框只能输入数字和小数点的写法(推荐)
2017/08/16 Javascript
vue :src 文件路径错误问题的解决方法
2018/05/15 Javascript
JavaScript设计模式之单例模式简单实例教程
2018/07/02 Javascript
layui 实现table翻页滚动条位置保持不变的例子
2019/09/05 Javascript
基于node+vue实现简单的WebSocket聊天功能
2020/02/01 Javascript
[03:41]2018完美盛典-《Fight With Us》
2018/12/16 DOTA
Python基于opencv的图像压缩算法实例分析
2018/05/03 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
为什么说Python可以实现所有的算法
2019/10/04 Python
如何使用python3获取当前路径及os.path.dirname的使用
2019/12/13 Python
Python面向对象封装操作案例详解
2019/12/31 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
2019/12/31 Python
Python json转字典字符方法实例解析
2020/04/13 Python
Footshop法国:购买运动鞋
2020/01/19 全球购物
硕士研究生自我鉴定
2013/11/08 职场文书
银行门卫岗位职责
2013/12/29 职场文书
办公室务虚会发言材料
2014/10/20 职场文书
财务个人年度总结范文
2015/02/26 职场文书
创卫工作总结2015
2015/04/22 职场文书
2016优秀大学生个人事迹材料范文
2016/03/01 职场文书