mirror of
https://github.com/django/django.git
synced 2025-07-06 18:59:13 +00:00
queryset-refactor: Merged from trunk up to [6623].
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6637 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
f951d97d99
commit
f189280eb3
Binary file not shown.
@ -1016,7 +1016,7 @@ msgstr "Escoja %s para modificar"
|
|||||||
|
|
||||||
#: contrib/admin/views/main.py:780
|
#: contrib/admin/views/main.py:780
|
||||||
msgid "Database error"
|
msgid "Database error"
|
||||||
msgstr "Erorr en la base de datos"
|
msgstr "Error en la base de datos"
|
||||||
|
|
||||||
#: contrib/auth/forms.py:17
|
#: contrib/auth/forms.py:17
|
||||||
#: contrib/auth/forms.py:138
|
#: contrib/auth/forms.py:138
|
||||||
|
@ -104,7 +104,7 @@ class PasswordResetForm(oldforms.Manipulator):
|
|||||||
'site_name': site_name,
|
'site_name': site_name,
|
||||||
'user': user,
|
'user': user,
|
||||||
}
|
}
|
||||||
send_mail('Password reset on %s' % site_name, t.render(Context(c)), None, [user.email])
|
send_mail(_('Password reset on %s') % site_name, t.render(Context(c)), None, [user.email])
|
||||||
|
|
||||||
class PasswordChangeForm(oldforms.Manipulator):
|
class PasswordChangeForm(oldforms.Manipulator):
|
||||||
"A form that lets a user change his password."
|
"A form that lets a user change his password."
|
||||||
|
@ -242,6 +242,8 @@ def setup_environ(settings_mod):
|
|||||||
"""
|
"""
|
||||||
Configures the runtime environment. This can also be used by external
|
Configures the runtime environment. This can also be used by external
|
||||||
scripts wanting to set up a similar environment to manage.py.
|
scripts wanting to set up a similar environment to manage.py.
|
||||||
|
Returns the project directory (assuming the passed settings module is
|
||||||
|
directly in the project directory).
|
||||||
"""
|
"""
|
||||||
# Add this project to sys.path so that it's importable in the conventional
|
# Add this project to sys.path so that it's importable in the conventional
|
||||||
# way. For example, if this file (manage.py) lives in a directory
|
# way. For example, if this file (manage.py) lives in a directory
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
from django.core.management.base import copy_helper, CommandError, LabelCommand
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from django.core.management.base import copy_helper, CommandError, LabelCommand
|
||||||
|
|
||||||
class Command(LabelCommand):
|
class Command(LabelCommand):
|
||||||
help = "Creates a Django app directory structure for the given app name in the current directory."
|
help = ("Creates a Django app directory structure for the given app name"
|
||||||
|
" in the current directory.")
|
||||||
args = "[appname]"
|
args = "[appname]"
|
||||||
label = 'application name'
|
label = 'application name'
|
||||||
|
|
||||||
@ -14,17 +16,18 @@ class Command(LabelCommand):
|
|||||||
def handle_label(self, app_name, directory=None, **options):
|
def handle_label(self, app_name, directory=None, **options):
|
||||||
if directory is None:
|
if directory is None:
|
||||||
directory = os.getcwd()
|
directory = os.getcwd()
|
||||||
# Determine the project_name a bit naively -- by looking at the name of
|
# Determine the project_name by using the basename of directory,
|
||||||
# the parent directory.
|
# which should be the full path of the project directory (or the
|
||||||
project_dir = os.path.normpath(os.path.join(directory, os.pardir))
|
# current directory if no directory was passed).
|
||||||
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:
|
||||||
raise CommandError("You cannot create an app with the same name (%r) as your project." % app_name)
|
raise CommandError("You cannot create an app with the same name"
|
||||||
copy_helper(self.style, 'app', app_name, directory, parent_dir)
|
" (%r) as your project." % app_name)
|
||||||
|
copy_helper(self.style, 'app', app_name, directory, project_name)
|
||||||
|
|
||||||
class ProjectCommand(Command):
|
class ProjectCommand(Command):
|
||||||
help = "Creates a Django app directory structure for the given app name in this project's directory."
|
help = ("Creates a Django app directory structure for the given app name"
|
||||||
|
" in this project's directory.")
|
||||||
|
|
||||||
def __init__(self, project_directory):
|
def __init__(self, project_directory):
|
||||||
super(ProjectCommand, self).__init__()
|
super(ProjectCommand, self).__init__()
|
||||||
|
@ -127,6 +127,27 @@ class BaseDatabaseOperations(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError('Full-text search is not implemented for this database backend')
|
raise NotImplementedError('Full-text search is not implemented for this database backend')
|
||||||
|
|
||||||
|
def last_executed_query(self, cursor, sql, params):
|
||||||
|
"""
|
||||||
|
Returns a string of the query last executed by the given cursor, with
|
||||||
|
placeholders replaced with actual values.
|
||||||
|
|
||||||
|
`sql` is the raw query containing placeholders, and `params` is the
|
||||||
|
sequence of parameters. These are used by default, but this method
|
||||||
|
exists for database backends to provide a better implementation
|
||||||
|
according to their own quoting schemes.
|
||||||
|
"""
|
||||||
|
from django.utils.encoding import smart_unicode, force_unicode
|
||||||
|
|
||||||
|
# Convert params to contain Unicode values.
|
||||||
|
to_unicode = lambda s: force_unicode(s, strings_only=True)
|
||||||
|
if isinstance(params, (list, tuple)):
|
||||||
|
u_params = tuple([to_unicode(val) for val in params])
|
||||||
|
else:
|
||||||
|
u_params = dict([(to_unicode(k), to_unicode(v)) for k, v in params.items()])
|
||||||
|
|
||||||
|
return smart_unicode(sql) % u_params
|
||||||
|
|
||||||
def last_insert_id(self, cursor, table_name, pk_name):
|
def last_insert_id(self, cursor, table_name, pk_name):
|
||||||
"""
|
"""
|
||||||
Given a cursor object that has just performed an INSERT statement into
|
Given a cursor object that has just performed an INSERT statement into
|
||||||
|
@ -5,7 +5,7 @@ Requires psycopg 2: http://initd.org/projects/psycopg2
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures
|
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures
|
||||||
from django.db.backends.postgresql.operations import DatabaseOperations
|
from django.db.backends.postgresql.operations import DatabaseOperations as PostgresqlDatabaseOperations
|
||||||
try:
|
try:
|
||||||
import psycopg2 as Database
|
import psycopg2 as Database
|
||||||
import psycopg2.extensions
|
import psycopg2.extensions
|
||||||
@ -21,6 +21,13 @@ psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
|
|||||||
class DatabaseFeatures(BaseDatabaseFeatures):
|
class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
needs_datetime_string_cast = False
|
needs_datetime_string_cast = False
|
||||||
|
|
||||||
|
class DatabaseOperations(PostgresqlDatabaseOperations):
|
||||||
|
def last_executed_query(self, cursor, sql, params):
|
||||||
|
# With psycopg2, cursor objects have a "query" attribute that is the
|
||||||
|
# exact query sent to the database. See docs here:
|
||||||
|
# http://www.initd.org/tracker/psycopg/wiki/psycopg2_documentation#postgresql-status-message-and-executed-query
|
||||||
|
return cursor.query
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
features = DatabaseFeatures()
|
features = DatabaseFeatures()
|
||||||
ops = DatabaseOperations()
|
ops = DatabaseOperations()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import md5
|
import md5
|
||||||
from time import time
|
from time import time
|
||||||
from django.utils.encoding import smart_unicode, force_unicode
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import decimal
|
import decimal
|
||||||
@ -11,7 +10,7 @@ except ImportError:
|
|||||||
class CursorDebugWrapper(object):
|
class CursorDebugWrapper(object):
|
||||||
def __init__(self, cursor, db):
|
def __init__(self, cursor, db):
|
||||||
self.cursor = cursor
|
self.cursor = cursor
|
||||||
self.db = db
|
self.db = db # Instance of a BaseDatabaseWrapper subclass
|
||||||
|
|
||||||
def execute(self, sql, params=()):
|
def execute(self, sql, params=()):
|
||||||
start = time()
|
start = time()
|
||||||
@ -19,8 +18,9 @@ class CursorDebugWrapper(object):
|
|||||||
return self.cursor.execute(sql, params)
|
return self.cursor.execute(sql, params)
|
||||||
finally:
|
finally:
|
||||||
stop = time()
|
stop = time()
|
||||||
|
sql = self.db.ops.last_executed_query(self.cursor, sql, params)
|
||||||
self.db.queries.append({
|
self.db.queries.append({
|
||||||
'sql': smart_unicode(sql) % convert_args(params),
|
'sql': sql,
|
||||||
'time': "%.3f" % (stop - start),
|
'time': "%.3f" % (stop - start),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class CursorDebugWrapper(object):
|
|||||||
finally:
|
finally:
|
||||||
stop = time()
|
stop = time()
|
||||||
self.db.queries.append({
|
self.db.queries.append({
|
||||||
'sql': 'MANY: ' + sql + ' ' + smart_unicode(tuple(param_list)),
|
'sql': '%s times: %s' % (len(param_list), sql),
|
||||||
'time': "%.3f" % (stop - start),
|
'time': "%.3f" % (stop - start),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -41,16 +41,6 @@ class CursorDebugWrapper(object):
|
|||||||
else:
|
else:
|
||||||
return getattr(self.cursor, attr)
|
return getattr(self.cursor, attr)
|
||||||
|
|
||||||
def convert_args(args):
|
|
||||||
"""
|
|
||||||
Convert sequence or dictionary to contain unicode values.
|
|
||||||
"""
|
|
||||||
to_unicode = lambda s: force_unicode(s, strings_only=True)
|
|
||||||
if isinstance(args, (list, tuple)):
|
|
||||||
return tuple([to_unicode(val) for val in args])
|
|
||||||
else:
|
|
||||||
return dict([(to_unicode(k), to_unicode(v)) for k, v in args.items()])
|
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
# Converters from database (string) to Python #
|
# Converters from database (string) to Python #
|
||||||
###############################################
|
###############################################
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
"""
|
"""
|
||||||
Field classes
|
Field classes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
# Python 2.3 fallbacks
|
||||||
|
try:
|
||||||
|
from decimal import Decimal, DecimalException
|
||||||
|
except ImportError:
|
||||||
|
from django.utils._decimal import Decimal, DecimalException
|
||||||
|
try:
|
||||||
|
set
|
||||||
|
except NameError:
|
||||||
|
from sets import Set as set
|
||||||
|
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext
|
||||||
from django.utils.encoding import StrAndUnicode, smart_unicode
|
from django.utils.encoding import StrAndUnicode, smart_unicode
|
||||||
@ -13,18 +22,14 @@ from django.utils.encoding import StrAndUnicode, smart_unicode
|
|||||||
from util import ErrorList, ValidationError
|
from util import ErrorList, ValidationError
|
||||||
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput
|
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput
|
||||||
|
|
||||||
try:
|
|
||||||
from decimal import Decimal, DecimalException
|
|
||||||
except ImportError:
|
|
||||||
from django.utils._decimal import Decimal, DecimalException
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'Field', 'CharField', 'IntegerField',
|
'Field', 'CharField', 'IntegerField',
|
||||||
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
|
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
|
||||||
'DEFAULT_TIME_INPUT_FORMATS', 'TimeField',
|
'DEFAULT_TIME_INPUT_FORMATS', 'TimeField',
|
||||||
'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField',
|
'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField',
|
||||||
'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField',
|
'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField',
|
||||||
'ChoiceField', 'NullBooleanField', 'MultipleChoiceField',
|
'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
|
||||||
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
|
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
|
||||||
'SplitDateTimeField', 'IPAddressField',
|
'SplitDateTimeField', 'IPAddressField',
|
||||||
)
|
)
|
||||||
@ -32,15 +37,6 @@ __all__ = (
|
|||||||
# These values, if given to to_python(), will trigger the self.required check.
|
# These values, if given to to_python(), will trigger the self.required check.
|
||||||
EMPTY_VALUES = (None, '')
|
EMPTY_VALUES = (None, '')
|
||||||
|
|
||||||
try:
|
|
||||||
set
|
|
||||||
except NameError:
|
|
||||||
from sets import Set as set # Python 2.3 fallback
|
|
||||||
|
|
||||||
try:
|
|
||||||
from decimal import Decimal
|
|
||||||
except ImportError:
|
|
||||||
from django.utils._decimal import Decimal # Python 2.3 fallback
|
|
||||||
|
|
||||||
class Field(object):
|
class Field(object):
|
||||||
widget = TextInput # Default widget to use when rendering this type of Field.
|
widget = TextInput # Default widget to use when rendering this type of Field.
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
"Translation helper functions"
|
"Translation helper functions"
|
||||||
|
|
||||||
import os, re, sys
|
import locale
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
import gettext as gettext_module
|
import gettext as gettext_module
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
from django.utils.encoding import force_unicode
|
from django.utils.encoding import force_unicode
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -25,15 +29,25 @@ _active = {}
|
|||||||
# The default translation is based on the settings file.
|
# The default translation is based on the settings file.
|
||||||
_default = None
|
_default = None
|
||||||
|
|
||||||
# This is a cache for accept-header to translation object mappings to prevent
|
# This is a cache for normalised accept-header languages to prevent multiple
|
||||||
# the accept parser to run multiple times for one user.
|
# file lookups when checking the same locale on repeated requests.
|
||||||
_accepted = {}
|
_accepted = {}
|
||||||
|
|
||||||
def to_locale(language):
|
# Format of Accept-Language header values. From RFC 2616, section 14.4 and 3.9.
|
||||||
|
accept_language_re = re.compile(r'''
|
||||||
|
([A-Za-z]{1,8}(?:-[A-Za-z]{1,8})*|\*) # "en", "en-au", "x-y-z", "*"
|
||||||
|
(?:;q=(0(?:\.\d{,3})?|1(?:.0{,3})?))? # Optional "q=1.00", "q=0.8"
|
||||||
|
(?:\s*,\s*|$) # Multiple accepts per header.
|
||||||
|
''', re.VERBOSE)
|
||||||
|
|
||||||
|
def to_locale(language, to_lower=False):
|
||||||
"Turns a language name (en-us) into a locale name (en_US)."
|
"Turns a language name (en-us) into a locale name (en_US)."
|
||||||
p = language.find('-')
|
p = language.find('-')
|
||||||
if p >= 0:
|
if p >= 0:
|
||||||
return language[:p].lower()+'_'+language[p+1:].upper()
|
if to_lower:
|
||||||
|
return language[:p].lower()+'_'+language[p+1:].lower()
|
||||||
|
else:
|
||||||
|
return language[:p].lower()+'_'+language[p+1:].upper()
|
||||||
else:
|
else:
|
||||||
return language.lower()
|
return language.lower()
|
||||||
|
|
||||||
@ -334,46 +348,40 @@ def get_language_from_request(request):
|
|||||||
if lang_code in supported and lang_code is not None and check_for_language(lang_code):
|
if lang_code in supported and lang_code is not None and check_for_language(lang_code):
|
||||||
return lang_code
|
return lang_code
|
||||||
|
|
||||||
lang_code = request.COOKIES.get('django_language', None)
|
lang_code = request.COOKIES.get('django_language')
|
||||||
if lang_code in supported and lang_code is not None and check_for_language(lang_code):
|
if lang_code and lang_code in supported and check_for_language(lang_code):
|
||||||
return lang_code
|
return lang_code
|
||||||
|
|
||||||
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', None)
|
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
|
||||||
if accept is not None:
|
for lang, unused in parse_accept_lang_header(accept):
|
||||||
|
if lang == '*':
|
||||||
|
break
|
||||||
|
|
||||||
t = _accepted.get(accept, None)
|
# We have a very restricted form for our language files (no encoding
|
||||||
if t is not None:
|
# specifier, since they all must be UTF-8 and only one possible
|
||||||
return t
|
# language each time. So we avoid the overhead of gettext.find() and
|
||||||
|
# look up the MO file manually.
|
||||||
|
|
||||||
def _parsed(el):
|
normalized = locale.locale_alias.get(to_locale(lang, True))
|
||||||
p = el.find(';q=')
|
if not normalized:
|
||||||
if p >= 0:
|
continue
|
||||||
lang = el[:p].strip()
|
|
||||||
order = int(float(el[p+3:].strip())*100)
|
|
||||||
else:
|
|
||||||
lang = el
|
|
||||||
order = 100
|
|
||||||
p = lang.find('-')
|
|
||||||
if p >= 0:
|
|
||||||
mainlang = lang[:p]
|
|
||||||
else:
|
|
||||||
mainlang = lang
|
|
||||||
return (lang, mainlang, order)
|
|
||||||
|
|
||||||
langs = [_parsed(el) for el in accept.split(',')]
|
# Remove the default encoding from locale_alias
|
||||||
langs.sort(lambda a,b: -1*cmp(a[2], b[2]))
|
normalized = normalized.split('.')[0]
|
||||||
|
|
||||||
for lang, mainlang, order in langs:
|
if normalized in _accepted:
|
||||||
if lang in supported or mainlang in supported:
|
# We've seen this locale before and have an MO file for it, so no
|
||||||
langfile = gettext_module.find('django', globalpath, [to_locale(lang)])
|
# need to check again.
|
||||||
if langfile:
|
return _accepted[normalized]
|
||||||
# reconstruct the actual language from the language
|
|
||||||
# filename, because otherwise we might incorrectly
|
for lang in (normalized, normalized.split('_')[0]):
|
||||||
# report de_DE if we only have de available, but
|
if lang not in supported:
|
||||||
# did find de_DE because of language normalization
|
continue
|
||||||
lang = langfile[len(globalpath):].split(os.path.sep)[1]
|
langfile = os.path.join(globalpath, lang, 'LC_MESSAGES',
|
||||||
_accepted[accept] = lang
|
'django.mo')
|
||||||
return lang
|
if os.path.exists(langfile):
|
||||||
|
_accepted[normalized] = lang
|
||||||
|
return lang
|
||||||
|
|
||||||
return settings.LANGUAGE_CODE
|
return settings.LANGUAGE_CODE
|
||||||
|
|
||||||
@ -505,3 +513,23 @@ def templatize(src):
|
|||||||
out.write(blankout(t.contents, 'X'))
|
out.write(blankout(t.contents, 'X'))
|
||||||
return out.getvalue()
|
return out.getvalue()
|
||||||
|
|
||||||
|
def parse_accept_lang_header(lang_string):
|
||||||
|
"""
|
||||||
|
Parses the lang_string, which is the body of an HTTP Accept-Language
|
||||||
|
header, and returns a list of (lang, q-value), ordered by 'q' values.
|
||||||
|
|
||||||
|
Any format errors in lang_string results in an empty list being returned.
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
pieces = accept_language_re.split(lang_string)
|
||||||
|
if pieces[-1]:
|
||||||
|
return []
|
||||||
|
for i in range(0, len(pieces) - 1, 3):
|
||||||
|
first, lang, priority = pieces[i : i + 3]
|
||||||
|
if first:
|
||||||
|
return []
|
||||||
|
priority = priority and float(priority) or 1.0
|
||||||
|
result.append((lang, priority))
|
||||||
|
result.sort(lambda x, y: -cmp(x[1], y[1]))
|
||||||
|
return result
|
||||||
|
|
||||||
|
@ -741,22 +741,25 @@ Customized actions
|
|||||||
|
|
||||||
**New in Django development version**
|
**New in Django development version**
|
||||||
|
|
||||||
If you want to add an action of your own to ``manage.py``, you can.
|
Applications can register their own actions with ``manage.py``. For example,
|
||||||
Simply add a ``management/commands`` directory to your application.
|
you might want to add a ``manage.py`` action for a Django app that you're
|
||||||
Each python module in that directory will be discovered and registered as
|
distributing.
|
||||||
|
|
||||||
|
To do this, just add a ``management/commands`` directory to your application.
|
||||||
|
Each Python module in that directory will be auto-discovered and registered as
|
||||||
a command that can be executed as an action when you run ``manage.py``::
|
a command that can be executed as an action when you run ``manage.py``::
|
||||||
|
|
||||||
/fancy_blog
|
blog/
|
||||||
__init__.py
|
__init__.py
|
||||||
models.py
|
models.py
|
||||||
/management
|
management/
|
||||||
__init__.py
|
__init__.py
|
||||||
/commands
|
commands/
|
||||||
__init__.py
|
__init__.py
|
||||||
explode.py
|
explode.py
|
||||||
views.py
|
views.py
|
||||||
|
|
||||||
In this example, ``explode`` command will be made available to any project
|
In this example, the ``explode`` command will be made available to any project
|
||||||
that includes the ``fancy_blog`` application in ``settings.INSTALLED_APPS``.
|
that includes the ``fancy_blog`` application in ``settings.INSTALLED_APPS``.
|
||||||
|
|
||||||
The ``explode.py`` module has only one requirement -- it must define a class
|
The ``explode.py`` module has only one requirement -- it must define a class
|
||||||
|
@ -26,7 +26,6 @@ There were some problems with form translations in #3600
|
|||||||
Translations are done at rendering time, so multi-lingual apps can define forms
|
Translations are done at rendering time, so multi-lingual apps can define forms
|
||||||
early and still send back the right translation.
|
early and still send back the right translation.
|
||||||
|
|
||||||
# XFAIL
|
|
||||||
>>> activate('de')
|
>>> activate('de')
|
||||||
>>> print f.as_p()
|
>>> print f.as_p()
|
||||||
<p><label for="id_username">Benutzername:</label> <input id="id_username" type="text" name="username" maxlength="10" /></p>
|
<p><label for="id_username">Benutzername:</label> <input id="id_username" type="text" name="username" maxlength="10" /></p>
|
||||||
|
57
tests/regressiontests/i18n/misc.py
Normal file
57
tests/regressiontests/i18n/misc.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
tests = """
|
||||||
|
>>> from django.utils.translation.trans_real import parse_accept_lang_header
|
||||||
|
>>> p = parse_accept_lang_header
|
||||||
|
|
||||||
|
Good headers.
|
||||||
|
>>> p('de')
|
||||||
|
[('de', 1.0)]
|
||||||
|
>>> p('en-AU')
|
||||||
|
[('en-AU', 1.0)]
|
||||||
|
>>> p('*;q=1.00')
|
||||||
|
[('*', 1.0)]
|
||||||
|
>>> p('en-AU;q=0.123')
|
||||||
|
[('en-AU', 0.123)]
|
||||||
|
>>> p('en-au;q=0.1')
|
||||||
|
[('en-au', 0.10000000000000001)]
|
||||||
|
>>> p('en-au;q=1.0')
|
||||||
|
[('en-au', 1.0)]
|
||||||
|
>>> p('da, en-gb;q=0.25, en;q=0.5')
|
||||||
|
[('da', 1.0), ('en', 0.5), ('en-gb', 0.25)]
|
||||||
|
>>> p('en-au-xx')
|
||||||
|
[('en-au-xx', 1.0)]
|
||||||
|
>>> p('de,en-au;q=0.75,en-us;q=0.5,en;q=0.25,es;q=0.125,fa;q=0.125')
|
||||||
|
[('de', 1.0), ('en-au', 0.75), ('en-us', 0.5), ('en', 0.25), ('es', 0.125), ('fa', 0.125)]
|
||||||
|
>>> p('*')
|
||||||
|
[('*', 1.0)]
|
||||||
|
>>> p('de;q=0.')
|
||||||
|
[('de', 1.0)]
|
||||||
|
>>> p('')
|
||||||
|
[]
|
||||||
|
|
||||||
|
Bad headers; should always return [].
|
||||||
|
>>> p('en-gb;q=1.0000')
|
||||||
|
[]
|
||||||
|
>>> p('en;q=0.1234')
|
||||||
|
[]
|
||||||
|
>>> p('en;q=.2')
|
||||||
|
[]
|
||||||
|
>>> p('abcdefghi-au')
|
||||||
|
[]
|
||||||
|
>>> p('**')
|
||||||
|
[]
|
||||||
|
>>> p('en,,gb')
|
||||||
|
[]
|
||||||
|
>>> p('en-au;q=0.1.0')
|
||||||
|
[]
|
||||||
|
>>> p('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZ,en')
|
||||||
|
[]
|
||||||
|
>>> p('da, en-gb;q=0.8, en;q=0.7,#')
|
||||||
|
[]
|
||||||
|
>>> p('de;q=2.0')
|
||||||
|
[]
|
||||||
|
>>> p('de;q=0.a')
|
||||||
|
[]
|
||||||
|
>>> p('')
|
||||||
|
[]
|
||||||
|
|
||||||
|
"""
|
@ -1,6 +1,7 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
import misc
|
||||||
|
|
||||||
ur"""
|
regressions = ur"""
|
||||||
Format string interpolation should work with *_lazy objects.
|
Format string interpolation should work with *_lazy objects.
|
||||||
|
|
||||||
>>> from django.utils.translation import ugettext_lazy, activate, deactivate, gettext_lazy
|
>>> from django.utils.translation import ugettext_lazy, activate, deactivate, gettext_lazy
|
||||||
@ -39,3 +40,8 @@ unicode(string_concat(...)) should not raise a TypeError - #4796
|
|||||||
>>> unicode(django.utils.translation.string_concat("dja", "ngo"))
|
>>> unicode(django.utils.translation.string_concat("dja", "ngo"))
|
||||||
u'django'
|
u'django'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
__test__ = {
|
||||||
|
'regressions': regressions,
|
||||||
|
'misc': misc.tests,
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@ urlpatterns = patterns('',
|
|||||||
# Test urls for testing reverse lookups
|
# Test urls for testing reverse lookups
|
||||||
(r'^$', views.index),
|
(r'^$', views.index),
|
||||||
(r'^client/(\d+)/$', views.client),
|
(r'^client/(\d+)/$', views.client),
|
||||||
(r'^client/(\d+)/(?P<action>[^/]+)/$', views.client_action),
|
(r'^client/(?P<id>\d+)/(?P<action>[^/]+)/$', views.client_action),
|
||||||
url(r'^named-client/(\d+)/$', views.client, name="named.client"),
|
url(r'^named-client/(\d+)/$', views.client, name="named.client"),
|
||||||
|
|
||||||
# Unicode strings are permitted everywhere.
|
# Unicode strings are permitted everywhere.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user