自定义数据库字段

扩展默认的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实现多语言的更多相关文章

  1. 【读书笔记】C#高级编程 第十二章 动态语言扩展

    (一)DLR C#4的动态功能是Dynamic Language Runtime(动态语言运行时,DLR)的一部分.DLR是添加到CLR的一系列服务. (二)dynamic类型 dynamic类型允许 ...

  2. python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API

    python  Django教程  之 模型(数据库).自定义Field.数据表更改.QuerySet API 一.Django 模型(数据库) Django 模型是与数据库相关的,与数据库相关的代码 ...

  3. Django之路:模型(数据库)和自定义Field以及数据表的更改

    一.Django 模型(数据库) Django模型是与数据库相关的,与数据库相关的代码一般写在models.py中,Django支持sqlite3,MySQL,PostgreSQL等数据库,只需要在s ...

  4. C# 6 与 .NET Core 1.0 高级编程 - 39 章 Windows 服务(上)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 39 章 Windows 服务(上)),不对的地方欢迎指出与交流. 章节出自<Professional C ...

  5. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

  6. 2018.6.19 Java核心API与高级编程实践复习总结

    Java 核心编程API与高级编程实践 第一章 异常 1.1 异常概述 在程序运行中,经常会出现一些意外情况,这些意外会导致程序出错或者崩溃而影响程序的正常执行,在java语言中,将这些程序意外称为异 ...

  7. 读《C#高级编程》第1章问题

    读<C#高级编程>第1章 .Net机构体系笔记 网红的话:爸爸说我将来会是一个牛逼的程序员,因为我有一个梦,虽然脑壳笨但是做事情很能坚持. 本章主要是了解.Net的结构,都是一些概念,并没 ...

  8. 《C#高级编程》读书笔记

    <C#高级编程>读书笔记 C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) sh ...

  9. jquery插件开发继承了jQuery高级编程思路

    要说jQuery 最成功的地方,我认为是它的可扩展性吸引了众多开发者为其开发插件,从而建立起了一个生态系统.这好比大公司们争相做平台一样,得平台者得天下.苹果,微软,谷歌等巨头,都有各自的平台及生态圈 ...

随机推荐

  1. 使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题

    原文 使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题 虽然微软宣称 Windows 10 将是最后一个 Windows 版本,但由于年代跨越 ...

  2. Multi-tasking RTOS for microprocessors with limited memory by saving only a single return address per task during context switching

    A real-time operating system (RTOS) for use with minimal-memory controllers has a kernel for managin ...

  3. android网络开源框架volley(五岁以下儿童)——volley一些细节

    最近的一次volley整理出下一个.我以前没有再次遭遇了一些小问题,在该记录: 1.HttpUrlConnection DELETE 信息不能加入body问题:java.net.ProtocolExc ...

  4. 嵌入式OS入门注意事项-同RTX案件:九.关于优先-翻转,继承和天花板

    嵌入式OS入门注意事项-同RTX案件:九.关于优先-翻转,继承和天花板 涉及当调度优先级,会有很多问题,本文中,优先调度和一些战略的主要问题,以应付. 有几个概念如下:(priority invers ...

  5. WPF中用于嵌入其他进程窗口的自定义控件(AppContainer)

    原文:WPF中用于嵌入其他进程窗口的自定义控件(AppContainer) 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199 ...

  6. 不得不说,我太佩服node了,连openXML也搞定了!

    https://github.com/Ziv-Barber/officegen 开源项目地址 使用报告等有空完成!

  7. js,css引用顺序设定

    遇到的困难 在ASP .NET MVC里面,会使用_Layout.cshtml来绘制一些全局的公共页面,以及引用相关的css和js而在每个独立的页面中,也有自己独立的js一般来说,希望公共的js放在独 ...

  8. WPF Path.Data 后台代码赋值

    Path path = new Path(); string sData = "M 250,40 L200,20 L200,60 Z"; var converter = TypeD ...

  9. git/github初级运用自如 (good)

    三 . 设置用户信息 这一步不是很重要,貌似不设置也行,但github官方步骤中有,所以这里也提一下. 在git中设置用户名,邮箱 $ git config --global user.name &q ...

  10. WPF中的PathAnimation(路径动画)

    原文:WPF中的PathAnimation(路径动画) WPF中的PathAnimation(路径动画)                                                 ...