自定义数据库字段

扩展默认的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. 《北京IT报道》你可以成为下一个《万万没有想到》?

    10一个月29当天上午,一位名为<北京IT报道>在视频短剧IT朋友谁快速刷新的互联网商业圈.这种制作粗糙.演员表情僵硬.安置赤裸网络剧,但对布局和内容因IT互联网从业者的生活,深受广大用户 ...

  2. 获取当前电脑的cpu使用率、内存使用率

    https://www.cnblogs.com/Chary/p/7771365.html http://www.cnblogs.com/zl1991/p/4679461.html 要关注几个类 Per ...

  3. Leetcode 237 Delete Node in a Linked List 链表

    如题 删除是要注意让现在的链表等于下一个链表的值 class Solution { public: void deleteNode(ListNode* node) { ListNode *nextno ...

  4. Linux 获得了其首款基于 RISC-V 的多核开源处理器

    去年,硅谷创业公司 SiFive 发布了首款开源 SoC(片上系统 System on a Chip),命名为 Freeform Everywhere 310.现在,该公司从嵌入式系统领先一步,发布了 ...

  5. matlab 深度学习

    0. 超参的定义 超参的定义直接使用结构体: opts.alpha = 1; opts.batchsize = 50; opts.numepoch = 5; 1. Autoencoder Train ...

  6. Emgu-WPF 激光雷达研究-移动物体跟踪

    原文:Emgu-WPF 激光雷达研究-移动物体跟踪 接前两篇博客: 激光雷达数据解析并绘制雷达图 https://blog.csdn.net/u013224722/article/details/80 ...

  7. 【C#】获取任意文件的缩略图

    原文:[C#]获取任意文件的缩略图 因为用shell取缩略图时,对于损坏的文件,读出来的图有黑边,所以就诞生了以下方法,不过这个效率要比用shell取的低3-4倍. 1.添加类WindowsThumb ...

  8. C# 读取大文件 (可以读取3GB大小的txt文件)

    原文:C# 读取大文件 (可以读取3GB大小的txt文件) 在处理大数据时,有可能 会碰到 超过3GB大小的文件,如果通过 记事本 或 NotePad++去打开它,会报错,读不到任何文件. 如果你只是 ...

  9. 图像滤镜艺术---(Instagram)1977滤镜

    原文:图像滤镜艺术---(Instagram)1977滤镜 图像特效---(Instagram)1977滤镜 本文介绍1977这个滤镜的具体实现,这个滤镜最早是Instagram中使用的 ,由于Ins ...

  10. UWP入门(十二)--数据绑定用法

    原文:UWP入门(十二)--数据绑定用法 主要几个元素: Template DataTemplate ItemSource 数据绑定是一个数据提取的方法,能使数据和UI上的控件紧密相连,下面的Demo ...