1
0
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:
Boulder Sprinters 2007-03-28 21:30:05 +00:00
parent d2c03a3779
commit 1f3fc7bc9f
28 changed files with 672 additions and 127 deletions

View File

@ -44,6 +44,7 @@ answer newbie questions, and generally made Django that much better:
adurdin@gmail.com
Andreas
andy@jadedplanet.net
Fabrice Aneche <akh@nobugware.com>
ant9000@netwise.it
David Ascher <http://ascher.ca/>
Arthur <avandorp@gmail.com>

View File

@ -1 +1 @@
VERSION = (0, 96, 'pre')
VERSION = (0, 96, None)

View File

@ -45,7 +45,7 @@ class Permission(models.Model):
ordering = ('content_type', 'codename')
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):
"""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.

View 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)

View 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'),
)

View 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)

View 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'),),
)

View File

@ -3,9 +3,12 @@
from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
try:
import memcache
import cmemcache as memcache
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):
def __init__(self, server, params):

View File

@ -299,7 +299,7 @@ def get_sql_delete(app):
from django.db.backends.util import truncate_name
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:
cursor = connection.cursor()
except:
@ -486,7 +486,7 @@ def get_sql_indexes_for_model(model):
unique = f.unique and 'UNIQUE ' or ''
output.append(
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_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \
"(%s);" % style.SQL_FIELD(backend.quote_name(f.column))
@ -546,6 +546,7 @@ def syncdb(verbosity=1, interactive=True):
created_models = set()
pending_references = {}
# Create the tables for each model
for app in models.get_apps():
app_name = app.__name__.split('.')[-2]
model_list = models.get_models(app)
@ -567,6 +568,11 @@ def syncdb(verbosity=1, interactive=True):
cursor.execute(statement)
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:
if model in created_models:
sql = _get_many_to_many_sql_for_model(model)
@ -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()]
for fixture_label in fixture_labels:
if verbosity > 0:
print "Loading '%s' fixtures..." % fixture_label
for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']:
if verbosity > 1:
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]
if format in serializers.get_serializer_formats():
formats = [format]
else:
formats = []
if verbosity > 0:
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) + ['']:
if verbosity > 1:
print "Checking %s for fixtures..." % humanize(fixture_dir)
label_found = False
for format in formats:

View File

@ -10,7 +10,7 @@ class CacheMiddleware(object):
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
(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
any other user-specific content).

View File

@ -354,6 +354,23 @@ class WidthRatioNode(Node):
return ''
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
def comment(parser, token):
"""
@ -595,8 +612,8 @@ def do_if(parser, token):
::
{% if althlete_list %}
Number of athletes: {{ althete_list|count }}
{% if athlete_list %}
Number of athletes: {{ athlete_list|count }}
{% else %}
No athletes.
{% endif %}
@ -967,3 +984,23 @@ def widthratio(parser, token):
return WidthRatioNode(parser.compile_filter(this_value_expr),
parser.compile_filter(max_value_expr), max_width)
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)

View File

@ -9,6 +9,13 @@ problems.
This code lives in ``django/contrib`` in the Django distribution. Here's a
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
admin
@ -51,8 +58,6 @@ See the `csrf documentation`_.
formtools
=========
**New in Django development version**
A set of high-level abstractions for Django forms (django.newforms).
django.contrib.formtools.preview
@ -142,8 +147,6 @@ See the `flatpages documentation`_.
localflavor
===========
**New in Django development version**
A collection of various Django snippets that are useful only for a particular
country or culture. For example, ``django.contrib.localflavor.usa.forms``
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
======
A collection of template filters that implement these common markup languages:
A collection of template filters that implement common markup languages:
* `Textile`_
* `Markdown`_
* `ReST (ReStructured Text)`_
* ``textile`` -- implements `Textile`_
* ``markdown`` -- implements `Markdown`_
* ``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
.. _Markdown: http://en.wikipedia.org/wiki/Markdown

View File

@ -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.
After installing Memcached itself, you'll need to install the Memcached Python
bindings. They're in a single Python module, memcache.py, 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.
bindings. Two versions of this are available. Choose and install *one* of the
following modules:
* 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
``memcached://ip:port/``, where ``ip`` is the IP address of the Memcached

View File

@ -100,8 +100,6 @@ if you're ever curious to see the full list of defaults.
dumpdata [appname appname ...]
------------------------------
**New in Django development version**
Output to standard output all data in the database associated with the named
application(s).
@ -117,8 +115,6 @@ The output of ``dumpdata`` can be used as input for ``loaddata``.
flush
-----
**New in Django development version**
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
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
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 ...]
------------------------------
**New in Django development version**
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
@ -350,14 +337,12 @@ Prints the DROP TABLE SQL statements for the given appnames.
sqlcustom [appname appname ...]
-------------------------------
**New in Django development version**
Prints the custom SQL statements for the given appnames.
For each model in each specified app, this command looks for the file
``<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
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
command.
@ -373,13 +358,6 @@ sqlindexes [appname appname ...]
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 ...]
--------------------------------------
@ -426,8 +404,6 @@ fixture data files.
test
----
**New in Django development version**
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
.. _testing django applications: ../testing/
@ -475,8 +451,6 @@ setting the Python path for you.
--format
--------
**New in Django development version**
Example usage::
django-admin.py dumpdata --format=xml
@ -493,8 +467,6 @@ options.
--indent
--------
**New in Django development version**
Example usage::
django-admin.py dumpdata --indent=4
@ -506,8 +478,6 @@ Pretty-printing will only be enabled if the indent option is provided.
--noinput
---------
**New in Django development version**
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
script.
@ -530,8 +500,6 @@ Example output::
--verbosity
-----------
**New in Django development version**
Example usage::
django-admin.py syncdb --verbosity=2
@ -543,8 +511,6 @@ and `2` is verbose output.
--adminmedia
------------
**New in Django development version**
Example usage::
django-admin.py manage.py --adminmedia=/tmp/new-admin-style/

View File

@ -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
context. By default, this is an empty dictionary. If a value in the
dictionary is callable, the generic view will call it
just before rendering the template. (**This is new in the
Django development version.**)
just before rendering the template.
**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.
* `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.
* `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.
* ``pages``: The total number of pages, as an integer.

View File

@ -86,25 +86,17 @@ Installing the official version
Distribution-provided packages will typically allow for automatic
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``
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.
5. Run ``sudo python setup.py install``.
The command will install Django in your Python installation's ``site-packages``
directory.
.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
.. _distribution specific notes: ../distributions/
Installing the development version

View File

@ -104,8 +104,6 @@ Also removes the content from any response to a HEAD request and sets the
django.middleware.http.SetRemoteAddrFromForwardedFor
----------------------------------------------------
**New in Django development version**
Sets ``request.META['REMOTE_ADDR']`` based on
``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

View File

@ -362,9 +362,8 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
containing only letters, numbers, underscores or hyphens. They're generally
used in URLs.
In the Django development version, you can specify ``maxlength``. If
``maxlength`` is not specified, Django will use a default length of 50. In
previous Django versions, there's no way to override the length of 50.
Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
not specified, Django will use a default length of 50.
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%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
**New in Django development version:** For faster and/or more restrictive
searches, prefix the field name with an operator:
For faster and/or more restrictive searches, prefix the field name
with an operator:
``^``
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~
**New in Django development version.**
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
in the URLConf file and in the model.

View File

@ -9,9 +9,10 @@ framework. This document explains how to use this new library.
Migration plan
==============
``django.newforms`` currently is only available in the Django development version
-- i.e., it's not available in the Django 0.95 release. For the next Django
release, our plan is to do the following:
``django.newforms`` currently is only available in Django beginning
with the 0.96 release. the Django development version -- i.e., it's
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
``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>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
================

264
docs/release_notes_0.96.txt Normal file
View 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

View File

@ -384,7 +384,6 @@ Methods
Deletes the cookie with the given key. Fails silently if the key doesn't
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
values you used in ``set_cookie()`` -- otherwise the cookie may not be deleted.

View File

@ -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::
>>> from django.contrib.sessions.models import Session
>>> s = Session.objects.get_object(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> s.expire_date
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
---------------------
**New in Django development version**
Default: ``False``
Whether to use a secure cookie for the session cookie. If this is set to

View File

@ -429,8 +429,6 @@ trailing space.
FIXTURE_DIRS
-------------
**New in Django development version**
Default: ``()`` (Empty tuple)
List of locations of the fixture data files, in search order. Note that
@ -716,8 +714,6 @@ See the `session docs`_.
SESSION_COOKIE_SECURE
---------------------
**New in Django development version**
Default: ``False``
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
-----------
**New in Django development version**
Default: ``'django.test.simple.run_tests'``
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
------------------
**New in Django development version**
Default: ``None``
The name of database to use when running the test suite. If a value of

View File

@ -112,8 +112,6 @@ know how to write Python code.
Comments
========
**New in Django development version**
To comment-out part of a template, use the comment syntax: ``{# #}``.
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
completely overriding it.
* **New in Django development version:** For extra readability, you can
optionally give a *name* to your ``{% endblock %}`` tag. For example::
* For extra readability, you can optionally give a *name* to your
``{% endblock %}`` tag. For example::
{% 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>
{% endfor %}
2. **New in Django development version.** If given a variable, check whether that
variable has changed. For example, the following shows the date every time it
changes, but only shows the hour if both the hour and the date has changed::
2. If given a variable, check whether that variable has changed. For
example, the following shows the date every time it changes, but
only shows the hour if both the hour and the date has changed::
{% for date in days %}
{% ifchanged date.date %} {{ date.date }} {% endifchanged %}
@ -739,6 +737,7 @@ The following snippet of template code would accomplish this dubious task::
<li>{{ item }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
@ -828,13 +827,9 @@ The argument tells which template bit to output:
``closecomment`` ``#}``
================== =======
Note: ``opencomment`` and ``closecomment`` are new in the Django development version.
url
~~~
**New in Django development version**
**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
@ -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
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
-------------------------
@ -976,8 +988,6 @@ place -- but only if there's a decimal part to be displayed. For example:
* ``36.15`` gets converted to ``36.2``
* ``36`` gets converted to ``36``
**New in Django development version**
If used with a numeric integer argument, ``floatformat`` rounds a number to that
many decimal places. For example:

View File

@ -2,8 +2,6 @@
Testing Django applications
===========================
**New in Django development version**.
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
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
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
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.,

View File

@ -400,8 +400,6 @@ to pass metadata and options to views.
Passing extra options to ``include()``
--------------------------------------
**New in Django development version.**
Similarly, you can pass extra options to ``include()``. When you pass extra
options to ``include()``, *each* line in the included URLconf will be passed
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
===========================================
**New in Django development version.**
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
supported -- you can pass any callable object as the view.