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:
parent
df8e3e6512
commit
62bdb6eae8
1
AUTHORS
1
AUTHORS
@ -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>
|
||||
|
@ -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.
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -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"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -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"
|
||||
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
"""
|
||||
|
@ -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')
|
||||
|
47
django/contrib/contenttypes/tests.py
Normal file
47
django/contrib/contenttypes/tests.py
Normal 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
|
||||
"""
|
@ -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 '')
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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."
|
||||
|
@ -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 = """
|
||||
|
@ -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?
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
-------------------
|
||||
|
@ -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
|
||||
|
3
tests/regressiontests/requests/__init__.py
Normal file
3
tests/regressiontests/requests/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
"""
|
||||
Tests for Django's various Request objects.
|
||||
"""
|
1
tests/regressiontests/requests/models.py
Normal file
1
tests/regressiontests/requests/models.py
Normal file
@ -0,0 +1 @@
|
||||
# Need a models module for the test runner.
|
34
tests/regressiontests/requests/tests.py
Normal file
34
tests/regressiontests/requests/tests.py
Normal 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:{}>
|
||||
"""
|
Loading…
x
Reference in New Issue
Block a user