1
0
mirror of https://github.com/django/django.git synced 2025-07-05 18:29:11 +00:00

queryset-refactor: Merged from trunk up to [7216].

git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7219 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-03-11 03:15:07 +00:00
parent df8e3e6512
commit 62bdb6eae8
37 changed files with 6781 additions and 3029 deletions

View File

@ -112,6 +112,7 @@ answer newbie questions, and generally made Django that much better:
Sander Dijkhuis <sander.dijkhuis@gmail.com>
Jordan Dimov <s3x3y1@gmail.com>
dne@mayonnaise.net
dready <wil@mojipage.com>
Maximillian Dornseif <md@hudora.de>
Jeremy Dunck <http://dunck.us/>
Andrew Durdin <adurdin@gmail.com>

View File

@ -91,8 +91,8 @@ LANGUAGES_BIDI = ("he", "ar", "fa")
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
LOCALE_PATHS = ()
LANGUAGE_COOKIE_NAME = 'django_language'
# Not-necessarily-technical managers of the site. They get broken link
# notifications and other various e-mails.

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,12 @@
# Italian translation of Django.
# Copyright (C) 2006 the Lawrence Journal-World
# This file is distributed under the same license as the Django package.
#
msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-02-02 18:31+0100\n"
"PO-Revision-Date: 2008-02-02 19:40+0100\n"
"PO-Revision-Date: 2008-03-02 11:40+0100\n"
"Last-Translator: Nicola Larosa <nico@tekNico.net>\n"
"Language-Team: Italiano\n"
"MIME-Version: 1.0\n"
@ -79,7 +78,7 @@ msgstr "Francese"
#: conf/global_settings.py:54
msgid "Gaeilge"
msgstr ""
msgstr "Gaelico"
#: conf/global_settings.py:55
msgid "Galician"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,33 +5,16 @@
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: Django 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-05-16 17:39+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Rudolph Froger <rfroger@estrate.nl>\n"
"POT-Creation-Date: 2008-02-27 10:34+0100\n"
"PO-Revision-Date: 2008-02-27 11:22+0100\n"
"Last-Translator: jdetaeye <jdetaeye@frepple.com>\n"
"Language-Team: nl <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: contrib/admin/media/js/calendar.js:24
#: contrib/admin/media/js/dateparse.js:32
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
"januari februari maart april mei juni juli augustus september oktober "
"november december"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "Z M D W D V Z"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "zondag maandag dinsdag woensdag donderdag vrijdag zaterdag"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
@ -62,49 +45,72 @@ msgstr "Selecteer uw keuze(s) en klik "
msgid "Clear all"
msgstr "Allemaal verwijderen"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
#: contrib/admin/media/js/calendar.js:24
#: contrib/admin/media/js/dateparse.js:32
msgid "January February March April May June July August September October November December"
msgstr "januari februari maart april mei juni juli augustus september oktober november december"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "Z M D W D V Z"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "zondag maandag dinsdag woensdag donderdag vrijdag zaterdag"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
msgid "Show"
msgstr "Tonen"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
msgid "Hide"
msgstr "Verbergen"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Now"
msgstr "Nu"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock"
msgstr "Klok"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time"
msgstr "Kies een tijd"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "Midnight"
msgstr "Middernacht"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m."
msgstr "6 uur"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon"
msgstr "12 uur"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
msgstr "Annuleren"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today"
msgstr "Vandaag"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar"
msgstr "Kalender"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday"
msgstr "Gisteren"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
msgstr "Morgen"

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ try:
except NameError:
from sets import Set as set # Python 2.3 fallback
class ModelBackend:
class ModelBackend(object):
"""
Authenticate against django.contrib.auth.models.User
"""

View File

@ -2,25 +2,49 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_unicode
CONTENT_TYPE_CACHE = {}
class ContentTypeManager(models.Manager):
# Cache to avoid re-looking up ContentType objects all over the place.
# This cache is shared by all the get_for_* methods.
_cache = {}
def get_for_model(self, model):
"""
Returns the ContentType object for the given model, creating the
ContentType if necessary.
Returns the ContentType object for a given model, creating the
ContentType if necessary. Lookups are cached so that subsequent lookups
for the same model don't hit the database.
"""
opts = model._meta
key = (opts.app_label, opts.object_name.lower())
try:
ct = CONTENT_TYPE_CACHE[key]
ct = self.__class__._cache[key]
except KeyError:
# The smart_unicode() is needed around opts.verbose_name_raw because it might
# be a django.utils.functional.__proxy__ object.
ct, created = self.model._default_manager.get_or_create(app_label=key[0],
model=key[1], defaults={'name': smart_unicode(opts.verbose_name_raw)})
CONTENT_TYPE_CACHE[key] = ct
# Load or create the ContentType entry. The smart_unicode() is
# needed around opts.verbose_name_raw because name_raw might be a
# django.utils.functional.__proxy__ object.
ct, created = self.get_or_create(
app_label = opts.app_label,
model = opts.object_name.lower(),
defaults = {'name': smart_unicode(opts.verbose_name_raw)},
)
self._add_to_cache(ct)
return ct
def get_for_id(self, id):
"""
Lookup a ContentType by ID. Uses the same shared cache as get_for_model
(though ContentTypes are obviously not created on-the-fly by get_by_id).
"""
try:
ct = self.__class__._cache[id]
except KeyError:
# This could raise a DoesNotExist; that's correct behavior and will
# make sure that only correct ctypes get stored in the cache dict.
ct = self.get(pk=id)
self._add_to_cache(ct)
return ct
def clear_cache(self):
"""
Clear out the content-type cache. This needs to happen during database
@ -28,14 +52,21 @@ class ContentTypeManager(models.Manager):
django.contrib.contenttypes.management.update_contenttypes for where
this gets called).
"""
global CONTENT_TYPE_CACHE
CONTENT_TYPE_CACHE = {}
self.__class__._cache.clear()
def _add_to_cache(self, ct):
"""Insert a ContentType into the cache."""
model = ct.model_class()
key = (model._meta.app_label, model._meta.object_name.lower())
self.__class__._cache[key] = ct
self.__class__._cache[ct.id] = ct
class ContentType(models.Model):
name = models.CharField(max_length=100)
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
class Meta:
verbose_name = _('content type')
verbose_name_plural = _('content types')

View File

@ -0,0 +1,47 @@
"""
Make sure that the content type cache (see ContentTypeManager) works correctly.
Lookups for a particular content type -- by model or by ID -- should hit the
database only on the first lookup.
First, let's make sure we're dealing with a blank slate (and that DEBUG is on so
that queries get logged)::
>>> from django.conf import settings
>>> settings.DEBUG = True
>>> from django.contrib.contenttypes.models import ContentType
>>> ContentType.objects.clear_cache()
>>> from django import db
>>> db.reset_queries()
At this point, a lookup for a ContentType should hit the DB::
>>> ContentType.objects.get_for_model(ContentType)
<ContentType: content type>
>>> len(db.connection.queries)
1
A second hit, though, won't hit the DB, nor will a lookup by ID::
>>> ct = ContentType.objects.get_for_model(ContentType)
>>> len(db.connection.queries)
1
>>> ContentType.objects.get_for_id(ct.id)
<ContentType: content type>
>>> len(db.connection.queries)
1
Once we clear the cache, another lookup will again hit the DB::
>>> ContentType.objects.clear_cache()
>>> ContentType.objects.get_for_model(ContentType)
<ContentType: content type>
>>> len(db.connection.queries)
2
Don't forget to reset DEBUG!
>>> settings.DEBUG = False
"""

View File

@ -6,7 +6,7 @@ from django.core import signals
from django.core.handlers.base import BaseHandler
from django.dispatch import dispatcher
from django.utils import datastructures
from django.utils.encoding import force_unicode
from django.utils.encoding import force_unicode, smart_str
# NOTE: do *not* import settings (or any module which eventually imports
# settings) until after ModPythonHandler has been called; otherwise os.environ
@ -36,8 +36,9 @@ class ModPythonRequest(http.HttpRequest):
meta = pformat(self.META)
except:
meta = '<could not parse>'
return '<ModPythonRequest\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
(self.path, get, post, cookies, meta)
return smart_str(u'<ModPythonRequest\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
(self.path, unicode(get), unicode(post),
unicode(cookies), unicode(meta)))
def get_full_path(self):
return '%s%s' % (self.path, self._req.args and ('?' + self._req.args) or '')

View File

@ -318,8 +318,8 @@ def send_mail(subject, message, from_email, recipient_list, fail_silently=False,
If auth_user is None, the EMAIL_HOST_USER setting is used.
If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
NOTE: This method is deprecated. It exists for backwards compatibility.
New code should use the EmailMessage class directly.
Note: The API for this method is frozen. New code wanting to extend the
functionality should use the EmailMessage class directly.
"""
connection = SMTPConnection(username=auth_user, password=auth_password,
fail_silently=fail_silently)
@ -335,8 +335,8 @@ def send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password
If auth_user is None, the EMAIL_HOST_USER setting is used.
If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
NOTE: This method is deprecated. It exists for backwards compatibility.
New code should use the EmailMessage class directly.
Note: The API for this method is frozen. New code wanting to extend the
functionality should use the EmailMessage class directly.
"""
connection = SMTPConnection(username=auth_user, password=auth_password,
fail_silently=fail_silently)

View File

@ -6,10 +6,22 @@ import sys
from django.utils import termcolors
def supports_color():
"""
Returns True if the running system's terminal supports color, and False
otherwise.
"""
unsupported_platform = (sys.platform in ('win32', 'Pocket PC')
or sys.platform.startswith('java'))
# isatty is not always implemented, #6223.
is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
if unsupported_platform or not is_a_tty:
return False
return True
def color_style():
"""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 not supports_color():
return no_style()
class dummy: pass
style = dummy()

View File

@ -108,10 +108,12 @@ class Command(BaseCommand):
transaction.rollback()
transaction.leave_transaction_management()
if show_traceback:
raise
sys.stderr.write(
self.style.ERROR("Problem installing fixture '%s': %s\n" %
(full_path, str(e))))
import traceback
traceback.print_exc()
else:
sys.stderr.write(
self.style.ERROR("Problem installing fixture '%s': %s\n" %
(full_path, str(e))))
return
fixture.close()
except:

View File

@ -67,6 +67,8 @@ class Command(NoArgsCommand):
created_models.add(model)
for refto, refs in references.items():
pending_references.setdefault(refto, []).extend(refs)
if refto in seen_models:
sql.extend(sql_for_pending_references(refto, self.style, pending_references))
sql.extend(sql_for_pending_references(model, self.style, pending_references))
if verbosity >= 1:
print "Creating table %s" % model._meta.db_table

View File

@ -90,6 +90,8 @@ def sql_create(app, style):
final_output.extend(output)
for refto, refs in references.items():
pending_references.setdefault(refto, []).extend(refs)
if refto in known_models:
final_output.extend(sql_for_pending_references(refto, style, pending_references))
final_output.extend(sql_for_pending_references(model, style, pending_references))
# Keep track of the fact that we've created the table for this model.
known_models.add(model)

View File

@ -3,23 +3,25 @@ from Cookie import SimpleCookie
from pprint import pformat
from urllib import urlencode
from urlparse import urljoin
from django.utils.datastructures import MultiValueDict, FileDict
from django.utils.encoding import smart_str, iri_to_uri, force_unicode
from utils import *
RESERVED_CHARS="!*'();:@&=+$,/?%#[]"
try:
# The mod_python version is more efficient, so try importing it first.
from mod_python.util import parse_qsl
except ImportError:
from cgi import parse_qsl
from django.utils.datastructures import MultiValueDict, FileDict
from django.utils.encoding import smart_str, iri_to_uri, force_unicode
from utils import *
RESERVED_CHARS="!*'();:@&=+$,/?%#[]"
class Http404(Exception):
pass
class HttpRequest(object):
"A basic HTTP request"
"""A basic HTTP request."""
# The encoding used in GET/POST dicts. None means use default setting.
_encoding = None
@ -46,7 +48,7 @@ class HttpRequest(object):
__contains__ = has_key
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.
if 'HTTP_X_FORWARDED_HOST' in self.META:
host = self.META['HTTP_X_FORWARDED_HOST']
@ -98,7 +100,7 @@ class HttpRequest(object):
encoding = property(_get_encoding, _set_encoding)
def parse_file_upload(header_dict, post_data):
"Returns a tuple of (POST QueryDict, FILES MultiValueDict)"
"""Returns a tuple of (POST QueryDict, FILES MultiValueDict)."""
import email, email.Message
from cgi import parse_header
raw_message = '\r\n'.join(['%s:%s' % pair for pair in header_dict.items()])
@ -130,6 +132,7 @@ def parse_file_upload(header_dict, post_data):
POST.appendlist(name_dict['name'], submessage.get_payload())
return POST, FILES
class QueryDict(MultiValueDict):
"""
A specialized MultiValueDict that takes a query string when initialized.
@ -148,12 +151,13 @@ class QueryDict(MultiValueDict):
self.encoding = encoding
self._mutable = True
for key, value in parse_qsl((query_string or ''), True): # keep_blank_values=True
self.appendlist(force_unicode(key, encoding, errors='replace'), force_unicode(value, encoding, errors='replace'))
self.appendlist(force_unicode(key, encoding, errors='replace'),
force_unicode(value, encoding, errors='replace'))
self._mutable = mutable
def _assert_mutable(self):
if not self._mutable:
raise AttributeError, "This QueryDict instance is immutable"
raise AttributeError("This QueryDict instance is immutable")
def __setitem__(self, key, value):
self._assert_mutable()
@ -222,7 +226,7 @@ class QueryDict(MultiValueDict):
return MultiValueDict.setdefault(self, key, default)
def copy(self):
"Returns a mutable copy of this object."
"""Returns a mutable copy of this object."""
return self.__deepcopy__({})
def urlencode(self):
@ -243,7 +247,7 @@ def parse_cookie(cookie):
return cookiedict
class HttpResponse(object):
"A basic HTTP response, with content and dictionary-accessed headers"
"""A basic HTTP response, with content and dictionary-accessed headers."""
status_code = 200
@ -272,13 +276,13 @@ class HttpResponse(object):
self._headers = {'content-type': ('Content-Type', content_type)}
def __str__(self):
"Full HTTP message, including headers"
"""Full HTTP message, including headers."""
return '\n'.join(['%s: %s' % (key, value)
for key, value in self._headers.values()]) \
+ '\n\n' + self.content
def _convert_to_ascii(self, *values):
"Convert all values to ascii strings"
"""Converts all values to ascii strings."""
for value in values:
if isinstance(value, unicode):
try:
@ -303,7 +307,7 @@ class HttpResponse(object):
return self._headers[header.lower()][1]
def has_header(self, header):
"Case-insensitive check for a header"
"""Case-insensitive check for a header."""
return self._headers.has_key(header.lower())
__contains__ = has_header
@ -314,16 +318,23 @@ class HttpResponse(object):
def get(self, header, alternate):
return self._headers.get(header.lower(), (None, alternate))[1]
def set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=None):
def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
domain=None, secure=False):
self.cookies[key] = value
for var in ('max_age', 'path', 'domain', 'secure', 'expires'):
val = locals()[var]
if val is not None:
self.cookies[key][var.replace('_', '-')] = val
if max_age is not None:
self.cookies[key]['max-age'] = max_age
if expires is not None:
self.cookies[key]['expires'] = expires
if path is not None:
self.cookies[key]['path'] = path
if domain is not None:
self.cookies[key]['domain'] = domain
if secure:
self.cookies[key]['secure'] = True
def delete_cookie(self, key, path='/', domain=None):
self.set_cookie(key, max_age=0, path=path, domain=domain,
expires='Thu, 01-Jan-1970 00:00:00 GMT')
expires='Thu, 01-Jan-1970 00:00:00 GMT')
def _get_content(self):
if self.has_header('Content-Encoding'):
@ -354,7 +365,7 @@ class HttpResponse(object):
# See http://docs.python.org/lib/bltin-file-objects.html
def write(self, content):
if not self._is_string:
raise Exception, "This %s instance is not writable" % self.__class__
raise Exception("This %s instance is not writable" % self.__class__)
self._container.append(content)
def flush(self):
@ -362,7 +373,7 @@ class HttpResponse(object):
def tell(self):
if not self._is_string:
raise Exception, "This %s instance cannot tell its position" % self.__class__
raise Exception("This %s instance cannot tell its position" % self.__class__)
return sum([len(chunk) for chunk in self._container])
class HttpResponseRedirect(HttpResponse):
@ -419,7 +430,7 @@ def get_host(request):
# this slightly more restricted function.
def str_to_unicode(s, encoding):
"""
Convert basestring objects to unicode, using the given encoding. Illegaly
Converts basestring objects to unicode, using the given encoding. Illegally
encoded input characters are replaced with Unicode "unknown" codepoint
(\ufffd).
@ -429,4 +440,3 @@ def str_to_unicode(s, encoding):
return unicode(s, encoding, 'replace')
else:
return s

View File

@ -129,7 +129,7 @@ class BaseForm(StrAndUnicode):
bf_errors = self.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable.
if bf.is_hidden:
if bf_errors:
top_errors.extend(['(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors])
top_errors.extend([u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors])
hidden_fields.append(unicode(bf))
else:
if errors_on_separate_row and bf_errors:
@ -150,7 +150,7 @@ class BaseForm(StrAndUnicode):
help_text = u''
output.append(normal_row % {'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text})
if top_errors:
output.insert(0, error_row % top_errors)
output.insert(0, error_row % force_unicode(top_errors))
if hidden_fields: # Insert any hidden fields in the last row.
str_hidden = u''.join(hidden_fields)
if output:

View File

@ -1,4 +1,4 @@
"Translation helper functions"
"""Translation helper functions."""
import locale
import os
@ -7,7 +7,6 @@ import sys
import gettext as gettext_module
from cStringIO import StringIO
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe, SafeData
try:
@ -30,7 +29,7 @@ _active = {}
# The default translation is based on the settings file.
_default = None
# This is a cache for normalised accept-header languages to prevent multiple
# This is a cache for normalized accept-header languages to prevent multiple
# file lookups when checking the same locale on repeated requests.
_accepted = {}
@ -56,7 +55,7 @@ def to_locale(language, to_lower=False):
return language.lower()
def to_language(locale):
"Turns a locale name (en_US) into a language name (en-us)."
"""Turns a locale name (en_US) into a language name (en-us)."""
p = locale.find('_')
if p >= 0:
return locale[:p].lower()+'-'+locale[p+1:].lower()
@ -229,7 +228,7 @@ def deactivate_all():
_active[currentThread()] = gettext_module.NullTranslations()
def get_language():
"Returns the currently selected language."
"""Returns the currently selected language."""
t = _active.get(currentThread(), None)
if t is not None:
try:
@ -251,7 +250,7 @@ def get_language_bidi():
def catalog():
"""
This function returns the current active catalog for further processing.
Returns the current active catalog for further processing.
This can be used if you need to modify the catalog or want to access the
whole message catalog instead of just translating one string.
"""
@ -355,7 +354,7 @@ def get_language_from_request(request):
if lang_code in supported and lang_code is not None and check_for_language(lang_code):
return lang_code
lang_code = request.COOKIES.get('django_language')
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
if lang_code and lang_code in supported and check_for_language(lang_code):
return lang_code
@ -374,7 +373,7 @@ def get_language_from_request(request):
normalized = locale.locale_alias.get(to_locale(accept_lang, True))
if not normalized:
continue
# Remove the default encoding from locale_alias
# Remove the default encoding from locale_alias.
normalized = normalized.split('.')[0]
if normalized in _accepted:
@ -396,9 +395,9 @@ def get_language_from_request(request):
def get_date_formats():
"""
This function checks whether translation files provide a translation for some
technical message ID to store date and time formats. If it doesn't contain
one, the formats provided in the settings will be used.
Checks whether translation files provide a translation for some technical
message ID to store date and time formats. If it doesn't contain one, the
formats provided in the settings will be used.
"""
from django.conf import settings
date_format = ugettext('DATE_FORMAT')
@ -414,9 +413,9 @@ def get_date_formats():
def get_partial_date_formats():
"""
This function checks whether translation files provide a translation for some
technical message ID to store partial date formats. If it doesn't contain
one, the formats provided in the settings will be used.
Checks whether translation files provide a translation for some technical
message ID to store partial date formats. If it doesn't contain one, the
formats provided in the settings will be used.
"""
from django.conf import settings
year_month_format = ugettext('YEAR_MONTH_FORMAT')
@ -440,6 +439,7 @@ block_re = re.compile(r"""^\s*blocktrans(?:\s+|$)""")
endblock_re = re.compile(r"""^\s*endblocktrans$""")
plural_re = re.compile(r"""^\s*plural$""")
constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""")
def templatize(src):
"""
Turns a Django template into something that is understood by xgettext. It
@ -475,7 +475,7 @@ def templatize(src):
elif pluralmatch:
inplural = True
else:
raise SyntaxError, "Translation blocks must not include other block tags: %s" % t.contents
raise SyntaxError("Translation blocks must not include other block tags: %s" % t.contents)
elif t.token_type == TOKEN_VAR:
if inplural:
plural.append('%%(%s)s' % t.contents)
@ -541,4 +541,3 @@ def parse_accept_lang_header(lang_string):
result.append((lang, priority))
result.sort(lambda x, y: -cmp(x[1], y[1]))
return result

View File

@ -5,7 +5,11 @@ import time
from datetime import timedelta, tzinfo
from django.utils.encoding import smart_unicode
DEFAULT_ENCODING = locale.getdefaultlocale()[1] or 'ascii'
try:
DEFAULT_ENCODING = locale.getdefaultlocale()[1] or 'ascii'
except:
# Any problems at all determining the locale and we fallback. See #5846.
DEFAULT_ENCODING = 'ascii'
class FixedOffset(tzinfo):
"Fixed offset in minutes east from UTC."

View File

@ -28,7 +28,7 @@ def set_language(request):
if hasattr(request, 'session'):
request.session['django_language'] = lang_code
else:
response.set_cookie('django_language', lang_code)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
return response
NullSource = """

View File

@ -166,7 +166,7 @@ logical to us.
We're well aware that there are other awesome Web frameworks out there, and
we're not averse to borrowing ideas where appropriate. However, Django was
developed precisely because we were unhappy with the status quo, so please be
aware that "because <Framework X>" does it is not going to be sufficient reason
aware that "because <Framework X> does it" is not going to be sufficient reason
to add a given feature to Django.
Why did you write all of Django from scratch, instead of using other Python libraries?

View File

@ -24,11 +24,14 @@ Installation
To install the flatpages app, follow these steps:
1. Add ``'django.contrib.flatpages'`` to your INSTALLED_APPS_ setting.
2. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'``
1. Install the `sites framework`_ by adding ``'django.contrib.sites'`` to
your INSTALLED_APPS_ setting, if it's not already in there.
2. Add ``'django.contrib.flatpages'`` to your INSTALLED_APPS_ setting.
3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'``
to your MIDDLEWARE_CLASSES_ setting.
3. Run the command ``manage.py syncdb``.
4. Run the command ``manage.py syncdb``.
.. _sites framework: ../sites/
.. _INSTALLED_APPS: ../settings/#installed-apps
.. _MIDDLEWARE_CLASSES: ../settings/#middleware-classes

View File

@ -547,7 +547,7 @@ following this algorithm:
* First, it looks for a ``django_language`` key in the the current user's
`session`_.
* Failing that, it looks for a cookie called ``django_language``.
* Failing that, it looks for a cookie that is named according to your ``LANGUAGE_COOKIE_NAME`` setting (the default name is: ``django_language``).
* Failing that, it looks at the ``Accept-Language`` HTTP header. This
header is sent by your browser and tells the server which language(s) you
prefer, in order by priority. Django tries each language in the header
@ -719,7 +719,8 @@ Activate this view by adding the following line to your URLconf::
The view expects to be called via the ``POST`` method, with a ``language``
parameter set in request. If session support is enabled, the view
saves the language choice in the user's session. Otherwise, it saves the
language choice in a ``django_language`` cookie.
language choice in a cookie that is by default named ``django_language``
(the name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting).
After setting the language choice, Django redirects the user, following this
algorithm:

View File

@ -243,6 +243,10 @@ object::
>>> f.cleaned_data
{'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
.. note::
**New in Django development version** The ``cleaned_data`` attribute was
called ``clean_data`` in earlier releases.
Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
always cleans the input into a Unicode string. We'll cover the encoding
implications later in this document.

View File

@ -579,6 +579,16 @@ in standard language format. For example, U.S. English is ``"en-us"``. See the
.. _internationalization docs: ../i18n/
LANGUAGE_COOKIE_NAME
--------------------
Default: ``'django_language'``
The name of the cookie to use for the language cookie. This can be whatever
you want (but should be different from SESSION_COOKIE_NAME). See the
`internationalization docs`_ for details.
LANGUAGES
---------
@ -822,8 +832,8 @@ SESSION_COOKIE_NAME
Default: ``'sessionid'``
The name of the cookie to use for sessions. This can be whatever you want.
See the `session docs`_.
The name of the cookie to use for sessions. This can be whatever you want (but
should be different from ``LANGUAGE_COOKIE_NAME``). See the `session docs`_.
SESSION_COOKIE_PATH
-------------------

View File

@ -629,9 +629,10 @@ the given Python module name, not the name of the app.
Once you've created that Python module, you'll just have to write a bit of
Python code, depending on whether you're writing filters or tags.
To be a valid tag library, the module contain a module-level variable named
``register`` that is a ``template.Library`` instance, in which all the tags and
filters are registered. So, near the top of your module, put the following::
To be a valid tag library, the module must contain a module-level variable
named ``register`` that is a ``template.Library`` instance, in which all the
tags and filters are registered. So, near the top of your module, put the
following::
from django import template
@ -983,7 +984,7 @@ Notes:
exception. It should fail silently, just as template filters should.
Ultimately, this decoupling of compilation and rendering results in an
efficient template system, because a template can render multiple context
efficient template system, because a template can render multiple contexts
without having to be parsed multiple times.
Auto-escaping considerations

View File

@ -0,0 +1,3 @@
"""
Tests for Django's various Request objects.
"""

View File

@ -0,0 +1 @@
# Need a models module for the test runner.

View File

@ -0,0 +1,34 @@
"""
>>> from django.http import HttpRequest
>>> print repr(HttpRequest())
<HttpRequest
GET:{},
POST:{},
COOKIES:{},
META:{}>
>>> from django.core.handlers.wsgi import WSGIRequest
>>> print repr(WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus'}))
<WSGIRequest
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{},
META:{...}>
>>> from django.core.handlers.modpython import ModPythonRequest
>>> class FakeModPythonRequest(ModPythonRequest):
... def __init__(self, *args, **kwargs):
... super(FakeModPythonRequest, self).__init__(*args, **kwargs)
... self._get = self._post = self._meta = self._cookies = {}
>>> class Dummy: pass
...
>>> req = Dummy()
>>> req.uri = 'bogus'
>>> print repr(FakeModPythonRequest(req))
<ModPythonRequest
path:bogus,
GET:{},
POST:{},
COOKIES:{},
META:{}>
"""