mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
boulder-oracle-sprint: Merged to [4839], part two.
git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@4842 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d2c03a3779
commit
1f3fc7bc9f
1
AUTHORS
1
AUTHORS
@ -44,6 +44,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
adurdin@gmail.com
|
adurdin@gmail.com
|
||||||
Andreas
|
Andreas
|
||||||
andy@jadedplanet.net
|
andy@jadedplanet.net
|
||||||
|
Fabrice Aneche <akh@nobugware.com>
|
||||||
ant9000@netwise.it
|
ant9000@netwise.it
|
||||||
David Ascher <http://ascher.ca/>
|
David Ascher <http://ascher.ca/>
|
||||||
Arthur <avandorp@gmail.com>
|
Arthur <avandorp@gmail.com>
|
||||||
|
@ -1 +1 @@
|
|||||||
VERSION = (0, 96, 'pre')
|
VERSION = (0, 96, None)
|
||||||
|
@ -45,7 +45,7 @@ class Permission(models.Model):
|
|||||||
ordering = ('content_type', 'codename')
|
ordering = ('content_type', 'codename')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s | %s" % (self.content_type, self.name)
|
return "%s | %s | %s" % (self.content_type.app_label, self.content_type, self.name)
|
||||||
|
|
||||||
class Group(models.Model):
|
class Group(models.Model):
|
||||||
"""Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
|
"""Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
|
||||||
|
0
django/contrib/localflavor/fr/__init__.py
Normal file
0
django/contrib/localflavor/fr/__init__.py
Normal file
44
django/contrib/localflavor/fr/forms.py
Normal file
44
django/contrib/localflavor/fr/forms.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
"""
|
||||||
|
FR-specific Form helpers
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.newforms import ValidationError
|
||||||
|
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
||||||
|
from django.newforms.util import smart_unicode
|
||||||
|
from django.utils.translation import gettext
|
||||||
|
import re
|
||||||
|
|
||||||
|
phone_digits_re = re.compile(r'^0\d(\s|\.)?(\d{2}(\s|\.)?){3}\d{2}$')
|
||||||
|
|
||||||
|
class FRZipCodeField(RegexField):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(FRZipCodeField, self).__init__(r'^\d{5}$',
|
||||||
|
max_length=None, min_length=None,
|
||||||
|
error_message=gettext(u'Enter a zip code in the format XXXXX.'),
|
||||||
|
*args, **kwargs)
|
||||||
|
|
||||||
|
class FRPhoneNumberField(Field):
|
||||||
|
"""
|
||||||
|
Validate local French phone number (not international ones)
|
||||||
|
The correct format is '0X XX XX XX XX'.
|
||||||
|
'0X.XX.XX.XX.XX' and '0XXXXXXXXX' validate but are corrected to
|
||||||
|
'0X XX XX XX XX'.
|
||||||
|
"""
|
||||||
|
def clean(self, value):
|
||||||
|
super(FRPhoneNumberField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
value = re.sub('(\.|\s)', '', smart_unicode(value))
|
||||||
|
m = phone_digits_re.search(value)
|
||||||
|
if m:
|
||||||
|
return u'%s %s %s %s %s' % (value[0:2], value[2:4], value[4:6], value[6:8], value[8:10])
|
||||||
|
raise ValidationError(u'Phone numbers must be in 0X XX XX XX XX format.')
|
||||||
|
|
||||||
|
class FRDepartmentSelect(Select):
|
||||||
|
"""
|
||||||
|
A Select widget that uses a list of FR departments as its choices.
|
||||||
|
"""
|
||||||
|
def __init__(self, attrs=None):
|
||||||
|
from fr_department import DEPARTMENT_ASCII_CHOICES # relative import
|
||||||
|
super(FRDepartmentSelect, self).__init__(attrs, choices=DEPARTMENT_ASCII_CHOICES)
|
||||||
|
|
112
django/contrib/localflavor/fr/fr_department.py
Normal file
112
django/contrib/localflavor/fr/fr_department.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
DEPARTMENT_ASCII_CHOICES = (
|
||||||
|
('01', '01 - Ain'),
|
||||||
|
('02', '02 - Aisne'),
|
||||||
|
('03', '03 - Allier'),
|
||||||
|
('04', '04 - Alpes-de-Haute-Provence'),
|
||||||
|
('05', '05 - Hautes-Alpes'),
|
||||||
|
('06', '06 - Alpes-Maritimes'),
|
||||||
|
('07', '07 - Ardeche'),
|
||||||
|
('08', '08 - Ardennes'),
|
||||||
|
('09', '09 - Ariege'),
|
||||||
|
('10', '10 - Aube'),
|
||||||
|
('11', '11 - Aude'),
|
||||||
|
('12', '12 - Aveyron'),
|
||||||
|
('13', '13 - Bouches-du-Rhone'),
|
||||||
|
('14', '14 - Calvados'),
|
||||||
|
('15', '15 - Cantal'),
|
||||||
|
('16', '16 - Charente'),
|
||||||
|
('17', '17 - Charente-Maritime'),
|
||||||
|
('18', '18 - Cher'),
|
||||||
|
('19', '19 - Correze'),
|
||||||
|
('21', '21 - Cote-d\'Or'),
|
||||||
|
('22', '22 - Cotes-d\'Armor'),
|
||||||
|
('23', '23 - Creuse'),
|
||||||
|
('24', '24 - Dordogne'),
|
||||||
|
('25', '25 - Doubs'),
|
||||||
|
('26', '26 - Drome'),
|
||||||
|
('27', '27 - Eure'),
|
||||||
|
('28', '28 - Eure-et-Loire'),
|
||||||
|
('29', '29 - Finistere'),
|
||||||
|
('2A', '2A - Corse-du-Sud'),
|
||||||
|
('2B', '2B - Haute-Corse'),
|
||||||
|
('30', '30 - Gard'),
|
||||||
|
('31', '31 - Haute-Garonne'),
|
||||||
|
('32', '32 - Gers'),
|
||||||
|
('33', '33 - Gironde'),
|
||||||
|
('34', '34 - Herault'),
|
||||||
|
('35', '35 - Ille-et-Vilaine'),
|
||||||
|
('36', '36 - Indre'),
|
||||||
|
('37', '37 - Indre-et-Loire'),
|
||||||
|
('38', '38 - Isere'),
|
||||||
|
('39', '39 - Jura'),
|
||||||
|
('40', '40 - Landes'),
|
||||||
|
('41', '41 - Loir-et-Cher'),
|
||||||
|
('42', '42 - Loire'),
|
||||||
|
('43', '43 - Haute-Loire'),
|
||||||
|
('44', '44 - Loire-Atlantique'),
|
||||||
|
('45', '45 - Loiret'),
|
||||||
|
('46', '46 - Lot'),
|
||||||
|
('47', '47 - Lot-et-Garonne'),
|
||||||
|
('48', '48 - Lozere'),
|
||||||
|
('49', '49 - Maine-et-Loire'),
|
||||||
|
('50', '50 - Manche'),
|
||||||
|
('51', '51 - Marne'),
|
||||||
|
('52', '52 - Haute-Marne'),
|
||||||
|
('53', '53 - Mayenne'),
|
||||||
|
('54', '54 - Meurthe-et-Moselle'),
|
||||||
|
('55', '55 - Meuse'),
|
||||||
|
('56', '56 - Morbihan'),
|
||||||
|
('57', '57 - Moselle'),
|
||||||
|
('58', '58 - Nievre'),
|
||||||
|
('59', '59 - Nord'),
|
||||||
|
('60', '60 - Oise'),
|
||||||
|
('61', '61 - Orne'),
|
||||||
|
('62', '62 - Pas-de-Calais'),
|
||||||
|
('63', '63 - Puy-de-Dome'),
|
||||||
|
('64', '64 - Pyrenees-Atlantiques'),
|
||||||
|
('65', '65 - Hautes-Pyrenees'),
|
||||||
|
('66', '66 - Pyrenees-Orientales'),
|
||||||
|
('67', '67 - Bas-Rhin'),
|
||||||
|
('68', '68 - Haut-Rhin'),
|
||||||
|
('69', '69 - Rhone'),
|
||||||
|
('70', '70 - Haute-Saone'),
|
||||||
|
('71', '71 - Saone-et-Loire'),
|
||||||
|
('72', '72 - Sarthe'),
|
||||||
|
('73', '73 - Savoie'),
|
||||||
|
('74', '74 - Haute-Savoie'),
|
||||||
|
('75', '75 - Paris'),
|
||||||
|
('76', '76 - Seine-Maritime'),
|
||||||
|
('77', '77 - Seine-et-Marne'),
|
||||||
|
('78', '78 - Yvelines'),
|
||||||
|
('79', '79 - Deux-Sevres'),
|
||||||
|
('80', '80 - Somme'),
|
||||||
|
('81', '81 - Tarn'),
|
||||||
|
('82', '82 - Tarn-et-Garonne'),
|
||||||
|
('83', '83 - Var'),
|
||||||
|
('84', '84 - Vaucluse'),
|
||||||
|
('85', '85 - Vendee'),
|
||||||
|
('86', '86 - Vienne'),
|
||||||
|
('87', '87 - Haute-Vienne'),
|
||||||
|
('88', '88 - Vosges'),
|
||||||
|
('89', '89 - Yonne'),
|
||||||
|
('90', '90 - Territoire de Belfort'),
|
||||||
|
('91', '91 - Essonne'),
|
||||||
|
('92', '92 - Hauts-de-Seine'),
|
||||||
|
('93', '93 - Seine-Saint-Denis'),
|
||||||
|
('94', '94 - Val-de-Marne'),
|
||||||
|
('95', '95 - Val-d\'Oise'),
|
||||||
|
('2A', '2A - Corse du sud'),
|
||||||
|
('2B', '2B - Haute Corse'),
|
||||||
|
('971', '971 - Guadeloupe'),
|
||||||
|
('972', '972 - Martinique'),
|
||||||
|
('973', '973 - Guyane'),
|
||||||
|
('974', '974 - La Reunion'),
|
||||||
|
('975', '975 - Saint-Pierre-et-Miquelon'),
|
||||||
|
('976', '976 - Mayotte'),
|
||||||
|
('984', '984 - Terres Australes et Antarctiques'),
|
||||||
|
('986', '986 - Wallis et Futuna'),
|
||||||
|
('987', '987 - Polynesie Francaise'),
|
||||||
|
('988', '988 - Nouvelle-Caledonie'),
|
||||||
|
)
|
0
django/contrib/localflavor/jp/__init__.py
Normal file
0
django/contrib/localflavor/jp/__init__.py
Normal file
38
django/contrib/localflavor/jp/forms.py
Normal file
38
django/contrib/localflavor/jp/forms.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
"""
|
||||||
|
JP-specific Form helpers
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.core import validators
|
||||||
|
from django.newforms import ValidationError
|
||||||
|
from django.utils.translation import gettext
|
||||||
|
from django.newforms.fields import RegexField, Select
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
class JPPostalCodeField(RegexField):
|
||||||
|
"""
|
||||||
|
A form field that validates its input is a Japanese postcode.
|
||||||
|
|
||||||
|
Accepts 7 digits, with or without a hyphen.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(JPPostalCodeField, self).__init__(r'^\d{3}-\d{4}$|^\d{7}$',
|
||||||
|
max_length=None, min_length=None,
|
||||||
|
error_message=gettext(u'Enter a postal code in the format XXXXXXX or XXX-XXXX.'),
|
||||||
|
*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
"""
|
||||||
|
Validates the input and returns a string that contains only numbers.
|
||||||
|
Returns an empty string for empty values.
|
||||||
|
"""
|
||||||
|
v = super(JPPostalCodeField, self).clean(value)
|
||||||
|
return v.replace('-', '')
|
||||||
|
|
||||||
|
class JPPrefectureSelect(Select):
|
||||||
|
"""
|
||||||
|
A Select widget that uses a list of Japanese prefectures as its choices.
|
||||||
|
"""
|
||||||
|
def __init__(self, attrs=None):
|
||||||
|
from jp_prefectures import JP_PREFECTURES
|
||||||
|
super(JPPrefectureSelect, self).__init__(attrs, choices=JP_PREFECTURES)
|
51
django/contrib/localflavor/jp/jp_prefectures.py
Normal file
51
django/contrib/localflavor/jp/jp_prefectures.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
from django.utils.translation import gettext_lazy as gettext_lazy
|
||||||
|
|
||||||
|
JP_PREFECTURES = (
|
||||||
|
('hokkaido', gettext_lazy('Hokkaido'),),
|
||||||
|
('aomori', gettext_lazy('Aomori'),),
|
||||||
|
('iwate', gettext_lazy('Iwate'),),
|
||||||
|
('miyagi', gettext_lazy('Miyagi'),),
|
||||||
|
('akita', gettext_lazy('Akita'),),
|
||||||
|
('yamagata', gettext_lazy('Yamagata'),),
|
||||||
|
('fukushima', gettext_lazy('Fukushima'),),
|
||||||
|
('ibaraki', gettext_lazy('Ibaraki'),),
|
||||||
|
('tochigi', gettext_lazy('Tochigi'),),
|
||||||
|
('gunma', gettext_lazy('Gunma'),),
|
||||||
|
('saitama', gettext_lazy('Saitama'),),
|
||||||
|
('chiba', gettext_lazy('Chiba'),),
|
||||||
|
('tokyo', gettext_lazy('Tokyo'),),
|
||||||
|
('kanagawa', gettext_lazy('Kanagawa'),),
|
||||||
|
('yamanashi', gettext_lazy('Yamanashi'),),
|
||||||
|
('nagano', gettext_lazy('Nagano'),),
|
||||||
|
('niigata', gettext_lazy('Niigata'),),
|
||||||
|
('toyama', gettext_lazy('Toyama'),),
|
||||||
|
('ishikawa', gettext_lazy('Ishikawa'),),
|
||||||
|
('fukui', gettext_lazy('Fukui'),),
|
||||||
|
('gifu', gettext_lazy('Gifu'),),
|
||||||
|
('shizuoka', gettext_lazy('Shizuoka'),),
|
||||||
|
('aichi', gettext_lazy('Aichi'),),
|
||||||
|
('mie', gettext_lazy('Mie'),),
|
||||||
|
('shiga', gettext_lazy('Shiga'),),
|
||||||
|
('kyoto', gettext_lazy('Kyoto'),),
|
||||||
|
('osaka', gettext_lazy('Osaka'),),
|
||||||
|
('hyogo', gettext_lazy('Hyogo'),),
|
||||||
|
('nara', gettext_lazy('Nara'),),
|
||||||
|
('wakayama', gettext_lazy('Wakayama'),),
|
||||||
|
('tottori', gettext_lazy('Tottori'),),
|
||||||
|
('shimane', gettext_lazy('Shimane'),),
|
||||||
|
('okayama', gettext_lazy('Okayama'),),
|
||||||
|
('hiroshima', gettext_lazy('Hiroshima'),),
|
||||||
|
('yamaguchi', gettext_lazy('Yamaguchi'),),
|
||||||
|
('tokushima', gettext_lazy('Tokushima'),),
|
||||||
|
('kagawa', gettext_lazy('Kagawa'),),
|
||||||
|
('ehime', gettext_lazy('Ehime'),),
|
||||||
|
('kochi', gettext_lazy('Kochi'),),
|
||||||
|
('fukuoka', gettext_lazy('Fukuoka'),),
|
||||||
|
('saga', gettext_lazy('Saga'),),
|
||||||
|
('nagasaki', gettext_lazy('Nagasaki'),),
|
||||||
|
('kumamoto', gettext_lazy('Kumamoto'),),
|
||||||
|
('oita', gettext_lazy('Oita'),),
|
||||||
|
('miyazaki', gettext_lazy('Miyazaki'),),
|
||||||
|
('kagoshima', gettext_lazy('Kagoshima'),),
|
||||||
|
('okinawa', gettext_lazy('Okinawa'),),
|
||||||
|
)
|
7
django/core/cache/backends/memcached.py
vendored
7
django/core/cache/backends/memcached.py
vendored
@ -3,9 +3,12 @@
|
|||||||
from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
|
from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import memcache
|
import cmemcache as memcache
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise InvalidCacheBackendError, "Memcached cache backend requires the 'memcache' library"
|
try:
|
||||||
|
import memcache
|
||||||
|
except:
|
||||||
|
raise InvalidCacheBackendError("Memcached cache backend requires either the 'memcache' or 'cmemcache' library")
|
||||||
|
|
||||||
class CacheClass(BaseCache):
|
class CacheClass(BaseCache):
|
||||||
def __init__(self, server, params):
|
def __init__(self, server, params):
|
||||||
|
@ -299,7 +299,7 @@ def get_sql_delete(app):
|
|||||||
from django.db.backends.util import truncate_name
|
from django.db.backends.util import truncate_name
|
||||||
introspection = get_introspection_module()
|
introspection = get_introspection_module()
|
||||||
|
|
||||||
# This should work even if a connecton isn't available
|
# This should work even if a connection isn't available
|
||||||
try:
|
try:
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
except:
|
except:
|
||||||
@ -486,7 +486,7 @@ def get_sql_indexes_for_model(model):
|
|||||||
unique = f.unique and 'UNIQUE ' or ''
|
unique = f.unique and 'UNIQUE ' or ''
|
||||||
output.append(
|
output.append(
|
||||||
style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \
|
style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \
|
||||||
truncate_name(style.SQL_TABLE('%s_%s' % (model._meta.db_table, f.column)), backend.get_max_name_length()) + ' ' + \
|
style.SQL_TABLE(backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \
|
||||||
style.SQL_KEYWORD('ON') + ' ' + \
|
style.SQL_KEYWORD('ON') + ' ' + \
|
||||||
style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \
|
style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \
|
||||||
"(%s);" % style.SQL_FIELD(backend.quote_name(f.column))
|
"(%s);" % style.SQL_FIELD(backend.quote_name(f.column))
|
||||||
@ -546,6 +546,7 @@ def syncdb(verbosity=1, interactive=True):
|
|||||||
created_models = set()
|
created_models = set()
|
||||||
pending_references = {}
|
pending_references = {}
|
||||||
|
|
||||||
|
# Create the tables for each model
|
||||||
for app in models.get_apps():
|
for app in models.get_apps():
|
||||||
app_name = app.__name__.split('.')[-2]
|
app_name = app.__name__.split('.')[-2]
|
||||||
model_list = models.get_models(app)
|
model_list = models.get_models(app)
|
||||||
@ -567,6 +568,11 @@ def syncdb(verbosity=1, interactive=True):
|
|||||||
cursor.execute(statement)
|
cursor.execute(statement)
|
||||||
table_list.append(table_name_converter(model._meta.db_table))
|
table_list.append(table_name_converter(model._meta.db_table))
|
||||||
|
|
||||||
|
# Create the m2m tables. This must be done after all tables have been created
|
||||||
|
# to ensure that all referred tables will exist.
|
||||||
|
for app in models.get_apps():
|
||||||
|
app_name = app.__name__.split('.')[-2]
|
||||||
|
model_list = models.get_models(app)
|
||||||
for model in model_list:
|
for model in model_list:
|
||||||
if model in created_models:
|
if model in created_models:
|
||||||
sql = _get_many_to_many_sql_for_model(model)
|
sql = _get_many_to_many_sql_for_model(model)
|
||||||
@ -576,7 +582,7 @@ def syncdb(verbosity=1, interactive=True):
|
|||||||
for statement in sql:
|
for statement in sql:
|
||||||
cursor.execute(statement)
|
cursor.execute(statement)
|
||||||
|
|
||||||
transaction.commit_unless_managed()
|
transaction.commit_unless_managed()
|
||||||
|
|
||||||
# Send the post_syncdb signal, so individual apps can do whatever they need
|
# Send the post_syncdb signal, so individual apps can do whatever they need
|
||||||
# to do at this point.
|
# to do at this point.
|
||||||
@ -1383,18 +1389,26 @@ def load_data(fixture_labels, verbosity=1):
|
|||||||
|
|
||||||
app_fixtures = [os.path.join(os.path.dirname(app.__file__),'fixtures') for app in get_apps()]
|
app_fixtures = [os.path.join(os.path.dirname(app.__file__),'fixtures') for app in get_apps()]
|
||||||
for fixture_label in fixture_labels:
|
for fixture_label in fixture_labels:
|
||||||
|
parts = fixture_label.split('.')
|
||||||
|
if len(parts) == 1:
|
||||||
|
fixture_name = fixture_label
|
||||||
|
formats = serializers.get_serializer_formats()
|
||||||
|
else:
|
||||||
|
fixture_name, format = '.'.join(parts[:-1]), parts[-1]
|
||||||
|
if format in serializers.get_serializer_formats():
|
||||||
|
formats = [format]
|
||||||
|
else:
|
||||||
|
formats = []
|
||||||
|
|
||||||
if verbosity > 0:
|
if verbosity > 0:
|
||||||
print "Loading '%s' fixtures..." % fixture_label
|
if formats:
|
||||||
|
print "Loading '%s' fixtures..." % fixture_name
|
||||||
|
else:
|
||||||
|
print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format)
|
||||||
|
|
||||||
for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']:
|
for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']:
|
||||||
if verbosity > 1:
|
if verbosity > 1:
|
||||||
print "Checking %s for fixtures..." % humanize(fixture_dir)
|
print "Checking %s for fixtures..." % humanize(fixture_dir)
|
||||||
parts = fixture_label.split('.')
|
|
||||||
if len(parts) == 1:
|
|
||||||
fixture_name = fixture_label
|
|
||||||
formats = serializers.get_serializer_formats()
|
|
||||||
else:
|
|
||||||
fixture_name, format = '.'.join(parts[:-1]), parts[-1]
|
|
||||||
formats = [format]
|
|
||||||
|
|
||||||
label_found = False
|
label_found = False
|
||||||
for format in formats:
|
for format in formats:
|
||||||
|
@ -10,7 +10,7 @@ class CacheMiddleware(object):
|
|||||||
Only parameter-less GET or HEAD-requests with status code 200 are cached.
|
Only parameter-less GET or HEAD-requests with status code 200 are cached.
|
||||||
|
|
||||||
If CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set to True, only anonymous requests
|
If CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set to True, only anonymous requests
|
||||||
(i.e., those node made by a logged-in user) will be cached. This is a
|
(i.e., those not made by a logged-in user) will be cached. This is a
|
||||||
simple and effective way of avoiding the caching of the Django admin (and
|
simple and effective way of avoiding the caching of the Django admin (and
|
||||||
any other user-specific content).
|
any other user-specific content).
|
||||||
|
|
||||||
|
@ -354,6 +354,23 @@ class WidthRatioNode(Node):
|
|||||||
return ''
|
return ''
|
||||||
return str(int(round(ratio)))
|
return str(int(round(ratio)))
|
||||||
|
|
||||||
|
class WithNode(Node):
|
||||||
|
def __init__(self, var, name, nodelist):
|
||||||
|
self.var = var
|
||||||
|
self.name = name
|
||||||
|
self.nodelist = nodelist
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<WithNode>"
|
||||||
|
|
||||||
|
def render(self, context):
|
||||||
|
val = self.var.resolve(context)
|
||||||
|
context.push()
|
||||||
|
context[self.name] = val
|
||||||
|
output = self.nodelist.render(context)
|
||||||
|
context.pop()
|
||||||
|
return output
|
||||||
|
|
||||||
#@register.tag
|
#@register.tag
|
||||||
def comment(parser, token):
|
def comment(parser, token):
|
||||||
"""
|
"""
|
||||||
@ -595,8 +612,8 @@ def do_if(parser, token):
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
{% if althlete_list %}
|
{% if athlete_list %}
|
||||||
Number of athletes: {{ althete_list|count }}
|
Number of athletes: {{ athlete_list|count }}
|
||||||
{% else %}
|
{% else %}
|
||||||
No athletes.
|
No athletes.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -967,3 +984,23 @@ def widthratio(parser, token):
|
|||||||
return WidthRatioNode(parser.compile_filter(this_value_expr),
|
return WidthRatioNode(parser.compile_filter(this_value_expr),
|
||||||
parser.compile_filter(max_value_expr), max_width)
|
parser.compile_filter(max_value_expr), max_width)
|
||||||
widthratio = register.tag(widthratio)
|
widthratio = register.tag(widthratio)
|
||||||
|
|
||||||
|
#@register.tag
|
||||||
|
def do_with(parser, token):
|
||||||
|
"""
|
||||||
|
Add a value to the context (inside of this block) for caching and easy
|
||||||
|
access. For example::
|
||||||
|
|
||||||
|
{% with person.some_sql_method as total %}
|
||||||
|
{{ total }} object{{ total|pluralize }}
|
||||||
|
{% endwith %}
|
||||||
|
"""
|
||||||
|
bits = list(token.split_contents())
|
||||||
|
if len(bits) != 4 or bits[2] != "as":
|
||||||
|
raise TemplateSyntaxError, "%r expected format is 'value as name'" % tagname
|
||||||
|
var = parser.compile_filter(bits[1])
|
||||||
|
name = bits[3]
|
||||||
|
nodelist = parser.parse(('endwith',))
|
||||||
|
parser.delete_first_token()
|
||||||
|
return WithNode(var, name, nodelist)
|
||||||
|
do_with = register.tag('with', do_with)
|
||||||
|
@ -9,6 +9,13 @@ problems.
|
|||||||
This code lives in ``django/contrib`` in the Django distribution. Here's a
|
This code lives in ``django/contrib`` in the Django distribution. Here's a
|
||||||
rundown of the packages in ``contrib``:
|
rundown of the packages in ``contrib``:
|
||||||
|
|
||||||
|
.. admonition:: Note
|
||||||
|
|
||||||
|
For most of these add-ons -- specifically, the add-ons that include either
|
||||||
|
models or template tags -- you'll need to add the package name (e.g.,
|
||||||
|
``'django.contrib.admin'``) to your ``INSTALLED_APPS`` setting and re-run
|
||||||
|
``manage.py syncdb``.
|
||||||
|
|
||||||
.. _"batteries included" philosophy: http://docs.python.org/tut/node12.html#batteries-included
|
.. _"batteries included" philosophy: http://docs.python.org/tut/node12.html#batteries-included
|
||||||
|
|
||||||
admin
|
admin
|
||||||
@ -51,8 +58,6 @@ See the `csrf documentation`_.
|
|||||||
formtools
|
formtools
|
||||||
=========
|
=========
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
A set of high-level abstractions for Django forms (django.newforms).
|
A set of high-level abstractions for Django forms (django.newforms).
|
||||||
|
|
||||||
django.contrib.formtools.preview
|
django.contrib.formtools.preview
|
||||||
@ -142,8 +147,6 @@ See the `flatpages documentation`_.
|
|||||||
localflavor
|
localflavor
|
||||||
===========
|
===========
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
A collection of various Django snippets that are useful only for a particular
|
A collection of various Django snippets that are useful only for a particular
|
||||||
country or culture. For example, ``django.contrib.localflavor.usa.forms``
|
country or culture. For example, ``django.contrib.localflavor.usa.forms``
|
||||||
contains a ``USZipCodeField`` that you can use to validate U.S. zip codes.
|
contains a ``USZipCodeField`` that you can use to validate U.S. zip codes.
|
||||||
@ -151,13 +154,20 @@ contains a ``USZipCodeField`` that you can use to validate U.S. zip codes.
|
|||||||
markup
|
markup
|
||||||
======
|
======
|
||||||
|
|
||||||
A collection of template filters that implement these common markup languages:
|
A collection of template filters that implement common markup languages:
|
||||||
|
|
||||||
* `Textile`_
|
* ``textile`` -- implements `Textile`_
|
||||||
* `Markdown`_
|
* ``markdown`` -- implements `Markdown`_
|
||||||
* `ReST (ReStructured Text)`_
|
* ``restructuredtext`` -- implements `ReST (ReStructured Text)`_
|
||||||
|
|
||||||
For documentation, read the source code in django/contrib/markup/templatetags/markup.py.
|
In each case, the filter expects formatted markup as a string and returns a
|
||||||
|
string representing the marked-up text. For example, the ``textile`` filter
|
||||||
|
converts text that is marked-up in Textile format to HTML.
|
||||||
|
|
||||||
|
To activate these filters, add ``'django.contrib.markup'`` to your
|
||||||
|
``INSTALLED_APPS`` setting. Once you've done that, use ``{% load markup %}`` in
|
||||||
|
a template, and you'll have access to these filters. For more documentation,
|
||||||
|
read the source code in django/contrib/markup/templatetags/markup.py.
|
||||||
|
|
||||||
.. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29
|
.. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29
|
||||||
.. _Markdown: http://en.wikipedia.org/wiki/Markdown
|
.. _Markdown: http://en.wikipedia.org/wiki/Markdown
|
||||||
|
@ -66,10 +66,19 @@ deleting arbitrary data in the cache. All data is stored directly in memory,
|
|||||||
so there's no overhead of database or filesystem usage.
|
so there's no overhead of database or filesystem usage.
|
||||||
|
|
||||||
After installing Memcached itself, you'll need to install the Memcached Python
|
After installing Memcached itself, you'll need to install the Memcached Python
|
||||||
bindings. They're in a single Python module, memcache.py, available at
|
bindings. Two versions of this are available. Choose and install *one* of the
|
||||||
ftp://ftp.tummy.com/pub/python-memcached/ . If that URL is no longer valid,
|
following modules:
|
||||||
just go to the Memcached Web site (http://www.danga.com/memcached/) and get the
|
|
||||||
Python bindings from the "Client APIs" section.
|
* The fastest available option is a module called ``cmemcache``, available
|
||||||
|
at http://gijsbert.org/cmemcache/ . (This module is only compatible with
|
||||||
|
the Django development version. Django 0.96 is only compatible with the
|
||||||
|
second option, below.)
|
||||||
|
|
||||||
|
* If you can't install ``cmemcache``, you can install ``python-memcached``,
|
||||||
|
available at ftp://ftp.tummy.com/pub/python-memcached/ . If that URL is
|
||||||
|
no longer valid, just go to the Memcached Web site
|
||||||
|
(http://www.danga.com/memcached/) and get the Python bindings from the
|
||||||
|
"Client APIs" section.
|
||||||
|
|
||||||
To use Memcached with Django, set ``CACHE_BACKEND`` to
|
To use Memcached with Django, set ``CACHE_BACKEND`` to
|
||||||
``memcached://ip:port/``, where ``ip`` is the IP address of the Memcached
|
``memcached://ip:port/``, where ``ip`` is the IP address of the Memcached
|
||||||
|
@ -100,8 +100,6 @@ if you're ever curious to see the full list of defaults.
|
|||||||
dumpdata [appname appname ...]
|
dumpdata [appname appname ...]
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Output to standard output all data in the database associated with the named
|
Output to standard output all data in the database associated with the named
|
||||||
application(s).
|
application(s).
|
||||||
|
|
||||||
@ -117,8 +115,6 @@ The output of ``dumpdata`` can be used as input for ``loaddata``.
|
|||||||
flush
|
flush
|
||||||
-----
|
-----
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Return the database to the state it was in immediately after syncdb was
|
Return the database to the state it was in immediately after syncdb was
|
||||||
executed. This means that all data will be removed from the database, any
|
executed. This means that all data will be removed from the database, any
|
||||||
post-synchronization handlers will be re-executed, and the ``initial_data``
|
post-synchronization handlers will be re-executed, and the ``initial_data``
|
||||||
@ -165,18 +161,9 @@ needed.
|
|||||||
``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection
|
``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection
|
||||||
only works in PostgreSQL and with certain types of MySQL tables.
|
only works in PostgreSQL and with certain types of MySQL tables.
|
||||||
|
|
||||||
install [appname appname ...]
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
**Removed in Django development version**
|
|
||||||
|
|
||||||
Executes the equivalent of ``sqlall`` for the given appnames.
|
|
||||||
|
|
||||||
loaddata [fixture fixture ...]
|
loaddata [fixture fixture ...]
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Searches for and loads the contents of the named fixture into the database.
|
Searches for and loads the contents of the named fixture into the database.
|
||||||
|
|
||||||
A *Fixture* is a collection of files that contain the serialized contents of
|
A *Fixture* is a collection of files that contain the serialized contents of
|
||||||
@ -350,14 +337,12 @@ Prints the DROP TABLE SQL statements for the given appnames.
|
|||||||
sqlcustom [appname appname ...]
|
sqlcustom [appname appname ...]
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Prints the custom SQL statements for the given appnames.
|
Prints the custom SQL statements for the given appnames.
|
||||||
|
|
||||||
For each model in each specified app, this command looks for the file
|
For each model in each specified app, this command looks for the file
|
||||||
``<appname>/sql/<modelname>.sql``, where ``<appname>`` is the given appname and
|
``<appname>/sql/<modelname>.sql``, where ``<appname>`` is the given appname and
|
||||||
``<modelname>`` is the model's name in lowercase. For example, if you have an
|
``<modelname>`` is the model's name in lowercase. For example, if you have an
|
||||||
app ``news`` that includes a ``Story`` model, ``sqlinitialdata`` will attempt
|
app ``news`` that includes a ``Story`` model, ``sqlcustom`` will attempt
|
||||||
to read a file ``news/sql/story.sql`` and append it to the output of this
|
to read a file ``news/sql/story.sql`` and append it to the output of this
|
||||||
command.
|
command.
|
||||||
|
|
||||||
@ -373,13 +358,6 @@ sqlindexes [appname appname ...]
|
|||||||
|
|
||||||
Prints the CREATE INDEX SQL statements for the given appnames.
|
Prints the CREATE INDEX SQL statements for the given appnames.
|
||||||
|
|
||||||
sqlinitialdata [appname appname ...]
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
**Removed in Django development version**
|
|
||||||
|
|
||||||
This method has been renamed ``sqlcustom`` in the development version of Django.
|
|
||||||
|
|
||||||
sqlreset [appname appname ...]
|
sqlreset [appname appname ...]
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
@ -426,8 +404,6 @@ fixture data files.
|
|||||||
test
|
test
|
||||||
----
|
----
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
|
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
|
||||||
|
|
||||||
.. _testing django applications: ../testing/
|
.. _testing django applications: ../testing/
|
||||||
@ -475,8 +451,6 @@ setting the Python path for you.
|
|||||||
--format
|
--format
|
||||||
--------
|
--------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Example usage::
|
Example usage::
|
||||||
|
|
||||||
django-admin.py dumpdata --format=xml
|
django-admin.py dumpdata --format=xml
|
||||||
@ -493,8 +467,6 @@ options.
|
|||||||
--indent
|
--indent
|
||||||
--------
|
--------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Example usage::
|
Example usage::
|
||||||
|
|
||||||
django-admin.py dumpdata --indent=4
|
django-admin.py dumpdata --indent=4
|
||||||
@ -506,8 +478,6 @@ Pretty-printing will only be enabled if the indent option is provided.
|
|||||||
--noinput
|
--noinput
|
||||||
---------
|
---------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Inform django-admin that the user should NOT be prompted for any input. Useful
|
Inform django-admin that the user should NOT be prompted for any input. Useful
|
||||||
if the django-admin script will be executed as an unattended, automated
|
if the django-admin script will be executed as an unattended, automated
|
||||||
script.
|
script.
|
||||||
@ -530,8 +500,6 @@ Example output::
|
|||||||
--verbosity
|
--verbosity
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Example usage::
|
Example usage::
|
||||||
|
|
||||||
django-admin.py syncdb --verbosity=2
|
django-admin.py syncdb --verbosity=2
|
||||||
@ -543,8 +511,6 @@ and `2` is verbose output.
|
|||||||
--adminmedia
|
--adminmedia
|
||||||
------------
|
------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Example usage::
|
Example usage::
|
||||||
django-admin.py manage.py --adminmedia=/tmp/new-admin-style/
|
django-admin.py manage.py --adminmedia=/tmp/new-admin-style/
|
||||||
|
|
||||||
|
@ -97,8 +97,7 @@ which is a dictionary of the parameters captured in the URL.
|
|||||||
* ``extra_context``: A dictionary of values to add to the template
|
* ``extra_context``: A dictionary of values to add to the template
|
||||||
context. By default, this is an empty dictionary. If a value in the
|
context. By default, this is an empty dictionary. If a value in the
|
||||||
dictionary is callable, the generic view will call it
|
dictionary is callable, the generic view will call it
|
||||||
just before rendering the template. (**This is new in the
|
just before rendering the template.
|
||||||
Django development version.**)
|
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
@ -752,10 +751,10 @@ If the results are paginated, the context will contain these extra variables:
|
|||||||
|
|
||||||
* ``previous``: The previous page number, as an integer. This is 1-based.
|
* ``previous``: The previous page number, as an integer. This is 1-based.
|
||||||
|
|
||||||
* `last_on_page`: **New in Django development version** The number of the
|
* `last_on_page`: The number of the
|
||||||
last result on the current page. This is 1-based.
|
last result on the current page. This is 1-based.
|
||||||
|
|
||||||
* `first_on_page`: **New in Django development version** The number of the
|
* `first_on_page`: The number of the
|
||||||
first result on the current page. This is 1-based.
|
first result on the current page. This is 1-based.
|
||||||
|
|
||||||
* ``pages``: The total number of pages, as an integer.
|
* ``pages``: The total number of pages, as an integer.
|
||||||
|
@ -86,25 +86,17 @@ Installing the official version
|
|||||||
Distribution-provided packages will typically allow for automatic
|
Distribution-provided packages will typically allow for automatic
|
||||||
installation of dependancies and easy upgrade paths.
|
installation of dependancies and easy upgrade paths.
|
||||||
|
|
||||||
2. Download Django-0.95.tar.gz from our `download page`_.
|
2. Download the latest release from our `download page`_.
|
||||||
|
|
||||||
3. ``tar xzvf Django-0.95.tar.gz``
|
3. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``).
|
||||||
|
|
||||||
4. ``cd Django-0.95``
|
4. Change into the downloaded directory (e.g. ``cd Django-NNN``).
|
||||||
|
|
||||||
5. ``sudo python setup.py install``
|
5. Run ``sudo python setup.py install``.
|
||||||
|
|
||||||
Note that the last command will automatically download and install setuptools_
|
|
||||||
if you don't already have it installed. This requires a working Internet
|
|
||||||
connection and may cause problems on Python 2.5. If you run into problems,
|
|
||||||
try using our development version by following the instructions below. The
|
|
||||||
development version no longer uses setuptools nor requires an Internet
|
|
||||||
connection.
|
|
||||||
|
|
||||||
The command will install Django in your Python installation's ``site-packages``
|
The command will install Django in your Python installation's ``site-packages``
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
|
|
||||||
.. _distribution specific notes: ../distributions/
|
.. _distribution specific notes: ../distributions/
|
||||||
|
|
||||||
Installing the development version
|
Installing the development version
|
||||||
|
@ -104,8 +104,6 @@ Also removes the content from any response to a HEAD request and sets the
|
|||||||
django.middleware.http.SetRemoteAddrFromForwardedFor
|
django.middleware.http.SetRemoteAddrFromForwardedFor
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Sets ``request.META['REMOTE_ADDR']`` based on
|
Sets ``request.META['REMOTE_ADDR']`` based on
|
||||||
``request.META['HTTP_X_FORWARDED_FOR']``, if the latter is set. This is useful
|
``request.META['HTTP_X_FORWARDED_FOR']``, if the latter is set. This is useful
|
||||||
if you're sitting behind a reverse proxy that causes each request's
|
if you're sitting behind a reverse proxy that causes each request's
|
||||||
|
@ -362,9 +362,8 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
|
|||||||
containing only letters, numbers, underscores or hyphens. They're generally
|
containing only letters, numbers, underscores or hyphens. They're generally
|
||||||
used in URLs.
|
used in URLs.
|
||||||
|
|
||||||
In the Django development version, you can specify ``maxlength``. If
|
Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
|
||||||
``maxlength`` is not specified, Django will use a default length of 50. In
|
not specified, Django will use a default length of 50.
|
||||||
previous Django versions, there's no way to override the length of 50.
|
|
||||||
|
|
||||||
Implies ``db_index=True``.
|
Implies ``db_index=True``.
|
||||||
|
|
||||||
@ -1457,8 +1456,8 @@ user searches for ``john lennon``, Django will do the equivalent of this SQL
|
|||||||
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
|
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
|
||||||
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
|
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
|
||||||
|
|
||||||
**New in Django development version:** For faster and/or more restrictive
|
For faster and/or more restrictive searches, prefix the field name
|
||||||
searches, prefix the field name with an operator:
|
with an operator:
|
||||||
|
|
||||||
``^``
|
``^``
|
||||||
Matches the beginning of the field. For example, if ``search_fields`` is
|
Matches the beginning of the field. For example, if ``search_fields`` is
|
||||||
@ -1754,8 +1753,6 @@ But this template code is good::
|
|||||||
The ``permalink`` decorator
|
The ``permalink`` decorator
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
**New in Django development version.**
|
|
||||||
|
|
||||||
The problem with the way we wrote ``get_absolute_url()`` above is that it
|
The problem with the way we wrote ``get_absolute_url()`` above is that it
|
||||||
slightly violates the DRY principle: the URL for this object is defined both
|
slightly violates the DRY principle: the URL for this object is defined both
|
||||||
in the URLConf file and in the model.
|
in the URLConf file and in the model.
|
||||||
|
@ -9,9 +9,10 @@ framework. This document explains how to use this new library.
|
|||||||
Migration plan
|
Migration plan
|
||||||
==============
|
==============
|
||||||
|
|
||||||
``django.newforms`` currently is only available in the Django development version
|
``django.newforms`` currently is only available in Django beginning
|
||||||
-- i.e., it's not available in the Django 0.95 release. For the next Django
|
with the 0.96 release. the Django development version -- i.e., it's
|
||||||
release, our plan is to do the following:
|
not available in the Django 0.95 release. For the next Django release,
|
||||||
|
our plan is to do the following:
|
||||||
|
|
||||||
* As of revision [4208], we've copied the current ``django.forms`` to
|
* As of revision [4208], we've copied the current ``django.forms`` to
|
||||||
``django.oldforms``. This allows you to upgrade your code *now* rather
|
``django.oldforms``. This allows you to upgrade your code *now* rather
|
||||||
@ -859,6 +860,16 @@ level and at the form instance level, and the latter gets precedence::
|
|||||||
<tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
|
<tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
|
||||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||||
|
|
||||||
|
Creating custom fields
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
If the built-in ``Field`` classes don't meet your needs, you can easily create
|
||||||
|
custom ``Field`` classes. To do this, just create a subclass of
|
||||||
|
``django.newforms.Field``. Its only requirements are that it implement a
|
||||||
|
``clean()`` method and that its ``__init__()`` method accept the core arguments
|
||||||
|
mentioned above (``required``, ``label``, ``initial``, ``widget``,
|
||||||
|
``help_text``).
|
||||||
|
|
||||||
More coming soon
|
More coming soon
|
||||||
================
|
================
|
||||||
|
|
||||||
|
264
docs/release_notes_0.96.txt
Normal file
264
docs/release_notes_0.96.txt
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
=================================
|
||||||
|
Django version 0.96 release notes
|
||||||
|
=================================
|
||||||
|
|
||||||
|
Welcome to Django 0.96!
|
||||||
|
|
||||||
|
The primary goal for 0.96 is a cleanup and stabilization of the features
|
||||||
|
introduced in 0.95. There have been a few small `backwards-incompatible
|
||||||
|
changes`_ since 0.95, but the upgrade process should be fairly simple
|
||||||
|
and should not require major changes to existing applications.
|
||||||
|
|
||||||
|
However, we're also releasing 0.96 now because we have a set of
|
||||||
|
backwards-incompatible changes scheduled for the near future. Once
|
||||||
|
completed, they will involve some code changes for application
|
||||||
|
developers, so we recommend that you stick with Django 0.96 until the
|
||||||
|
next official release; then you'll be able to upgrade in one step
|
||||||
|
instead of needing to make incremental changes to keep up with the
|
||||||
|
development version of Django.
|
||||||
|
|
||||||
|
Backwards-incompatible changes
|
||||||
|
==============================
|
||||||
|
|
||||||
|
The following changes may require you to update your code when you switch from
|
||||||
|
0.95 to 0.96:
|
||||||
|
|
||||||
|
``MySQLdb`` version requirement
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Due to a bug in older versions of the ``MySQLdb`` Python module (which
|
||||||
|
Django uses to connect to MySQL databases), Django's MySQL backend now
|
||||||
|
requires version 1.2.1p2 or higher of `MySQLdb`, and will raise
|
||||||
|
exceptions if you attempt to use an older version.
|
||||||
|
|
||||||
|
If you're currently unable to upgrade your copy of ``MySQLdb`` to meet
|
||||||
|
this requirement, a separate, backwards-compatible backend, called
|
||||||
|
"mysql_old", has been added to Django. To use this backend, change
|
||||||
|
the ``DATABASE_ENGINE`` setting in your Django settings file from
|
||||||
|
this::
|
||||||
|
|
||||||
|
DATABASE_ENGINE = "mysql"
|
||||||
|
|
||||||
|
to this::
|
||||||
|
|
||||||
|
DATABASE_ENGINE = "mysql_old"
|
||||||
|
|
||||||
|
However, we strongly encourage MySQL users to upgrade to a more recent
|
||||||
|
version of `MySQLdb` as soon as possible, The "mysql_old" backend is
|
||||||
|
provided only to ease this transition, and is considered deprecated;
|
||||||
|
aside from any necessary security fixes, it will not be actively
|
||||||
|
maintained, and it will be removed in a future release of Django.
|
||||||
|
|
||||||
|
Also, note that some features, like the new ``DATABASE_OPTIONS``
|
||||||
|
setting (see the `databases documentation`_ for details), are only
|
||||||
|
available on the "mysql" backend, and will not be made available for
|
||||||
|
"mysql_old".
|
||||||
|
|
||||||
|
.. _databases documentation: ../databases/
|
||||||
|
|
||||||
|
Database constraint names changed
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
The format of the constraint names Django generates for foreign key
|
||||||
|
references have changed slightly. These names are generally only used
|
||||||
|
when it is not possible to put the reference directly on the affected
|
||||||
|
column, so they are not always visible.
|
||||||
|
|
||||||
|
The effect of this change is that running ``manage.py reset`` and
|
||||||
|
similar commands against an existing database may generate SQL with
|
||||||
|
the new form of constraint name, while the database itself contains
|
||||||
|
constraints named in the old form; this will cause the database server
|
||||||
|
to raise an error message about modifying non-existent constraints.
|
||||||
|
|
||||||
|
If you need to work around this, there are two methods available:
|
||||||
|
|
||||||
|
1. Redirect the output of ``manage.py`` to a file, and edit the
|
||||||
|
generated SQL to use the correct constraint names before
|
||||||
|
executing it.
|
||||||
|
|
||||||
|
2. Examine the output of ``manage.py sqlall`` to see the new-style
|
||||||
|
constraint names, and use that as a guide to rename existing
|
||||||
|
constraints in your database.
|
||||||
|
|
||||||
|
Name changes in ``manage.py``
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
A few of the options to ``manage.py`` have changed with the addition of fixture
|
||||||
|
support:
|
||||||
|
|
||||||
|
* There are new ``dumpdata`` and ``loaddata`` commands which, as
|
||||||
|
you might expect, will dump and load data to/from the
|
||||||
|
database. These commands can operate against any of Django's
|
||||||
|
supported serialization formats.
|
||||||
|
|
||||||
|
* The ``sqlinitialdata`` command has been renamed to ``sqlcustom`` to
|
||||||
|
emphasize that ``loaddata`` should be used for data (and ``sqlcustom`` for
|
||||||
|
other custom SQL -- views, stored procedures, etc.).
|
||||||
|
|
||||||
|
* The vestigial ``install`` command has been removed. Use ``syncdb``.
|
||||||
|
|
||||||
|
Backslash escaping changed
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
The Django database API now escapes backslashes given as query parameters. If
|
||||||
|
you have any database API code that matches backslashes, and it was working before
|
||||||
|
(despite the lack of escaping), you'll have to change your code to "unescape" the
|
||||||
|
slashes one level.
|
||||||
|
|
||||||
|
For example, this used to work::
|
||||||
|
|
||||||
|
# Find text containing a single backslash
|
||||||
|
MyModel.objects.filter(text__contains='\\\\')
|
||||||
|
|
||||||
|
The above is now incorrect, and should be rewritten as::
|
||||||
|
|
||||||
|
# Find text containing a single backslash
|
||||||
|
MyModel.objects.filter(text__contains='\\')
|
||||||
|
|
||||||
|
Removed ENABLE_PSYCO setting
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
The ``ENABLE_PSYCO`` setting no longer exists. If your settings file includes
|
||||||
|
``ENABLE_PSYCO`` it will have no effect; to use Psyco_, we recommend
|
||||||
|
writing a middleware class to activate it.
|
||||||
|
|
||||||
|
.. _psyco: http://psyco.sourceforge.net/
|
||||||
|
|
||||||
|
What's new in 0.96?
|
||||||
|
===================
|
||||||
|
|
||||||
|
This revision represents over a thousand source commits and over four hundred
|
||||||
|
bug fixes, so we can't possibly catalog all the changes. Here, we describe the
|
||||||
|
most notable changes in this release.
|
||||||
|
|
||||||
|
New forms library
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
``django.newforms`` is Django's new form-handling library. It's a
|
||||||
|
replacement for ``django.forms``, the old form/manipulator/validation
|
||||||
|
framework. Both APIs are available in 0.96, but over the next two
|
||||||
|
releases we plan to switch completely to the new forms system, and
|
||||||
|
deprecate and remove the old system.
|
||||||
|
|
||||||
|
There are three elements to this transition:
|
||||||
|
|
||||||
|
* We've copied the current ``django.forms`` to
|
||||||
|
``django.oldforms``. This allows you to upgrade your code *now*
|
||||||
|
rather than waiting for the backwards-incompatible change and
|
||||||
|
rushing to fix your code after the fact. Just change your
|
||||||
|
import statements like this::
|
||||||
|
|
||||||
|
from django import forms # 0.95-style
|
||||||
|
from django import oldforms as forms # 0.96-style
|
||||||
|
|
||||||
|
* The next official release of Django will move the current
|
||||||
|
``django.newforms`` to ``django.forms``. This will be a
|
||||||
|
backwards-incompatible change, and anyone still using the old
|
||||||
|
version of ``django.forms`` at that time will need to change
|
||||||
|
their import statements as described above.
|
||||||
|
|
||||||
|
* The next release after that will completely remove
|
||||||
|
``django.oldforms``.
|
||||||
|
|
||||||
|
Although the ``newforms`` library will continue to evolve, it's ready for use
|
||||||
|
for most common cases. We recommend that anyone new to form handling skip the
|
||||||
|
old forms system and start with the new.
|
||||||
|
|
||||||
|
For more information about ``django.newforms``, read the `newforms
|
||||||
|
documentation`_.
|
||||||
|
|
||||||
|
.. _newforms documentation: ../newforms/
|
||||||
|
|
||||||
|
URLconf improvements
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
You can now use any callable as the callback in URLconfs (previously, only
|
||||||
|
strings that referred to callables were allowed). This allows a much more
|
||||||
|
natural use of URLconfs. For example, this URLconf::
|
||||||
|
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
('^myview/$', 'mysite.myapp.views.myview')
|
||||||
|
)
|
||||||
|
|
||||||
|
can now be rewritten as::
|
||||||
|
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from mysite.myapp.views import myview
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
('^myview/$', myview)
|
||||||
|
)
|
||||||
|
|
||||||
|
One useful application of this can be seen when using decorators; this
|
||||||
|
change allows you to apply decorators to views *in your
|
||||||
|
URLconf*. Thus, you can make a generic view require login very
|
||||||
|
easily::
|
||||||
|
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.views.generic.list_detail import object_list
|
||||||
|
from mysite.myapp.models import MyModel
|
||||||
|
|
||||||
|
info = {
|
||||||
|
"queryset" : MyModel.objects.all(),
|
||||||
|
}
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
('^myview/$', login_required(object_list), info)
|
||||||
|
)
|
||||||
|
|
||||||
|
Note that both syntaxes (strings and callables) are valid, and will continue to
|
||||||
|
be valid for the foreseeable future.
|
||||||
|
|
||||||
|
The test framework
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Django now includes a test framework so you can start transmuting fear into
|
||||||
|
boredom (with apologies to Kent Beck). You can write tests based on doctest_
|
||||||
|
or unittest_ and test your views with a simple test client.
|
||||||
|
|
||||||
|
There is also new support for "fixtures" -- initial data, stored in any of the
|
||||||
|
supported `serialization formats`_, that will be loaded into your database at the
|
||||||
|
start of your tests. This makes testing with real data much easier.
|
||||||
|
|
||||||
|
See `the testing documentation`_ for the full details.
|
||||||
|
|
||||||
|
.. _doctest: http://docs.python.org/lib/module-doctest.html
|
||||||
|
.. _unittest: http://docs.python.org/lib/module-unittest.html
|
||||||
|
.. _the testing documentation: ../testing/
|
||||||
|
.. _serialization formats: ../serialization/
|
||||||
|
|
||||||
|
Improvements to the admin interface
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
A small change, but a very nice one: dedicated views for adding and
|
||||||
|
updating users have been added to the admin interface, so you no
|
||||||
|
longer need to worry about working with hashed passwords in the admin.
|
||||||
|
|
||||||
|
Thanks
|
||||||
|
======
|
||||||
|
|
||||||
|
Since 0.95, a number of people have stepped forward and taken a major
|
||||||
|
new role in Django's development. We'd like to thank these people for
|
||||||
|
all their hard work:
|
||||||
|
|
||||||
|
* Russell Keith-Magee and Malcolm Tredinnick for their major code
|
||||||
|
contributions. This release wouldn't have been possible without them.
|
||||||
|
|
||||||
|
* Our new release manager, James Bennett, for his work in getting out
|
||||||
|
0.95.1, 0.96, and (hopefully) future release.
|
||||||
|
|
||||||
|
* Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill,
|
||||||
|
Michael Radziej, and Gary Wilson. They agreed to take on the monumental
|
||||||
|
task of wrangling our tickets into nicely cataloged submission. Figuring
|
||||||
|
out what to work on is now about a million times easier; thanks again,
|
||||||
|
guys.
|
||||||
|
|
||||||
|
* Everyone who submitted a bug report, patch or ticket comment. We can't
|
||||||
|
possibly thank everyone by name -- over 200 developers submitted patches
|
||||||
|
that went into 0.96 -- but everyone who's contributed to Django is listed
|
||||||
|
in AUTHORS_.
|
||||||
|
|
||||||
|
.. _AUTHORS: http://code.djangoproject.com/browser/django/trunk/AUTHORS
|
@ -384,7 +384,6 @@ Methods
|
|||||||
Deletes the cookie with the given key. Fails silently if the key doesn't
|
Deletes the cookie with the given key. Fails silently if the key doesn't
|
||||||
exist.
|
exist.
|
||||||
|
|
||||||
The ``path`` and ``domain`` arguments are new in the Django development version.
|
|
||||||
Due to the way cookies work, ``path`` and ``domain`` should be the same
|
Due to the way cookies work, ``path`` and ``domain`` should be the same
|
||||||
values you used in ``set_cookie()`` -- otherwise the cookie may not be deleted.
|
values you used in ``set_cookie()`` -- otherwise the cookie may not be deleted.
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ is defined in ``django/contrib/sessions/models.py``. Because it's a normal
|
|||||||
model, you can access sessions using the normal Django database API::
|
model, you can access sessions using the normal Django database API::
|
||||||
|
|
||||||
>>> from django.contrib.sessions.models import Session
|
>>> from django.contrib.sessions.models import Session
|
||||||
>>> s = Session.objects.get_object(pk='2b1189a188b44ad18c35e113ac6ceead')
|
>>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
|
||||||
>>> s.expire_date
|
>>> s.expire_date
|
||||||
datetime.datetime(2005, 8, 20, 13, 35, 12)
|
datetime.datetime(2005, 8, 20, 13, 35, 12)
|
||||||
|
|
||||||
@ -265,8 +265,6 @@ The name of the cookie to use for sessions. This can be whatever you want.
|
|||||||
SESSION_COOKIE_SECURE
|
SESSION_COOKIE_SECURE
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Default: ``False``
|
Default: ``False``
|
||||||
|
|
||||||
Whether to use a secure cookie for the session cookie. If this is set to
|
Whether to use a secure cookie for the session cookie. If this is set to
|
||||||
|
@ -429,8 +429,6 @@ trailing space.
|
|||||||
FIXTURE_DIRS
|
FIXTURE_DIRS
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Default: ``()`` (Empty tuple)
|
Default: ``()`` (Empty tuple)
|
||||||
|
|
||||||
List of locations of the fixture data files, in search order. Note that
|
List of locations of the fixture data files, in search order. Note that
|
||||||
@ -716,8 +714,6 @@ See the `session docs`_.
|
|||||||
SESSION_COOKIE_SECURE
|
SESSION_COOKIE_SECURE
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Default: ``False``
|
Default: ``False``
|
||||||
|
|
||||||
Whether to use a secure cookie for the session cookie. If this is set to
|
Whether to use a secure cookie for the session cookie. If this is set to
|
||||||
@ -812,8 +808,6 @@ misspelled) variables. See `How invalid variables are handled`_.
|
|||||||
TEST_RUNNER
|
TEST_RUNNER
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Default: ``'django.test.simple.run_tests'``
|
Default: ``'django.test.simple.run_tests'``
|
||||||
|
|
||||||
The name of the method to use for starting the test suite. See
|
The name of the method to use for starting the test suite. See
|
||||||
@ -824,8 +818,6 @@ The name of the method to use for starting the test suite. See
|
|||||||
TEST_DATABASE_NAME
|
TEST_DATABASE_NAME
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
Default: ``None``
|
Default: ``None``
|
||||||
|
|
||||||
The name of database to use when running the test suite. If a value of
|
The name of database to use when running the test suite. If a value of
|
||||||
|
@ -112,8 +112,6 @@ know how to write Python code.
|
|||||||
Comments
|
Comments
|
||||||
========
|
========
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
To comment-out part of a template, use the comment syntax: ``{# #}``.
|
To comment-out part of a template, use the comment syntax: ``{# #}``.
|
||||||
|
|
||||||
For example, this template would render as ``'hello'``::
|
For example, this template would render as ``'hello'``::
|
||||||
@ -253,8 +251,8 @@ Here are some tips for working with inheritance:
|
|||||||
if you want to add to the contents of a parent block instead of
|
if you want to add to the contents of a parent block instead of
|
||||||
completely overriding it.
|
completely overriding it.
|
||||||
|
|
||||||
* **New in Django development version:** For extra readability, you can
|
* For extra readability, you can optionally give a *name* to your
|
||||||
optionally give a *name* to your ``{% endblock %}`` tag. For example::
|
``{% endblock %}`` tag. For example::
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
...
|
...
|
||||||
@ -548,9 +546,9 @@ The 'ifchanged' block tag is used within a loop. It has two possible uses.
|
|||||||
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
|
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
2. **New in Django development version.** If given a variable, check whether that
|
2. If given a variable, check whether that variable has changed. For
|
||||||
variable has changed. For example, the following shows the date every time it
|
example, the following shows the date every time it changes, but
|
||||||
changes, but only shows the hour if both the hour and the date has changed::
|
only shows the hour if both the hour and the date has changed::
|
||||||
|
|
||||||
{% for date in days %}
|
{% for date in days %}
|
||||||
{% ifchanged date.date %} {{ date.date }} {% endifchanged %}
|
{% ifchanged date.date %} {{ date.date }} {% endifchanged %}
|
||||||
@ -739,6 +737,7 @@ The following snippet of template code would accomplish this dubious task::
|
|||||||
<li>{{ item }}</li>
|
<li>{{ item }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -828,13 +827,9 @@ The argument tells which template bit to output:
|
|||||||
``closecomment`` ``#}``
|
``closecomment`` ``#}``
|
||||||
================== =======
|
================== =======
|
||||||
|
|
||||||
Note: ``opencomment`` and ``closecomment`` are new in the Django development version.
|
|
||||||
|
|
||||||
url
|
url
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
**Note that the syntax for this tag may change in the future, as we make it more robust.**
|
**Note that the syntax for this tag may change in the future, as we make it more robust.**
|
||||||
|
|
||||||
Returns an absolute URL (i.e., a URL without the domain name) matching a given
|
Returns an absolute URL (i.e., a URL without the domain name) matching a given
|
||||||
@ -878,6 +873,23 @@ Above, if ``this_value`` is 175 and ``max_value`` is 200, the the image in the
|
|||||||
above example will be 88 pixels wide (because 175/200 = .875; .875 * 100 = 87.5
|
above example will be 88 pixels wide (because 175/200 = .875; .875 * 100 = 87.5
|
||||||
which is rounded up to 88).
|
which is rounded up to 88).
|
||||||
|
|
||||||
|
with
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
**New in Django development version**
|
||||||
|
|
||||||
|
Caches a complex variable under a simpler name. This is useful when accessing
|
||||||
|
an "expensive" method (e.g., one that hits the database) multiple times.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
{% with business.employees.count as total %}
|
||||||
|
{{ total }} employee{{ total|pluralize }}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
The populated variable (in the example above, ``total``) is only available
|
||||||
|
between the ``{% with %}`` and ``{% endwith %}`` tags.
|
||||||
|
|
||||||
Built-in filter reference
|
Built-in filter reference
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
@ -976,9 +988,7 @@ place -- but only if there's a decimal part to be displayed. For example:
|
|||||||
* ``36.15`` gets converted to ``36.2``
|
* ``36.15`` gets converted to ``36.2``
|
||||||
* ``36`` gets converted to ``36``
|
* ``36`` gets converted to ``36``
|
||||||
|
|
||||||
**New in Django development version**
|
If used with a numeric integer argument, ``floatformat`` rounds a number to that
|
||||||
|
|
||||||
If used with a numeric integer argument, ``floatformat`` rounds a number to that
|
|
||||||
many decimal places. For example:
|
many decimal places. For example:
|
||||||
|
|
||||||
* ``36.1234`` with floatformat:3 gets converted to ``36.123``
|
* ``36.1234`` with floatformat:3 gets converted to ``36.123``
|
||||||
@ -991,7 +1001,7 @@ For example:
|
|||||||
* ``36.1234`` with floatformat:-3 gets converted to ``36.123``
|
* ``36.1234`` with floatformat:-3 gets converted to ``36.123``
|
||||||
* ``36`` with floatformat:-4 gets converted to ``36``
|
* ``36`` with floatformat:-4 gets converted to ``36``
|
||||||
|
|
||||||
Using ``floatformat`` with no argument is equivalent to using ``floatformat`` with
|
Using ``floatformat`` with no argument is equivalent to using ``floatformat`` with
|
||||||
an argument of ``-1``.
|
an argument of ``-1``.
|
||||||
|
|
||||||
get_digit
|
get_digit
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
Testing Django applications
|
Testing Django applications
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
**New in Django development version**.
|
|
||||||
|
|
||||||
Automated testing is an extremely useful weapon in the bug-killing arsenal
|
Automated testing is an extremely useful weapon in the bug-killing arsenal
|
||||||
of the modern developer. When initially writing code, a test suite can be
|
of the modern developer. When initially writing code, a test suite can be
|
||||||
used to validate that code behaves as expected. When refactoring or
|
used to validate that code behaves as expected. When refactoring or
|
||||||
@ -227,6 +225,12 @@ can be invoked on the ``Client`` instance.
|
|||||||
The key-value pairs in the data dictionary will be encoded as a multipart
|
The key-value pairs in the data dictionary will be encoded as a multipart
|
||||||
message and used to create the POST data payload.
|
message and used to create the POST data payload.
|
||||||
|
|
||||||
|
To submit multiple values for a given key (for example, to specify
|
||||||
|
the selections for a multiple selection list), provide the values as a
|
||||||
|
list or tuple for the required key. For example, a data dictionary of
|
||||||
|
``{'choices': ('a','b','d')}`` would submit three selected rows for the
|
||||||
|
field named ``choices``.
|
||||||
|
|
||||||
Submitting files is a special case. To POST a file, you need only
|
Submitting files is a special case. To POST a file, you need only
|
||||||
provide the file field name as a key, and a file handle to the file you wish to
|
provide the file field name as a key, and a file handle to the file you wish to
|
||||||
upload as a value. The Test Client will populate the two POST fields (i.e.,
|
upload as a value. The Test Client will populate the two POST fields (i.e.,
|
||||||
|
@ -400,8 +400,6 @@ to pass metadata and options to views.
|
|||||||
Passing extra options to ``include()``
|
Passing extra options to ``include()``
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
**New in Django development version.**
|
|
||||||
|
|
||||||
Similarly, you can pass extra options to ``include()``. When you pass extra
|
Similarly, you can pass extra options to ``include()``. When you pass extra
|
||||||
options to ``include()``, *each* line in the included URLconf will be passed
|
options to ``include()``, *each* line in the included URLconf will be passed
|
||||||
the extra options.
|
the extra options.
|
||||||
@ -442,8 +440,6 @@ every view in the the included URLconf accepts the extra options you're passing.
|
|||||||
Passing callable objects instead of strings
|
Passing callable objects instead of strings
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
**New in Django development version.**
|
|
||||||
|
|
||||||
Some developers find it more natural to pass the actual Python function object
|
Some developers find it more natural to pass the actual Python function object
|
||||||
rather than a string containing the path to its module. This alternative is
|
rather than a string containing the path to its module. This alternative is
|
||||||
supported -- you can pass any callable object as the view.
|
supported -- you can pass any callable object as the view.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user