django-I18n-国际化语言

发布在 Django

上一篇文章提到了django 的语言问题,查阅资料后发现刚才的解释不是十分准确,看到一篇介绍相关内容的博客感觉不错,节选部分全文

先来看两个概念:

  • 国际化:是指为了该软件在任何地区的潜在使用而进行程序设计的过程。 它包括了为将来翻译而标记的文本(比如用户界面要素和错误信息等)、日期和时间的抽象显示以便保证不同地区的标准得到遵循、为不同时区提供支持,并且一般 确保代码中不会存在关于使用者所在地区的假设。 您会经常看到国际化被缩写为“I18N” (18表示Internationlization这个单词首字母I和结尾字母N之间的字母有18个)。
  • 本地化: 是指使一个国际化的程序为了在某个特定地区使用而进行实际翻译的过程。 有时,本地化缩写为L10N 。

使用Django 国际化

  1. 第一步:在你的Python代码和模板中嵌入待翻译的字符串。
  2. 第二步:把那些字符串翻译成你要支持的语言。
  3. 第三步:在你的Django settings文件中激活本地中间件。

如何嵌入待翻译的字符串

使用函数django.utils.translation.ugettext() 来指定一个翻译字符串。 作为惯例,使用短别名_来引入这个函数以节省键入时间.

1
2
3
4
from django.utils.translation import ugettext as _
def my_view(request):
output = _("Welcome to my site.")
return HttpResponse(output)

小注意:

  1. _ugettext()函数的参数可以是变量,但检测工具make_messages.py将找不到这些字符串。
  2. _占位符:特定语言的译文可能对翻译字符串重新排序,使用位置占位符可能达不到预期效果,建议使用命名字符串插入,如_('today is %(day)s'%{'day':'monday'})
  3. 本人补充——把ugettext函数重命名为下划线不是强制要求,但这样更符合惯例。

扩展知识:

  1. 使用 django.utils.translation.gettext_noop() 函数来标记一个不需要立即翻译的字符串。 这个串会稍后从变量翻译。使用这种方法的环境是,有字符串必须以原始语言的形式存储(如储存在数据库中的字符串)而在最后需要被翻译出来(如显示给用户时)。
  2. 使用 django.utils.translation.gettext_lazy() 函数,使得其中的值只有在访问时才会被翻译,而不是在gettext_lazy() 被调用时翻译。
  3. 使用django.utils.translation.ungettext()来指定以复数形式表示的消息。

模块中嵌入翻译字符串

Django模板使用两种模板标签,为了使得模板访问到标签,需要将

1
{% load i18n %}

放在模板最前面。这个

1
{% trans %}

模板标记翻译一个常量字符串 或 可变内容:

1
2
3
{%load i18n%}
<title>{%trans 'this is a title' %}</title>
<title>{%trans strvar %}</title>

小注意:

在一个带

1
{% trans %}

的字符串中,混进一个模板变量是不可能的。如果译文要求字符串带有变量,使用

1
2
{%blocktrans%}
{%endblocktrans%}

评论和分享

django-groundwork,它不实现具体的功能,而是扩展了manage.py 的命令,使得通过命令行可以生成一些代码/文件。根据你的模型自动生成模板、view、url等。 将下载好的groundwork放到与APP同级的目录,在setting.py 中添加'django-groundwork'

网上流传的都不太适合我使用的1.5.3版本,所以个人对其进行了小修改。

groundwork.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from django.core.management.base import BaseCommand, CommandError
from django.db import models
from placeholders import *
import os
class Command(BaseCommand):
def handle(self, *args, **options):
"Usage : manage.py groundwork <app> <model>"
PROJECT_ROOT = os.getcwd()+r'/'+args[0]
PROJECT_MROOT = os.getcwd()
TEMPLATE_DIR = os.path.join ( PROJECT_ROOT , 'templates')
print PROJECT_ROOT
print TEMPLATE_DIR
try:
app = args[1] # App name is the first parameter
model_names = args[2:] # Models which need to be scaffolded will follow
model_instances = [ models.get_model(app, x) for x in model_names ]
# url config
urls = URL_IMPORTS
# Generate CRUD urls for each model
for model_instance in model_instances:
urls += URL_CRUD_CONFIG % {'model':model_instance._meta.object_name.lower(), 'modelClass': model_instance._meta.object_name }
urls += URL_END
# write to urls.py
f = open( os.path.join (PROJECT_MROOT , app, 'urls.py') , 'w')
f.write(urls)
f.close()
# append to root urlconf
f = open( os.path.join (PROJECT_ROOT , 'urls.py') , 'a')
f.write( "nurlpatterns += patterns ('',n (r'^%(app)s/', include('%(app)s.urls')),n)n" % {'app': app } )
f.close()
# forms
forms_content = FORMS_IMPORTS
print forms_content
for model_instance in model_instances:
forms_content += FORMS_MODELFORM_CONFIG % { 'modelClass' : model_instance._meta.object_name }
formspath = os.path.join (PROJECT_MROOT, app, 'forms.py')
f = open( formspath , 'w')
f.write(forms_content)
f.close()
# views
views_content = VIEWS_IMPORTS
for model_instance in model_instances:
views_content += VIEWS_CREATE
views_content += VIEWS_LIST
views_content += VIEWS_VIEW
views_content += VIEWS_UPDATE
views_content = views_content % {'model':model_instance._meta.object_name.lower(), 'modelClass': model_instance._meta.object_name, 'app': app }
# write to views.py
viewspath = os.path.join (PROJECT_MROOT, app, 'views.py')
f = open( viewspath, 'w')
f.write(views_content)
f.close()
# Templates
template_dir = os.path.join(TEMPLATE_DIR, app )
if not os.path.exists(template_dir):
os.makedirs(template_dir)
print "Generate base template? [Y/N]?"
yn = raw_input()
if yn.lower() == 'y':
f = open(os.path.join(TEMPLATE_DIR, 'base.html') , 'w')
f.write(TEMPLATES_BASE)
f.close()
for model_instance in model_instances:
f = open(os.path.join( TEMPLATE_DIR, app, 'create_%s.html' % (model_instance._meta.object_name.lower()) ) ,'w')
f.write( TEMPLATES_CREATE % { 'modelClass' : model_instance._meta.object_name } )
f.close()
f = open(os.path.join( TEMPLATE_DIR, app, 'list_%s.html' % (model_instance._meta.object_name.lower()) ) ,'w')
f.write( TEMPLATES_LIST % { 'modelClass' : model_instance._meta.object_name ,'model' : model_instance._meta.object_name.lower(), 'app' : app} )
f.close()
f = open(os.path.join( TEMPLATE_DIR, app, 'edit_%s.html' % (model_instance._meta.object_name.lower()) ) ,'w')
f.write( TEMPLATES_EDIT % { 'modelClass' : model_instance._meta.object_name } )
f.close()
f = open(os.path.join( TEMPLATE_DIR, app, 'view_%s.html' % (model_instance._meta.object_name.lower()) ) , 'w')
f.write( TEMPLATES_VIEW % { 'modelClass' : model_instance._meta.object_name, 'model' : model_instance._meta.object_name.lower()} )
f.close()
# settings
f = open(os.path.join(PROJECT_ROOT, 'settings.py'), 'a')
f.write( "nimport osnTEMPLATE_DIRS += (os.path.join( os.path.dirname(__file__), 'templates') ,)n")
f.close()
except:
print "Usage : manage.py groundwork <app> <model>"

placeholders.py(1.5以后版本<herf url后面的view必须用引号引起来):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
URL_IMPORTS = """
from django.conf.urls.defaults import *
from models import *
from views import *
urlpatterns = patterns('',
"""
URL_CRUD_CONFIG = """
(r'%(model)s/create/$', create_%(model)s),
(r'%(model)s/list/$', list_%(model)s ),
(r'%(model)s/edit/(?P<id>[^/]+)/$', edit_%(model)s),
(r'%(model)s/view/(?P<id>[^/]+)/$', view_%(model)s),
"""
URL_END = """
)
"""
# --------------------- #
# forms.py file section #
# --------------------- #
FORMS_IMPORTS = """
from django import forms
from models import *
"""
FORMS_MODELFORM_CONFIG = """
class %(modelClass)sForm(forms.ModelForm):
class Meta:
model = %(modelClass)s
# exclude = [] # uncomment this line and specify any field to exclude it from the form
def __init__(self, *args, **kwargs):
super(%(modelClass)sForm, self).__init__(*args, **kwargs)
"""
# --------------------- #
# views.py file section #
# --------------------- #
VIEWS_IMPORTS = """
# Create your views here.
from django import forms
from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
from django.template.loader import get_template
from django.core.paginator import Paginator
from django.core.urlresolvers import reverse
# app specific files
from models import *
from forms import *
"""
VIEWS_CREATE = """
def create_%(model)s(request):
form = %(modelClass)sForm(request.POST or None)
if form.is_valid():
form.save()
form = %(modelClass)sForm()
t = get_template('%(app)s/create_%(model)s.html')
c = RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
VIEWS_LIST = """
def list_%(model)s(request):
list_items = %(modelClass)s.objects.all()
paginator = Paginator(list_items ,10)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
list_items = paginator.page(page)
except :
list_items = paginator.page(paginator.num_pages)
t = get_template('%(app)s/list_%(model)s.html')
c = RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
VIEWS_UPDATE = """
def edit_%(model)s(request, id):
%(model)s_instance = %(modelClass)s.objects.get(id=id)
form = %(modelClass)sForm(request.POST or None, instance = %(model)s_instance)
if form.is_valid():
form.save()
t=get_template('%(app)s/edit_%(model)s.html')
c=RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
VIEWS_VIEW = """
def view_%(model)s(request, id):
%(model)s_instance = %(modelClass)s.objects.get(id = id)
t=get_template('%(app)s/view_%(model)s.html')
c=RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
# ------------------------- #
# templates.py file section #
# ------------------------- #
TEMPLATES_CREATE = """
{%% extends "base.html" %%}
{%% block title %%} %(modelClass)s - Create {%% endblock %%}
{%% block heading %%}<h1> %(modelClass)s - Create </h1> {%% endblock %%}
{%% block content %%}
<table>
<form action="" method="POST"> {%% csrf_token %%}
{{form}}
<tr>
<td colspan="2" align="right"><input type="submit" value="Create"/></td>
</tr>
</form>
</table>
{%% endblock %%}
"""
TEMPLATES_LIST = """
{%% extends "base.html" %%}
{%% block title %%} <h1> %(modelClass)s </h1><h2> List </h2> {%% endblock %%}
{%% block heading %%}
<h1> %(modelClass)s</h1>
<h2> List Records</h2>
{%% endblock %%}
{%% block content %%}
<table>
<thead>
<tr><th>Record</th><th colspan="3">Actions</th></tr>
{%% for item in list_items.object_list %%}
<tr><td> {{item}}</td> <td><a href="{%% url "%(app)s.views.view_%(model)s" item.id %%}">Show</a> </td> <td><a href="{%% url "%(app)s.views.edit_%(model)s" item.id %%}">Edit</a></tr>
{%% endfor %%}
<tr><td colspan="3"> <a href="{%% url "%(app)s.views.create_%(model)s" %%}">Add New</a></td></tr>
</table>
<div align="center">
{%% if list_items.has_previous %%}
<a href="?page={{ list_items.previous_page_number }}">Previous</a>
{%% endif %%}
<span class="current">
Page {{ list_items.number }} of {{ list_items.paginator.num_pages }}.
</span>
{%% if list_items.has_next %%}
<a href="?page={{ list_items.next_page_number }}">Next</a>
{%% endif %%}
</div>
{%% endblock %%}
"""
TEMPLATES_EDIT = """
{%% extends "base.html" %%}
{%% block title %%} %(modelClass)s - Edit {%% endblock %%}
{%% block heading %%} <h1> %(modelClass)s</h1><h2> Edit </h2> {%% endblock %%}
{%% block content %%}
<table>
<form action="" method="POST"> {%% csrf_token %%}
{{form}}
<tr>
<td colspan="2" align="right"><input type="submit" value="Save"/></td>
</tr>
</form>
</table>
{%% endblock %%}
"""
TEMPLATES_VIEW = """
{%% extends "base.html" %%}
{%% block title %%} %(modelClass)s - View {%% endblock %%}
{%% block heading %%} <h1> %(modelClass)s</h1><h2>View</h2> {%% endblock %%}
{%% block content %%}
<table>
{{ %(model)s_instance }}
</table>
{%% endblock %%}
"""
TEMPLATES_BASE = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta name="description" content=""/>
<meta name="keywords" content="" />
<meta name="author" content="" />
<title>
{% block title %} {% endblock %}
</title>
<style type="text/css">
html * { padding:0; margin:0; }
body * { padding:10px 20px; }
body * * { padding:0; }
body { font:small sans-serif; }
body>div { border-bottom:1px solid #ddd; }
h1 { font-weight:normal; }
h2 { margin-bottom:.8em; }
h2 span { font-size:80% ; color:#666; font-weight:normal; }
h3 { margin:1em 0 .5em 0; }
h4 { margin:0 0 .5em 0; font-weight: normal; }
td {font-size:1em; padding:3px 17px 2px 17px;}
ul { margin-left: 2em; margin-top: 1em; }
#summary { background: #e0ebff; }
#summary h2 { font-weight: normal; color: #666; }
#explanation { background:#eee; }
#content { background:#f6f6f6; }
#summary table { border:none; background:transparent; }
</style>
</head>
<body>
<div id="summary">
{% block heading %}
{% endblock %}
</div>
<div id="content">
{% block content %}
{% endblock %}
</div>
<div id="explanation" align="center">
django-groundwork
</div>
</body>
</html>
"""

安装后,使用python manage.py help可以看到,列出的可用命令中多了一个groundwork。其语法是:

1
python manage.py groundwork appname ModelName1 ModelName2

修改后:

1
python manage.py groundwork projectname appname ModelName1 ModelName2

此时运行开发服务器(python manage.py runserver),就可以访问下面的地址:

http://localhost:8000/appname/ModelName/list/访问ModelName列表,并链接到create,edit,view等界面。

注意,用此APP需要先定义好模型,否则后面每次使用时候都会在setting.py中添加冗余数据。

评论和分享

django版本更换

发布在 Django

如果你打算从过去的一个版本升级Django, 你需要先删除老版本的Django之后, 再安装新的版本.

如果你是通过执行命令 setup.py install 来安装 Django, 卸载的方法很简单,

只要在site-packages 目录下删除 django 目录就可以了.

如果你使用 Python egg 来安装 Django, 直接删除 Django .egg 文件,

并且删除 easy-install.pth中的 egg 引用就可以了.

这个文件应当可以在 site-packages 目录中被找到…

如何找到 site-packages 目录?

site-packages 目录的位置取决于使用何种操作系统以及 Python 的安装位置.

可以通过如下的命令来显示出 site-packages

python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

(注意,上面的命令请在shell 中执行,不是在 Python中执行.)

评论和分享

作者的图片

Roy

君以国士待我,我必以国士报君。


野生程序猿


China