1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

Merged revisions 6442-6524 via svnmerge from [repos:django/trunk trunk].

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6525 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-10-16 16:54:23 +00:00
parent ba9fa9844c
commit 58fc789765
33 changed files with 218 additions and 156 deletions

View File

@ -313,7 +313,7 @@ answer newbie questions, and generally made Django that much better:
Vlado <vlado@labath.org> Vlado <vlado@labath.org>
Milton Waddams Milton Waddams
wam-djangobug@wamber.net wam-djangobug@wamber.net
wangchun <yaohua2000@gmail.com> Wang Chun <wangchun@exoweb.net>
Filip Wasilewski <filip.wasilewski@gmail.com> Filip Wasilewski <filip.wasilewski@gmail.com>
Dan Watson <http://theidioteque.net/> Dan Watson <http://theidioteque.net/>
Chris Wesseling <Chris.Wesseling@cwi.nl> Chris Wesseling <Chris.Wesseling@cwi.nl>

View File

@ -14,7 +14,8 @@ def compile_messages(locale=None):
basedirs = [os.path.join('conf', 'locale'), 'locale'] basedirs = [os.path.join('conf', 'locale'), 'locale']
if os.environ.get('DJANGO_SETTINGS_MODULE'): if os.environ.get('DJANGO_SETTINGS_MODULE'):
from django.conf import settings from django.conf import settings
basedirs += settings.LOCALE_PATHS if hasattr(settings, 'LOCALE_PATHS'):
basedirs += settings.LOCALE_PATHS
# Gather existing directories. # Gather existing directories.
basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs))) basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs)))

View File

@ -74,59 +74,62 @@ def make_messages():
if os.path.exists(potfile): if os.path.exists(potfile):
os.unlink(potfile) os.unlink(potfile)
all_files = []
for (dirpath, dirnames, filenames) in os.walk("."): for (dirpath, dirnames, filenames) in os.walk("."):
for file in filenames: all_files.extend([(dirpath, f) for f in filenames])
if domain == 'djangojs' and file.endswith('.js'): all_files.sort()
if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) for dirpath, file in all_files:
if domain == 'djangojs' and file.endswith('.js'):
if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
src = open(os.path.join(dirpath, file), "rb").read()
src = pythonize_re.sub('\n#', src)
open(os.path.join(dirpath, '%s.py' % file), "wb").write(src)
thefile = '%s.py' % file
cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
(stdin, stdout, stderr) = os.popen3(cmd, 't')
msgs = stdout.read()
errors = stderr.read()
if errors:
print "errors happened while running xgettext on %s" % file
print errors
sys.exit(8)
old = '#: '+os.path.join(dirpath, thefile)[2:]
new = '#: '+os.path.join(dirpath, file)[2:]
msgs = msgs.replace(old, new)
if msgs:
open(potfile, 'ab').write(msgs)
os.unlink(os.path.join(dirpath, thefile))
elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')):
thefile = file
if file.endswith('.html'):
src = open(os.path.join(dirpath, file), "rb").read() src = open(os.path.join(dirpath, file), "rb").read()
src = pythonize_re.sub('\n#', src)
open(os.path.join(dirpath, '%s.py' % file), "wb").write(src)
thefile = '%s.py' % file thefile = '%s.py' % file
cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( open(os.path.join(dirpath, thefile), "wb").write(templatize(src))
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) if verbose:
(stdin, stdout, stderr) = os.popen3(cmd, 't') sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
msgs = stdout.read() cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
errors = stderr.read() domain, os.path.join(dirpath, thefile))
if errors: (stdin, stdout, stderr) = os.popen3(cmd, 't')
print "errors happened while running xgettext on %s" % file msgs = stdout.read()
print errors errors = stderr.read()
sys.exit(8) if errors:
print "errors happened while running xgettext on %s" % file
print errors
sys.exit(8)
if thefile != file:
old = '#: '+os.path.join(dirpath, thefile)[2:] old = '#: '+os.path.join(dirpath, thefile)[2:]
new = '#: '+os.path.join(dirpath, file)[2:] new = '#: '+os.path.join(dirpath, file)[2:]
msgs = msgs.replace(old, new) msgs = msgs.replace(old, new)
if msgs: if os.path.exists(potfile):
open(potfile, 'ab').write(msgs) # Strip the header
msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
else:
msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
if msgs:
open(potfile, 'ab').write(msgs)
if thefile != file:
os.unlink(os.path.join(dirpath, thefile)) os.unlink(os.path.join(dirpath, thefile))
elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')):
thefile = file
if file.endswith('.html'):
src = open(os.path.join(dirpath, file), "rb").read()
thefile = '%s.py' % file
open(os.path.join(dirpath, thefile), "wb").write(templatize(src))
if verbose:
sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
domain, os.path.join(dirpath, thefile))
(stdin, stdout, stderr) = os.popen3(cmd, 't')
msgs = stdout.read()
errors = stderr.read()
if errors:
print "errors happened while running xgettext on %s" % file
print errors
sys.exit(8)
if thefile != file:
old = '#: '+os.path.join(dirpath, thefile)[2:]
new = '#: '+os.path.join(dirpath, file)[2:]
msgs = msgs.replace(old, new)
if os.path.exists(potfile):
# Strip the header
msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
else:
msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
if msgs:
open(potfile, 'ab').write(msgs)
if thefile != file:
os.unlink(os.path.join(dirpath, thefile))
if os.path.exists(potfile): if os.path.exists(potfile):
(stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%s"' % potfile, 'b') (stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%s"' % potfile, 'b')

View File

@ -1,6 +1,7 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Translation of django.po to German
# This file is distributed under the same license as the PACKAGE package. #
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # Copyright (C) 2005-2007,
# This file is distributed under the same license as the django package.
# #
msgid "" msgid ""
"" ""
@ -1629,76 +1630,76 @@ msgstr "Webseite"
msgid "flat pages" msgid "flat pages"
msgstr "Webseiten" msgstr "Webseiten"
#: contrib/humanize/templatetags/humanize.py:17 #: contrib/humanize/templatetags/humanize.py:20
msgid "th" msgid "th"
msgstr "" msgstr "."
#: contrib/humanize/templatetags/humanize.py:17 #: contrib/humanize/templatetags/humanize.py:20
msgid "st" msgid "st"
msgstr "" msgstr "."
#: contrib/humanize/templatetags/humanize.py:17 #: contrib/humanize/templatetags/humanize.py:20
msgid "nd" msgid "nd"
msgstr "" msgstr "."
#: contrib/humanize/templatetags/humanize.py:17 #: contrib/humanize/templatetags/humanize.py:20
msgid "rd" msgid "rd"
msgstr "" msgstr "."
#: contrib/humanize/templatetags/humanize.py:47
#, python-format
msgid "%(value).1f million"
msgid_plural "%(value).1f million"
msgstr[0] ""
msgstr[1] ""
#: contrib/humanize/templatetags/humanize.py:50 #: contrib/humanize/templatetags/humanize.py:50
#, python-format #, python-format
msgid "%(value).1f billion" msgid "%(value).1f million"
msgid_plural "%(value).1f billion" msgid_plural "%(value).1f million"
msgstr[0] "" msgstr[0] "%(value).1f Million"
msgstr[1] "" msgstr[1] "%(value).1f Millionen"
#: contrib/humanize/templatetags/humanize.py:53 #: contrib/humanize/templatetags/humanize.py:53
#, python-format #, python-format
msgid "%(value).1f billion"
msgid_plural "%(value).1f billion"
msgstr[0] "%(value).1f Milliarde"
msgstr[1] "%(value).1f Milliarden"
#: contrib/humanize/templatetags/humanize.py:56
#, python-format
msgid "%(value).1f trillion" msgid "%(value).1f trillion"
msgid_plural "%(value).1f trillion" msgid_plural "%(value).1f trillion"
msgstr[0] "" msgstr[0] "%(value).1f Billion"
msgstr[1] "" msgstr[1] "%(value).1f Billionen"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "one" msgid "one"
msgstr "ein" msgstr "ein"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "two" msgid "two"
msgstr "zwei" msgstr "zwei"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "three" msgid "three"
msgstr "drei" msgstr "drei"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "four" msgid "four"
msgstr "vier" msgstr "vier"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "five" msgid "five"
msgstr "fünf" msgstr "fünf"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "six" msgid "six"
msgstr "sechs" msgstr "sechs"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "seven" msgid "seven"
msgstr "sieben" msgstr "sieben"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "eight" msgid "eight"
msgstr "acht" msgstr "acht"
#: contrib/humanize/templatetags/humanize.py:68 #: contrib/humanize/templatetags/humanize.py:71
msgid "nine" msgid "nine"
msgstr "neun" msgstr "neun"

View File

@ -14,7 +14,7 @@ import os
class ModPythonRequest(http.HttpRequest): class ModPythonRequest(http.HttpRequest):
def __init__(self, req): def __init__(self, req):
self._req = req self._req = req
self.path = force_unicode(req.uri) self.path = force_unicode(req.uri, errors='ignore')
def __repr__(self): def __repr__(self):
# Since this is called as part of error handling, we need to be very # Since this is called as part of error handling, we need to be very

View File

@ -75,7 +75,7 @@ def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0):
class WSGIRequest(http.HttpRequest): class WSGIRequest(http.HttpRequest):
def __init__(self, environ): def __init__(self, environ):
self.environ = environ self.environ = environ
self.path = force_unicode(environ['PATH_INFO']) self.path = force_unicode(environ['PATH_INFO'], errors='ignore')
self.META = environ self.META = environ
self.method = environ['REQUEST_METHOD'].upper() self.method = environ['REQUEST_METHOD'].upper()

View File

@ -239,7 +239,7 @@ def setup_environ(settings_mod):
project_directory, settings_filename = os.path.split(settings_mod.__file__) project_directory, settings_filename = os.path.split(settings_mod.__file__)
project_name = os.path.basename(project_directory) project_name = os.path.basename(project_directory)
settings_name = os.path.splitext(settings_filename)[0] settings_name = os.path.splitext(settings_filename)[0]
sys.path.append(os.path.join(project_directory, '..')) sys.path.append(os.path.join(project_directory, os.pardir))
project_module = __import__(project_name, {}, {}, ['']) project_module = __import__(project_name, {}, {}, [''])
sys.path.pop() sys.path.pop()

View File

@ -1,10 +1,10 @@
import os
import sys
from optparse import make_option, OptionParser
import django import django
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style from django.core.management.color import color_style
import itertools
from optparse import make_option, OptionParser
import sys
import os
class CommandError(Exception): class CommandError(Exception):
pass pass
@ -19,7 +19,7 @@ def handle_default_options(options):
os.environ['DJANGO_SETTINGS_MODULE'] = options.settings os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
if options.pythonpath: if options.pythonpath:
sys.path.insert(0, options.pythonpath) sys.path.insert(0, options.pythonpath)
class BaseCommand(object): class BaseCommand(object):
# Metadata about this command. # Metadata about this command.
option_list = ( option_list = (
@ -161,17 +161,25 @@ class NoArgsCommand(BaseCommand):
args = '' args = ''
def handle(self, *args, **options): def handle(self, *args, **options):
from django.db import models if args:
if len(args) != 0:
raise CommandError("Command doesn't accept any arguments") raise CommandError("Command doesn't accept any arguments")
return self.handle_noargs(**options) return self.handle_noargs(**options)
def handle_noargs(self, **options): def handle_noargs(self, **options):
raise NotImplementedError() raise NotImplementedError()
def copy_helper(style, app_or_project, name, directory, other_name=''): def copy_helper(style, app_or_project, name, directory, other_name=''):
import django """
Copies either a Django application layout template or a Django project
layout template into the specified directory.
* style - A color style object (see django.core.management.color).
* app_or_project - The string 'app' or 'project'.
* name - The name of the application or project.
* directory - The directory to copy the layout template to.
* other_name - When copying an application layout, this should be the name
of the project.
"""
import re import re
import shutil import shutil
other = {'project': 'app', 'app': 'project'}[app_or_project] other = {'project': 'app', 'app': 'project'}[app_or_project]
@ -221,4 +229,3 @@ def _make_writeable(filename):
st = os.stat(filename) st = os.stat(filename)
new_permissions = stat.S_IMODE(st.st_mode) | stat.S_IWUSR new_permissions = stat.S_IMODE(st.st_mode) | stat.S_IWUSR
os.chmod(filename, new_permissions) os.chmod(filename, new_permissions)

View File

@ -2,12 +2,14 @@
Sets up the terminal color scheme. Sets up the terminal color scheme.
""" """
from django.utils import termcolors
import sys import sys
from django.utils import termcolors
def color_style(): def color_style():
"Returns a Style object with the Django color scheme." """Returns a Style object with the Django color scheme."""
if sys.platform == 'win32' or sys.platform == 'Pocket PC' or sys.platform.startswith('java') or not sys.stdout.isatty(): if (sys.platform == 'win32' or sys.platform == 'Pocket PC'
or sys.platform.startswith('java') or not sys.stdout.isatty()):
return no_style() return no_style()
class dummy: pass class dummy: pass
style = dummy() style = dummy()
@ -21,7 +23,7 @@ def color_style():
return style return style
def no_style(): def no_style():
"Returns a Style object that has no colors." """Returns a Style object that has no colors."""
class dummy: class dummy:
def __getattr__(self, attr): def __getattr__(self, attr):
return lambda x: x return lambda x: x

View File

@ -20,7 +20,7 @@ class Command(BaseCommand):
import django import django
from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException
from django.core.handlers.wsgi import WSGIHandler from django.core.handlers.wsgi import WSGIHandler
if len(args) != 0: if args:
raise CommandError('Usage is runserver %s' % self.args) raise CommandError('Usage is runserver %s' % self.args)
if not addrport: if not addrport:
addr = '' addr = ''

View File

@ -16,7 +16,7 @@ class Command(LabelCommand):
directory = os.getcwd() directory = os.getcwd()
# Determine the project_name a bit naively -- by looking at the name of # Determine the project_name a bit naively -- by looking at the name of
# the parent directory. # the parent directory.
project_dir = os.path.normpath(os.path.join(directory, '..')) project_dir = os.path.normpath(os.path.join(directory, os.pardir))
parent_dir = os.path.basename(project_dir) parent_dir = os.path.basename(project_dir)
project_name = os.path.basename(directory) project_name = os.path.basename(directory)
if app_name == project_name: if app_name == project_name:

View File

@ -100,5 +100,5 @@ class DatabaseOperations(BaseDatabaseOperations):
style.SQL_FIELD(qn('id')), style.SQL_FIELD(qn('id')),
style.SQL_KEYWORD('IS NOT'), style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'), style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table()))) style.SQL_TABLE(qn(f.m2m_db_table()))))
return output return output

View File

@ -238,7 +238,7 @@ class Field(object):
if self.default is not NOT_PROVIDED: if self.default is not NOT_PROVIDED:
if callable(self.default): if callable(self.default):
return self.default() return self.default()
return self.default return force_unicode(self.default, strings_only=True)
if not self.empty_strings_allowed or (self.null and settings.DATABASE_ENGINE != 'oracle'): if not self.empty_strings_allowed or (self.null and settings.DATABASE_ENGINE != 'oracle'):
return None return None
return "" return ""

View File

@ -47,8 +47,9 @@ class HttpRequest(object):
def get_host(self): def get_host(self):
"Returns the HTTP host using the environment or request headers." "Returns the HTTP host using the environment or request headers."
# We try three options, in order of decreasing preference. # We try three options, in order of decreasing preference.
host = self.META.get('HTTP_X_FORWARDED_HOST', '') if 'HTTP_X_FORWARDED_HOST' in self.META:
if 'HTTP_HOST' in self.META: host = self.META['HTTP_X_FORWARDED_HOST']
elif 'HTTP_HOST' in self.META:
host = self.META['HTTP_HOST'] host = self.META['HTTP_HOST']
else: else:
# Reconstruct the host using the algorithm from PEP 333. # Reconstruct the host using the algorithm from PEP 333.

View File

@ -7,7 +7,9 @@ try:
except NameError: except NameError:
from sets import Set as set # Python 2.3 fallback from sets import Set as set # Python 2.3 fallback
import copy
from itertools import chain from itertools import chain
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
from django.utils.html import escape from django.utils.html import escape
from django.utils.translation import ugettext from django.utils.translation import ugettext
@ -32,6 +34,12 @@ class Widget(object):
else: else:
self.attrs = {} self.attrs = {}
def __deepcopy__(self, memo):
obj = copy.copy(self)
obj.attrs = self.attrs.copy()
memo[id(self)] = obj
return obj
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None):
""" """
Returns this Widget rendered as HTML, as a Unicode string. Returns this Widget rendered as HTML, as a Unicode string.
@ -88,7 +96,7 @@ class PasswordInput(Input):
input_type = 'password' input_type = 'password'
def __init__(self, attrs=None, render_value=True): def __init__(self, attrs=None, render_value=True):
self.attrs = attrs or {} super(PasswordInput, self).__init__(attrs)
self.render_value = render_value self.render_value = render_value
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None):
@ -105,8 +113,8 @@ class MultipleHiddenInput(HiddenInput):
of values. of values.
""" """
def __init__(self, attrs=None, choices=()): def __init__(self, attrs=None, choices=()):
super(MultipleHiddenInput, self).__init__(attrs)
# choices can be any iterable # choices can be any iterable
self.attrs = attrs or {}
self.choices = choices self.choices = choices
def render(self, name, value, attrs=None, choices=()): def render(self, name, value, attrs=None, choices=()):
@ -145,9 +153,9 @@ class Textarea(Widget):
class CheckboxInput(Widget): class CheckboxInput(Widget):
def __init__(self, attrs=None, check_test=bool): def __init__(self, attrs=None, check_test=bool):
super(CheckboxInput, self).__init__(attrs)
# check_test is a callable that takes a value and returns True # check_test is a callable that takes a value and returns True
# if the checkbox should be checked for that value. # if the checkbox should be checked for that value.
self.attrs = attrs or {}
self.check_test = check_test self.check_test = check_test
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None):
@ -164,7 +172,7 @@ class CheckboxInput(Widget):
class Select(Widget): class Select(Widget):
def __init__(self, attrs=None, choices=()): def __init__(self, attrs=None, choices=()):
self.attrs = attrs or {} super(Select, self).__init__(attrs)
# choices can be any iterable, but we may need to render this widget # choices can be any iterable, but we may need to render this widget
# multiple times. Thus, collapse it into a list so it can be consumed # multiple times. Thus, collapse it into a list so it can be consumed
# more than once. # more than once.
@ -203,8 +211,8 @@ class NullBooleanSelect(Select):
class SelectMultiple(Widget): class SelectMultiple(Widget):
def __init__(self, attrs=None, choices=()): def __init__(self, attrs=None, choices=()):
super(SelectMultiple, self).__init__(attrs)
# choices can be any iterable # choices can be any iterable
self.attrs = attrs or {}
self.choices = choices self.choices = choices
def render(self, name, value, attrs=None, choices=()): def render(self, name, value, attrs=None, choices=()):

View File

@ -500,7 +500,7 @@ class SelectField(FormField):
selected_html = u'' selected_html = u''
if smart_unicode(value) == str_data: if smart_unicode(value) == str_data:
selected_html = u' selected="selected"' selected_html = u' selected="selected"'
output.append(u' <option value="%s"%s>%s</option>' % (escape(value), selected_html, escape(display_name))) output.append(u' <option value="%s"%s>%s</option>' % (escape(value), selected_html, force_unicode(escape(display_name))))
output.append(u' </select>') output.append(u' </select>')
return u'\n'.join(output) return u'\n'.join(output)
@ -612,7 +612,7 @@ class SelectMultipleField(SelectField):
selected_html = u'' selected_html = u''
if smart_unicode(value) in str_data_list: if smart_unicode(value) in str_data_list:
selected_html = u' selected="selected"' selected_html = u' selected="selected"'
output.append(u' <option value="%s"%s>%s</option>' % (escape(value), selected_html, escape(choice))) output.append(u' <option value="%s"%s>%s</option>' % (escape(value), selected_html, force_unicode(escape(choice))))
output.append(u' </select>') output.append(u' </select>')
return u'\n'.join(output) return u'\n'.join(output)

View File

@ -54,7 +54,10 @@ class SortedDict(dict):
def __init__(self, data=None): def __init__(self, data=None):
if data is None: data = {} if data is None: data = {}
dict.__init__(self, data) dict.__init__(self, data)
self.keyOrder = data.keys() if isinstance(data, dict):
self.keyOrder = data.keys()
else:
self.keyOrder=[key for key, value in data]
def __setitem__(self, key, value): def __setitem__(self, key, value):
dict.__setitem__(self, key, value) dict.__setitem__(self, key, value)

View File

@ -2,6 +2,7 @@
Internationalization support. Internationalization support.
""" """
from django.utils.functional import lazy from django.utils.functional import lazy
from django.utils.encoding import force_unicode
__all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext', __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext',
'ngettext_lazy', 'string_concat', 'activate', 'deactivate', 'ngettext_lazy', 'string_concat', 'activate', 'deactivate',
@ -39,7 +40,7 @@ def delayed_loader(*args, **kwargs):
g['real_%s' % name] = getattr(trans, name) g['real_%s' % name] = getattr(trans, name)
# Make the originally requested function call on the way out the door. # Make the originally requested function call on the way out the door.
return g[caller](*args, **kwargs) return g['real_%s' % caller](*args, **kwargs)
g = globals() g = globals()
for name in __all__: for name in __all__:
@ -63,14 +64,10 @@ def ugettext(message):
def ungettext(singular, plural, number): def ungettext(singular, plural, number):
return real_ungettext(singular, plural, number) return real_ungettext(singular, plural, number)
def string_concat(*strings):
return real_string_concat(*strings)
ngettext_lazy = lazy(ngettext, str) ngettext_lazy = lazy(ngettext, str)
gettext_lazy = lazy(gettext, str) gettext_lazy = lazy(gettext, str)
ungettext_lazy = lazy(ungettext, unicode) ungettext_lazy = lazy(ungettext, unicode)
ugettext_lazy = lazy(ugettext, unicode) ugettext_lazy = lazy(ugettext, unicode)
string_concat = lazy(string_concat, unicode)
def activate(language): def activate(language):
return real_activate(language) return real_activate(language)
@ -108,3 +105,10 @@ def templatize(src):
def deactivate_all(): def deactivate_all():
return real_deactivate_all() return real_deactivate_all()
def string_concat(*strings):
"""
Lazy variant of string concatenation, needed for translations that are
constructed from multiple parts.
"""
return u''.join([force_unicode(s) for s in strings])
string_concat = lazy(string_concat, unicode)

View File

@ -13,7 +13,6 @@ ngettext_lazy = ngettext
def ungettext(singular, plural, number): def ungettext(singular, plural, number):
return force_unicode(ngettext(singular, plural, number)) return force_unicode(ngettext(singular, plural, number))
string_concat = lambda *strings: u''.join([force_unicode(el) for el in strings])
activate = lambda x: None activate = lambda x: None
deactivate = deactivate_all = install = lambda: None deactivate = deactivate_all = install = lambda: None
get_language = lambda: settings.LANGUAGE_CODE get_language = lambda: settings.LANGUAGE_CODE

View File

@ -516,9 +516,3 @@ def templatize(src):
out.write(blankout(t.contents, 'X')) out.write(blankout(t.contents, 'X'))
return out.getvalue() return out.getvalue()
def string_concat(*strings):
""""
Lazy variant of string concatenation, needed for translations that are
constructed from multiple parts.
"""
return u''.join([force_unicode(s) for s in strings])

View File

@ -1,6 +1,8 @@
from django.template import loader """
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified Views and functions for serving static files. These are only to be used
from django.template import Template, Context, TemplateDoesNotExist during development, and SHOULD NOT be used in a production setting.
"""
import mimetypes import mimetypes
import os import os
import posixpath import posixpath
@ -9,6 +11,10 @@ import rfc822
import stat import stat
import urllib import urllib
from django.template import loader
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified
from django.template import Template, Context, TemplateDoesNotExist
def serve(request, path, document_root=None, show_indexes=False): def serve(request, path, document_root=None, show_indexes=False):
""" """
Serve static files below a given point in the directory structure. Serve static files below a given point in the directory structure.
@ -29,12 +35,12 @@ def serve(request, path, document_root=None, show_indexes=False):
newpath = '' newpath = ''
for part in path.split('/'): for part in path.split('/'):
if not part: if not part:
# strip empty path components # Strip empty path components.
continue continue
drive, part = os.path.splitdrive(part) drive, part = os.path.splitdrive(part)
head, part = os.path.split(part) head, part = os.path.split(part)
if part in (os.curdir, os.pardir): if part in (os.curdir, os.pardir):
# strip '.' amd '..' in path # Strip '.' and '..' in path.
continue continue
newpath = os.path.join(newpath, part).replace('\\', '/') newpath = os.path.join(newpath, part).replace('\\', '/')
if newpath and path != newpath: if newpath and path != newpath:

View File

@ -175,9 +175,9 @@ operators. You will also need the `cx_Oracle`_ driver, version 4.3.1 or newer.
.. _`cx_Oracle`: http://cx-oracle.sourceforge.net/ .. _`cx_Oracle`: http://cx-oracle.sourceforge.net/
To run ``python manage.py syncdb``, you'll need to create an Oracle database To run ``python manage.py syncdb``, you'll need to create an Oracle database
user with CREATE TABLE, CREATE SEQUENCE, and CREATE PROCEDURE privileges. To user with CREATE TABLE, CREATE SEQUENCE, CREATE PROCEDURE, and CREATE TRIGGER
run Django's test suite, the user also needs CREATE and DROP DATABASE and privileges. To run Django's test suite, the user also needs
CREATE and DROP TABLESPACE privileges. CREATE and DROP DATABASE and CREATE and DROP TABLESPACE privileges.
Connecting to the Database Connecting to the Database
-------------------------- --------------------------

View File

@ -456,10 +456,13 @@ otherwise, they'll be tacked together without whitespace!
.. admonition:: Mind your charset .. admonition:: Mind your charset
When creating a ``.po`` file with your favorite text editor, first edit When creating a PO file with your favorite text editor, first edit
the charset line (search for ``"CHARSET"``) and set it to the charset the charset line (search for ``"CHARSET"``) and set it to the charset
you'll be using to edit the content. Generally, utf-8 should work for most you'll be using to edit the content. Due to the way the ``gettext`` tools
languages, but ``gettext`` should handle any charset you throw at it. work internally and because we want to allow non-ASCII source strings in
Django's core and your applications, you **must** use UTF-8 as the encoding
for your PO file (this means that everybody will be using the same
encoding, which is important when Django processes the PO files).
To reexamine all source code and templates for new translation strings and To reexamine all source code and templates for new translation strings and
update all message files for **all** languages, run this:: update all message files for **all** languages, run this::

View File

@ -2075,9 +2075,9 @@ More coming soon
================ ================
That's all the documentation for now. For more, see the file That's all the documentation for now. For more, see the file
http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms/tests.py http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms
-- the unit tests for ``django.newforms``. This can give you a good idea of -- the unit tests for ``django.newforms``. This can give you a good idea of
what's possible. what's possible. (Each submodule there contains separate tests.)
If you're really itching to learn and use this library, please be patient. If you're really itching to learn and use this library, please be patient.
We're working hard on finishing both the code and documentation. We're working hard on finishing both the code and documentation.

View File

@ -381,8 +381,8 @@ Methods
``mimetype``. Historically, the parameter was only called ``mimetype``, ``mimetype``. Historically, the parameter was only called ``mimetype``,
but since this is actually the value included in the HTTP ``Content-Type`` but since this is actually the value included in the HTTP ``Content-Type``
header, it can also include the character set encoding, which makes it header, it can also include the character set encoding, which makes it
more than just a MIME type specification. If ``mimetype`` is specifiedi more than just a MIME type specification. If ``mimetype`` is specified
(not None), that value is used. Otherwise, ``content_type`` is used. If (not None), that value is used. Otherwise, ``content_type`` is used. If
neither is given, the ``DEFAULT_CONTENT_TYPE`` setting is used. neither is given, the ``DEFAULT_CONTENT_TYPE`` setting is used.
``__setitem__(header, value)`` ``__setitem__(header, value)``

View File

@ -316,7 +316,7 @@ optional, third positional argument, ``processors``. In this example, the
}, [ip_address_processor]) }, [ip_address_processor])
return t.render(c) return t.render(c)
Note:: .. note::
If you're using Django's ``render_to_response()`` shortcut to populate a If you're using Django's ``render_to_response()`` shortcut to populate a
template with the contents of a dictionary, your template will be passed a template with the contents of a dictionary, your template will be passed a
``Context`` instance by default (not a ``RequestContext``). To use a ``Context`` instance by default (not a ``RequestContext``). To use a

View File

@ -110,19 +110,22 @@ Conversion functions
The ``django.utils.encoding`` module contains a few functions that are handy The ``django.utils.encoding`` module contains a few functions that are handy
for converting back and forth between Unicode and bytestrings. for converting back and forth between Unicode and bytestrings.
* ``smart_unicode(s, encoding='utf-8', errors='strict')`` converts its * ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')``
input to a Unicode string. The ``encoding`` parameter specifies the input converts its input to a Unicode string. The ``encoding`` parameter
encoding. (For example, Django uses this internally when processing form specifies the input encoding. (For example, Django uses this internally
input data, which might not be UTF-8 encoded.) The ``errors`` parameter when processing form input data, which might not be UTF-8 encoded.) The
takes any of the values that are accepted by Python's ``unicode()`` ``strings_only`` parameter, if set to True, will result in Python
function for its error handling. numbers, booleans and ``None`` not being converted to a string (they keep
their original types). The ``errors`` parameter takes any of the values
that are accepted by Python's ``unicode()`` function for its error
handling.
If you pass ``smart_unicode()`` an object that has a ``__unicode__`` If you pass ``smart_unicode()`` an object that has a ``__unicode__``
method, it will use that method to do the conversion. method, it will use that method to do the conversion.
* ``force_unicode(s, encoding='utf-8', errors='strict')`` is identical to * ``force_unicode(s, encoding='utf-8', strings_only=False, errors='strict')``
``smart_unicode()`` in almost all cases. The difference is when the is identical to ``smart_unicode()`` in almost all cases. The difference
first argument is a `lazy translation`_ instance. While is when the first argument is a `lazy translation`_ instance. While
``smart_unicode()`` preserves lazy translations, ``force_unicode()`` ``smart_unicode()`` preserves lazy translations, ``force_unicode()``
forces those objects to a Unicode string (causing the translation to forces those objects to a Unicode string (causing the translation to
occur). Normally, you'll want to use ``smart_unicode()``. However, occur). Normally, you'll want to use ``smart_unicode()``. However,
@ -132,11 +135,10 @@ for converting back and forth between Unicode and bytestrings.
* ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')`` * ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')``
is essentially the opposite of ``smart_unicode()``. It forces the first is essentially the opposite of ``smart_unicode()``. It forces the first
argument to a bytestring. The ``strings_only`` parameter, if set to True, argument to a bytestring. The ``strings_only`` parameter has the same
will result in Python integers, booleans and ``None`` not being behaviour as for ``smart_unicode()`` and ``force_unicode()``. This is
converted to a string (they keep their original types). This is slightly slightly different semantics from Python's builtin ``str()`` function,
different semantics from Python's builtin ``str()`` function, but the but the difference is needed in a few places within Django's internals.
difference is needed in a few places within Django's internals.
Normally, you'll only need to use ``smart_unicode()``. Call it as early as Normally, you'll only need to use ``smart_unicode()``. Call it as early as
possible on any input data that might be either Unicode or a bytestring, and possible on any input data that might be either Unicode or a bytestring, and

View File

@ -152,7 +152,7 @@ TypeError: 'foo' is an invalid keyword argument for this function
>>> a6 = Article(pub_date=datetime(2005, 7, 31)) >>> a6 = Article(pub_date=datetime(2005, 7, 31))
>>> a6.save() >>> a6.save()
>>> a6.headline >>> a6.headline
'Default headline' u'Default headline'
# For DateTimeFields, Django saves as much precision (in seconds) as you # For DateTimeFields, Django saves as much precision (in seconds) as you
# give it. # give it.

View File

@ -42,7 +42,7 @@ __test__ = {'API_TESTS':"""
# Access database columns via Python attributes. # Access database columns via Python attributes.
>>> a.headline >>> a.headline
'Default headline' u'Default headline'
# make sure the two dates are sufficiently close # make sure the two dates are sufficiently close
>>> d = now - a.pub_date >>> d = now - a.pub_date

View File

@ -55,6 +55,14 @@ True
>>> print repr(d) >>> print repr(d)
{'one': 'not one', 'two': 'two', 'three': 'three'} {'one': 'not one', 'two': 'two', 'three': 'three'}
Init from sequence of tuples
>>> d = SortedDict((
... (1, "one"),
... (0, "zero"),
... (2, "two")))
>>> print repr(d)
{1: 'one', 0: 'zero', 2: 'two'}
### DotExpandedDict ############################################################ ### DotExpandedDict ############################################################
>>> d = DotExpandedDict({'person.1.firstname': ['Simon'], 'person.1.lastname': ['Willison'], 'person.2.firstname': ['Adrian'], 'person.2.lastname': ['Holovaty']}) >>> d = DotExpandedDict({'person.1.firstname': ['Simon'], 'person.1.lastname': ['Willison'], 'person.2.firstname': ['Adrian'], 'person.2.lastname': ['Holovaty']})

View File

@ -0,0 +1,12 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
class TestModel(models.Model):
text = models.CharField(max_length=10, default=_('Anything'))
__test__ = {'API_TESTS': '''
>>> tm = TestModel()
>>> tm.save()
'''
}

View File

@ -30,4 +30,12 @@ True
>>> s4 = ugettext_lazy('Some other string') >>> s4 = ugettext_lazy('Some other string')
>>> s == s4 >>> s == s4
False False
unicode(string_concat(...)) should not raise a TypeError - #4796
>>> import django.utils.translation
>>> reload(django.utils.translation)
<module 'django.utils.translation' from ...>
>>> unicode(django.utils.translation.string_concat("dja", "ngo"))
u'django'
""" """