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网络编程学习笔记(五):socket的一些补充
Jun 09 Python
Python datetime时间格式化去掉前导0
Jul 31 Python
python多进程操作实例
Nov 21 Python
python根据出生日期返回年龄的方法
Mar 26 Python
多版本Python共存的配置方法
May 22 Python
python 判断是否为正小数和正整数的实例
Jul 23 Python
Python爬虫之xlml解析库(全面了解)
Aug 08 Python
用Python删除本地目录下某一时间点之前创建的所有文件的实例
Dec 14 Python
Python中最好用的命令行参数解析工具(argparse)
Aug 23 Python
Python vtk读取并显示dicom文件示例
Jan 13 Python
如何用python爬取微博热搜数据并保存
Feb 20 Python
详解Python flask的前后端交互
Mar 31 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
实现WordPress主题侧边栏切换功能的PHP脚本详解
2015/12/14 PHP
php运行报错Call to undefined function curl_init()的最新解决方法
2016/11/20 PHP
PHP ElasticSearch做搜索实例讲解
2020/02/05 PHP
JS是按值传递还是按引用传递
2015/01/30 Javascript
完美兼容多浏览器的js判断图片路径代码汇总
2015/04/17 Javascript
javascript实现控制的多级下拉菜单
2015/07/05 Javascript
AngularJS1.X学习笔记2-数据绑定详解
2017/04/01 Javascript
微信小程序实现简单input正则表达式验证功能示例
2017/11/30 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
微信小程序中weui用法解析
2019/10/21 Javascript
jquery实现上传文件进度条
2020/03/26 jQuery
[02:27]刀塔重生降临
2015/10/14 DOTA
centos系统升级python 2.7.3
2014/07/03 Python
python连接oracle数据库实例
2014/10/17 Python
python通过socket查询whois的方法
2015/07/18 Python
python 文件操作删除某行的实例
2017/09/04 Python
Python中的浮点数原理与运算分析
2017/10/12 Python
Python使用flask框架操作sqlite3的两种方式
2018/01/31 Python
Django中Forms的使用代码解析
2018/02/10 Python
Python实现检测文件MD5值的方法示例
2018/04/11 Python
Python拼接字符串的7种方法总结
2018/11/01 Python
python 实现将list转成字符串,中间用空格隔开
2019/12/25 Python
matplotlib对象拾取事件处理的实现
2021/01/14 Python
使用CSS3来制作消息提醒框
2015/07/12 HTML / CSS
HTML页面中添加Canvas标签示例
2015/01/01 HTML / CSS
Evisu官方网站:日本牛仔品牌,时尚街头设计风格
2016/12/30 全球购物
Pretty Little Thing爱尔兰:时尚女性服饰
2017/03/27 全球购物
Omio荷兰:预订火车、巴士和机票
2018/11/04 全球购物
编写一个类体现构造,公有,私有方法,静态,私有变量
2013/08/10 面试题
中秋节礼品促销方案
2014/02/02 职场文书
日语专业个人求职信范文
2014/02/02 职场文书
个人委托书范本
2014/09/13 职场文书
作风转变年心得体会
2014/10/22 职场文书
入股协议书范本
2014/11/01 职场文书
公司庆典欢迎词
2015/01/26 职场文书
python批量更改目录名/文件名的方法
2021/04/18 Python