1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +00:00

i18n: merged r776:r786 from trunk

git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@787 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Georg Bauer 2005-10-06 10:04:07 +00:00
parent 04a66b6e55
commit cb09e10eb2
12 changed files with 70 additions and 45 deletions

View File

@ -42,9 +42,11 @@ LANGUAGES = (
# notifications and other various e-mails. # notifications and other various e-mails.
MANAGERS = ADMINS MANAGERS = ADMINS
# Default MIME type to use for all HttpResponse objects, if a MIME type # Default content type and charset to use for all HttpResponse objects, if a
# isn't manually specified. This is directly used as the Content-Type header. # MIME type isn't manually specified. These are used to construct the
DEFAULT_MIME_TYPE = 'text/html; charset=utf-8' # Content-Type header.
DEFAULT_CONTENT_TYPE = 'text/html'
DEFAULT_CHARSET = 'utf-8'
# E-mail address that error messages come from. # E-mail address that error messages come from.
SERVER_EMAIL = 'root@localhost' SERVER_EMAIL = 'root@localhost'
@ -110,6 +112,9 @@ ALLOWED_INCLUDE_ROOTS = ()
# is an admin. # is an admin.
ADMIN_FOR = [] ADMIN_FOR = []
# Whether to check the flat-pages table as a last resort for all 404 errors.
USE_FLAT_PAGES = True
# 404s that may be ignored. # 404s that may be ignored.
IGNORABLE_404_STARTS = ('/cgi-bin/', '/_vti_bin', '/_vti_inf') IGNORABLE_404_STARTS = ('/cgi-bin/', '/_vti_bin', '/_vti_inf')
IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', 'favicon.ico', '.php') IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', 'favicon.ico', '.php')

View File

@ -1,6 +1,7 @@
from django.core import validators from django.core import validators
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.utils.html import escape from django.utils.html import escape
from django.conf.settings import DEFAULT_CHARSET
FORM_FIELD_ID_PREFIX = 'id_' FORM_FIELD_ID_PREFIX = 'id_'
@ -221,7 +222,7 @@ class TextField(FormField):
self.validator_list = [self.isValidLength, self.hasNoNewlines] + validator_list self.validator_list = [self.isValidLength, self.hasNoNewlines] + validator_list
def isValidLength(self, data, form): def isValidLength(self, data, form):
if data and self.maxlength and len(data) > self.maxlength: if data and self.maxlength and len(data.decode(DEFAULT_CHARSET)) > self.maxlength:
raise validators.ValidationError, "Ensure your text is less than %s characters." % self.maxlength raise validators.ValidationError, "Ensure your text is less than %s characters." % self.maxlength
def hasNoNewlines(self, data, form): def hasNoNewlines(self, data, form):
@ -235,7 +236,7 @@ class TextField(FormField):
if self.maxlength: if self.maxlength:
maxlength = 'maxlength="%s" ' % self.maxlength maxlength = 'maxlength="%s" ' % self.maxlength
if isinstance(data, unicode): if isinstance(data, unicode):
data = data.encode('utf-8') data = data.encode(DEFAULT_CHARSET)
return '<input type="text" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \ return '<input type="text" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \
(FORM_FIELD_ID_PREFIX + self.field_name, self.__class__.__name__, self.is_required and ' required' or '', (FORM_FIELD_ID_PREFIX + self.field_name, self.__class__.__name__, self.is_required and ' required' or '',
self.field_name, self.length, escape(data), maxlength) self.field_name, self.length, escape(data), maxlength)
@ -264,7 +265,7 @@ class LargeTextField(TextField):
if data is None: if data is None:
data = '' data = ''
if isinstance(data, unicode): if isinstance(data, unicode):
data = data.encode('utf-8') data = data.encode(DEFAULT_CHARSET)
return '<textarea id="%s" class="v%s%s" name="%s" rows="%s" cols="%s">%s</textarea>' % \ return '<textarea id="%s" class="v%s%s" name="%s" rows="%s" cols="%s">%s</textarea>' % \
(FORM_FIELD_ID_PREFIX + self.field_name, self.__class__.__name__, self.is_required and ' required' or '', (FORM_FIELD_ID_PREFIX + self.field_name, self.__class__.__name__, self.is_required and ' required' or '',
self.field_name, self.rows, self.cols, escape(data)) self.field_name, self.rows, self.cols, escape(data))

View File

@ -150,14 +150,15 @@ class ModPythonHandler(BaseHandler):
def populate_apache_request(http_response, mod_python_req): def populate_apache_request(http_response, mod_python_req):
"Populates the mod_python request object with an HttpResponse" "Populates the mod_python request object with an HttpResponse"
mod_python_req.content_type = http_response['Content-Type'] or httpwrappers.DEFAULT_MIME_TYPE from django.conf import settings
mod_python_req.content_type = http_response['Content-Type']
for key, value in http_response.headers.items(): for key, value in http_response.headers.items():
if key != 'Content-Type': if key != 'Content-Type':
mod_python_req.headers_out[key] = value mod_python_req.headers_out[key] = value
for c in http_response.cookies.values(): for c in http_response.cookies.values():
mod_python_req.headers_out.add('Set-Cookie', c.output(header='')) mod_python_req.headers_out.add('Set-Cookie', c.output(header=''))
mod_python_req.status = http_response.status_code mod_python_req.status = http_response.status_code
mod_python_req.write(http_response.get_content_as_string('utf-8')) mod_python_req.write(http_response.get_content_as_string(settings.DEFAULT_CHARSET))
def handler(req): def handler(req):
# mod_python hooks into this function. # mod_python hooks into this function.

View File

@ -167,6 +167,6 @@ class WSGIHandler(BaseHandler):
response_headers = response.headers.items() response_headers = response.headers.items()
for c in response.cookies.values(): for c in response.cookies.values():
response_headers.append(('Set-Cookie', c.output(header=''))) response_headers.append(('Set-Cookie', c.output(header='')))
output = [response.get_content_as_string('utf-8')] output = [response.get_content_as_string(settings.DEFAULT_CHARSET)]
start_response(status, response_headers) start_response(status, response_headers)
return output return output

View File

@ -549,16 +549,29 @@ def get_validation_errors(outfile):
if not isinstance(opts.admin, meta.Admin): if not isinstance(opts.admin, meta.Admin):
e.add(opts, '"admin" attribute, if given, must be set to a meta.Admin() instance.') e.add(opts, '"admin" attribute, if given, must be set to a meta.Admin() instance.')
else: else:
for fn in opts.admin.list_display: # list_display
try: if not isinstance(opts.admin.list_display, (list, tuple)):
f = opts.get_field(fn) e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.')
except meta.FieldDoesNotExist: else:
klass = opts.get_model_module().Klass for fn in opts.admin.list_display:
if not hasattr(klass, fn) or not callable(getattr(klass, fn)): try:
e.add(opts, '"admin.list_display" refers to %r, which isn\'t a field or method.' % fn) f = opts.get_field(fn)
else: except meta.FieldDoesNotExist:
if isinstance(f, meta.ManyToManyField): klass = opts.get_model_module().Klass
e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn) if not hasattr(klass, fn) or not callable(getattr(klass, fn)):
e.add(opts, '"admin.list_display" refers to %r, which isn\'t a field or method.' % fn)
else:
if isinstance(f, meta.ManyToManyField):
e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn)
# list_filter
if not isinstance(opts.admin.list_filter, (list, tuple)):
e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.')
else:
for fn in opts.admin.list_filter:
try:
f = opts.get_field(fn)
except meta.FieldDoesNotExist:
e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn)
# Check ordering attribute. # Check ordering attribute.
if opts.ordering: if opts.ordering:

View File

@ -55,6 +55,7 @@ times with multiple contexts)
'\n<html>\n\n</html>\n' '\n<html>\n\n</html>\n'
""" """
import re import re
from django.conf.settings import DEFAULT_CHARSET
__all__ = ('Template','Context','compile_string') __all__ = ('Template','Context','compile_string')
@ -519,7 +520,7 @@ class VariableNode(Node):
if not isinstance(output, basestring): if not isinstance(output, basestring):
output = str(output) output = str(output)
elif isinstance(output, unicode): elif isinstance(output, unicode):
output = output.encode('utf-8') output = output.encode(DEFAULT_CHARSET)
return output return output
def register_tag(token_command, callback_function): def register_tag(token_command, callback_function):

View File

@ -76,7 +76,7 @@ class CacheMiddleware:
Sets the cache, if needed. Sets the cache, if needed.
""" """
if request._cache_middleware_set_cache: if request._cache_middleware_set_cache:
content = response.get_content_as_string('utf-8') content = response.get_content_as_string(settings.DEFAULT_CHARSET)
if request._cache_middleware_accepts_gzip: if request._cache_middleware_accepts_gzip:
content = compress_string(content) content = compress_string(content)
response.content = content response.content = content

View File

@ -54,31 +54,29 @@ class CommonMiddleware:
return None return None
def process_response(self, request, response): def process_response(self, request, response):
""" "Check for a flat page (for 404s) and calculate the Etag, if needed."
Check for a flatfile (for 404s) and calculate the Etag, if needed.
"""
# If this was a 404, check for a flat file
if response.status_code == 404: if response.status_code == 404:
try: if settings.USE_FLAT_PAGES:
response = flat_file(request, request.path) try:
except exceptions.Http404: return flat_file(request, request.path)
except exceptions.Http404:
pass
if settings.SEND_BROKEN_LINK_EMAILS:
# If the referrer was from an internal link or a non-search-engine site, # If the referrer was from an internal link or a non-search-engine site,
# send a note to the managers. # send a note to the managers.
if settings.SEND_BROKEN_LINK_EMAILS: domain = request.META['HTTP_HOST']
domain = request.META['HTTP_HOST'] referer = request.META.get('HTTP_REFERER', None)
referer = request.META.get('HTTP_REFERER', None) is_internal = referer and (domain in referer)
is_internal = referer and (domain in referer) path = request.get_full_path()
path = request.get_full_path() if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer):
if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer): mail_managers("Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''), domain),
mail_managers("Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''), domain), "Referrer: %s\nRequested URL: %s\n" % (referer, request.get_full_path()))
"Referrer: %s\nRequested URL: %s\n" % (referer, request.get_full_path()))
# If there's no flatfile we want to return the original 404 response
return response return response
# Use ETags, if requested # Use ETags, if requested.
if settings.USE_ETAGS: if settings.USE_ETAGS:
etag = md5.new(response.get_content_as_string('utf-8')).hexdigest() etag = md5.new(response.get_content_as_string(settings.DEFAULT_CHARSET)).hexdigest()
if request.META.get('HTTP_IF_NONE_MATCH') == etag: if request.META.get('HTTP_IF_NONE_MATCH') == etag:
response = httpwrappers.HttpResponseNotModified() response = httpwrappers.HttpResponseNotModified()
else: else:

View File

@ -1,7 +1,7 @@
from Cookie import SimpleCookie from Cookie import SimpleCookie
from pprint import pformat from pprint import pformat
from urllib import urlencode from urllib import urlencode
import datastructures from django.utils import datastructures
class HttpRequest(object): # needs to be new-style class because subclasses define "property"s class HttpRequest(object): # needs to be new-style class because subclasses define "property"s
"A basic HTTP request" "A basic HTTP request"
@ -139,8 +139,8 @@ class HttpResponse:
"A basic HTTP response, with content and dictionary-accessed headers" "A basic HTTP response, with content and dictionary-accessed headers"
def __init__(self, content='', mimetype=None): def __init__(self, content='', mimetype=None):
if not mimetype: if not mimetype:
from django.conf.settings import DEFAULT_MIME_TYPE from django.conf.settings import DEFAULT_CONTENT_TYPE, DEFAULT_CHARSET
mimetype = DEFAULT_MIME_TYPE mimetype = "%s; charset=%s" % (DEFAULT_CONTENT_TYPE, DEFAULT_CHARSET)
self.content = content self.content = content
self.headers = {'Content-Type':mimetype} self.headers = {'Content-Type':mimetype}
self.cookies = SimpleCookie() self.cookies = SimpleCookie()

View File

@ -431,7 +431,7 @@ def change_list(request, app_label, module_name):
if j == 0: # First column is a special case if j == 0: # First column is a special case
result_id = getattr(result, pk) result_id = getattr(result, pk)
raw_template.append('<th%s><a href="%s/"%s>%s</a></th>' % \ raw_template.append('<th%s><a href="%s/"%s>%s</a></th>' % \
(row_class, result_id, (is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), result_repr)) (row_class, result_id, (is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %r); return false;"' % result_id or ''), result_repr))
else: else:
raw_template.append('<td%s>%s</td>' % (row_class, result_repr)) raw_template.append('<td%s>%s</td>' % (row_class, result_repr))
raw_template.append('</tr>\n') raw_template.append('</tr>\n')

View File

@ -1,6 +1,7 @@
from django.core.cache import cache from django.core.cache import cache
from django.utils.httpwrappers import HttpResponseNotModified from django.utils.httpwrappers import HttpResponseNotModified
from django.utils.text import compress_string from django.utils.text import compress_string
from django.conf.settings import DEFAULT_CHARSET
import datetime, md5 import datetime, md5
def cache_page(view_func, cache_timeout, key_prefix=''): def cache_page(view_func, cache_timeout, key_prefix=''):
@ -25,7 +26,7 @@ def cache_page(view_func, cache_timeout, key_prefix=''):
response = cache.get(cache_key, None) response = cache.get(cache_key, None)
if response is None: if response is None:
response = view_func(request, *args, **kwargs) response = view_func(request, *args, **kwargs)
content = response.get_content_as_string('utf-8') content = response.get_content_as_string(DEFAULT_CHARSET)
if accepts_gzip: if accepts_gzip:
content = compress_string(content) content = compress_string(content)
response.content = content response.content = content

View File

@ -572,6 +572,9 @@ object in the result list is "truncated" to the given ``type``.
* ``"month"`` returns a list of all distinct year/month values for the field. * ``"month"`` returns a list of all distinct year/month values for the field.
* ``"day"`` returns a list of all distinct year/month/day values for the field. * ``"day"`` returns a list of all distinct year/month/day values for the field.
Additional, optional keyword arguments, in the format described in
"Field lookups" above, are also accepted.
Here's an example, using the ``Poll`` model defined above:: Here's an example, using the ``Poll`` model defined above::
>>> from datetime import datetime >>> from datetime import datetime
@ -587,6 +590,8 @@ Here's an example, using the ``Poll`` model defined above::
[datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)] [datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)]
>>> polls.get_pub_date_list('day') >>> polls.get_pub_date_list('day')
[datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)] [datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)]
>>> polls.get_pub_date_list('day', question__contains='name')
[datetime.datetime(2005, 3, 20)]
``get_FOO_list()`` also accepts an optional keyword argument ``order``, which ``get_FOO_list()`` also accepts an optional keyword argument ``order``, which
should be either ``"ASC"`` or ``"DESC"``. This specifies how to order the should be either ``"ASC"`` or ``"DESC"``. This specifies how to order the