1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

schema-evolution: update from HEAD (v5821)

git-svn-id: http://code.djangoproject.com/svn/django/branches/schema-evolution@5822 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Derek Anderson 2007-08-06 16:50:17 +00:00
parent 0af6ed0c48
commit 5aa0172558
111 changed files with 1068 additions and 487 deletions

View File

@ -45,6 +45,7 @@ answer newbie questions, and generally made Django that much better:
Marty Alchin <gulopine@gamemusic.org>
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
AgarFu <heaven@croasanaso.sytes.net>
Derek Anderson <public@kered.org>
Andreas
andy@jadedplanet.net
Fabrice Aneche <akh@nobugware.com>
@ -96,6 +97,7 @@ answer newbie questions, and generally made Django that much better:
Maximillian Dornseif <md@hudora.de>
Jeremy Dunck <http://dunck.us/>
Andrew Durdin <adurdin@gmail.com>
dusk@woofle.net
Andy Dustman <farcepest@gmail.com>
Clint Ecker
enlight

View File

@ -18,7 +18,7 @@ class LogEntry(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType, blank=True, null=True)
object_id = models.TextField(_('object id'), blank=True, null=True)
object_repr = models.CharField(_('object repr'), maxlength=200)
object_repr = models.CharField(_('object repr'), max_length=200)
action_flag = models.PositiveSmallIntegerField(_('action flag'))
change_message = models.TextField(_('change message'), blank=True)
objects = LogEntryManager()

View File

@ -192,7 +192,7 @@ def auto_populated_field_script(auto_pop_fields, change = False):
t.append(u'document.getElementById("id_%s").onkeyup = function() {' \
' var e = document.getElementById("id_%s");' \
' if(!e._changed) { e.value = URLify(%s, %s);} }; ' % (
f, field.name, add_values, field.maxlength))
f, field.name, add_values, field.max_length))
return u''.join(t)
auto_populated_field_script = register.simple_tag(auto_populated_field_script)

View File

@ -291,7 +291,7 @@ def get_return_data_type(func_name):
DATA_TYPE_MAPPING = {
'AutoField' : _('Integer'),
'BooleanField' : _('Boolean (Either True or False)'),
'CharField' : _('String (up to %(maxlength)s)'),
'CharField' : _('String (up to %(max_length)s)'),
'CommaSeparatedIntegerField': _('Comma-separated integers'),
'DateField' : _('Date (without time)'),
'DateTimeField' : _('Date (with time)'),
@ -310,7 +310,7 @@ DATA_TYPE_MAPPING = {
'PhoneNumberField' : _('Phone number'),
'PositiveIntegerField' : _('Integer'),
'PositiveSmallIntegerField' : _('Integer'),
'SlugField' : _('String (up to %(maxlength)s)'),
'SlugField' : _('String (up to %(max_length)s)'),
'SmallIntegerField' : _('Integer'),
'TextField' : _('Text'),
'TimeField' : _('Time'),

View File

@ -673,7 +673,7 @@ class ChangeList(object):
try:
attr = getattr(lookup_opts.admin.manager.model, field_name)
order_field = attr.admin_order_field
except IndexError:
except AttributeError:
pass
else:
if not isinstance(f.rel, models.ManyToOneRel) or not f.null:

View File

@ -10,10 +10,10 @@ class UserCreationForm(oldforms.Manipulator):
"A form that creates a user, with no privileges, from the given username and password."
def __init__(self):
self.fields = (
oldforms.TextField(field_name='username', length=30, maxlength=30, is_required=True,
oldforms.TextField(field_name='username', length=30, max_length=30, is_required=True,
validator_list=[validators.isAlphaNumeric, self.isValidUsername]),
oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True),
oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True,
validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
)
@ -42,9 +42,9 @@ class AuthenticationForm(oldforms.Manipulator):
"""
self.request = request
self.fields = [
oldforms.TextField(field_name="username", length=15, maxlength=30, is_required=True,
oldforms.TextField(field_name="username", length=15, max_length=30, is_required=True,
validator_list=[self.isValidUser, self.hasCookiesEnabled]),
oldforms.PasswordField(field_name="password", length=15, maxlength=30, is_required=True),
oldforms.PasswordField(field_name="password", length=15, max_length=30, is_required=True),
]
self.user_cache = None
@ -111,11 +111,11 @@ class PasswordChangeForm(oldforms.Manipulator):
def __init__(self, user):
self.user = user
self.fields = (
oldforms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True,
oldforms.PasswordField(field_name="old_password", length=30, max_length=30, is_required=True,
validator_list=[self.isValidOldPassword]),
oldforms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True,
oldforms.PasswordField(field_name="new_password1", length=30, max_length=30, is_required=True,
validator_list=[validators.AlwaysMatchesOtherField('new_password2', _("The two 'new password' fields didn't match."))]),
oldforms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True),
oldforms.PasswordField(field_name="new_password2", length=30, max_length=30, is_required=True),
)
def isValidOldPassword(self, new_data, all_data):
@ -133,8 +133,8 @@ class AdminPasswordChangeForm(oldforms.Manipulator):
def __init__(self, user):
self.user = user
self.fields = (
oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True),
oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True,
validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
)

View File

@ -50,9 +50,9 @@ class Permission(models.Model):
Three basic permissions -- add, change and delete -- are automatically created for each Django model.
"""
name = models.CharField(_('name'), maxlength=50)
name = models.CharField(_('name'), max_length=50)
content_type = models.ForeignKey(ContentType)
codename = models.CharField(_('codename'), maxlength=100)
codename = models.CharField(_('codename'), max_length=100)
class Meta:
verbose_name = _('permission')
@ -70,7 +70,7 @@ class Group(models.Model):
Beyond permissions, groups are a convenient way to categorize users to apply some label, or extended functionality, to them. For example, you could create a group 'Special users', and you could write code that would do special things to those users -- such as giving them access to a members-only portion of your site, or sending them members-only e-mail messages.
"""
name = models.CharField(_('name'), maxlength=80, unique=True)
name = models.CharField(_('name'), max_length=80, unique=True)
permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL)
class Meta:
@ -108,11 +108,11 @@ class User(models.Model):
Username and password are required. Other fields are optional.
"""
username = models.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric], help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
first_name = models.CharField(_('first name'), maxlength=30, blank=True)
last_name = models.CharField(_('last name'), maxlength=30, blank=True)
username = models.CharField(_('username'), max_length=30, unique=True, validator_list=[validators.isAlphaNumeric], help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('e-mail address'), blank=True)
password = models.CharField(_('password'), maxlength=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site."))
is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts."))
is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))

View File

@ -65,8 +65,8 @@ class Comment(models.Model):
user = models.ForeignKey(User, raw_id_admin=True)
content_type = models.ForeignKey(ContentType)
object_id = models.IntegerField(_('object ID'))
headline = models.CharField(_('headline'), maxlength=255, blank=True)
comment = models.TextField(_('comment'), maxlength=3000)
headline = models.CharField(_('headline'), max_length=255, blank=True)
comment = models.TextField(_('comment'), max_length=3000)
rating1 = models.PositiveSmallIntegerField(_('rating #1'), blank=True, null=True)
rating2 = models.PositiveSmallIntegerField(_('rating #2'), blank=True, null=True)
rating3 = models.PositiveSmallIntegerField(_('rating #3'), blank=True, null=True)
@ -164,8 +164,8 @@ class FreeComment(models.Model):
# A FreeComment is a comment by a non-registered user.
content_type = models.ForeignKey(ContentType)
object_id = models.IntegerField(_('object ID'))
comment = models.TextField(_('comment'), maxlength=3000)
person_name = models.CharField(_("person's name"), maxlength=50)
comment = models.TextField(_('comment'), max_length=3000)
person_name = models.CharField(_("person's name"), max_length=50)
submit_date = models.DateTimeField(_('date/time submitted'), auto_now_add=True)
is_public = models.BooleanField(_('is public'))
ip_address = models.IPAddressField(_('ip address'))

View File

@ -29,7 +29,7 @@ class PublicCommentManipulator(AuthenticationForm):
else:
return []
self.fields.extend([
oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
oldforms.LargeTextField(field_name="comment", max_length=3000, is_required=True,
validator_list=[self.hasNoProfanities]),
oldforms.RadioSelectField(field_name="rating1", choices=choices,
is_required=ratings_required and num_rating_choices > 0,
@ -122,9 +122,9 @@ class PublicFreeCommentManipulator(oldforms.Manipulator):
"Manipulator that handles public free (unregistered) comments"
def __init__(self):
self.fields = (
oldforms.TextField(field_name="person_name", maxlength=50, is_required=True,
oldforms.TextField(field_name="person_name", max_length=50, is_required=True,
validator_list=[self.hasNoProfanities]),
oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
oldforms.LargeTextField(field_name="comment", max_length=3000, is_required=True,
validator_list=[self.hasNoProfanities]),
)

View File

@ -32,9 +32,9 @@ class ContentTypeManager(models.Manager):
CONTENT_TYPE_CACHE = {}
class ContentType(models.Model):
name = models.CharField(maxlength=100)
app_label = models.CharField(maxlength=100)
model = models.CharField(_('python model class name'), maxlength=100)
name = models.CharField(max_length=100)
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
class Meta:
verbose_name = _('content type')

View File

@ -4,12 +4,12 @@ from django.contrib.sites.models import Site
from django.utils.translation import ugettext_lazy as _
class FlatPage(models.Model):
url = models.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL], db_index=True,
url = models.CharField(_('URL'), max_length=100, validator_list=[validators.isAlphaNumericURL], db_index=True,
help_text=_("Example: '/about/contact/'. Make sure to have leading and trailing slashes."))
title = models.CharField(_('title'), maxlength=200)
title = models.CharField(_('title'), max_length=200)
content = models.TextField(_('content'))
enable_comments = models.BooleanField(_('enable comments'))
template_name = models.CharField(_('template name'), maxlength=70, blank=True,
template_name = models.CharField(_('template name'), max_length=70, blank=True,
help_text=_("Example: 'flatpages/contact_page.html'. If this isn't provided, the system will use 'flatpages/default.html'."))
registration_required = models.BooleanField(_('registration required'), help_text=_("If this is checked, only logged-in users will be able to view the page."))
sites = models.ManyToManyField(Site)

View File

@ -4,9 +4,9 @@ from django.utils.translation import ugettext_lazy as _
class Redirect(models.Model):
site = models.ForeignKey(Site, radio_admin=models.VERTICAL)
old_path = models.CharField(_('redirect from'), maxlength=200, db_index=True,
old_path = models.CharField(_('redirect from'), max_length=200, db_index=True,
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
new_path = models.CharField(_('redirect to'), maxlength=200, blank=True,
new_path = models.CharField(_('redirect to'), max_length=200, blank=True,
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
class Meta:

View File

@ -65,7 +65,7 @@ class Session(models.Model):
the sessions documentation that is shipped with Django (also available
on the Django website).
"""
session_key = models.CharField(_('session key'), maxlength=40, primary_key=True)
session_key = models.CharField(_('session key'), max_length=40, primary_key=True)
session_data = models.TextField(_('session data'))
expire_date = models.DateTimeField(_('expire date'))
objects = SessionManager()

View File

@ -12,8 +12,8 @@ class SiteManager(models.Manager):
return self.get(pk=sid)
class Site(models.Model):
domain = models.CharField(_('domain name'), maxlength=100)
name = models.CharField(_('display name'), maxlength=50)
domain = models.CharField(_('domain name'), max_length=100)
name = models.CharField(_('display name'), max_length=50)
objects = SiteManager()
class Meta:
db_table = 'django_site'

View File

@ -1064,9 +1064,9 @@ def inspectdb():
field_type, new_params = field_type
extra_params.update(new_params)
# Add maxlength for all CharFields.
# Add max_length for all CharFields.
if field_type == 'CharField' and row[3]:
extra_params['maxlength'] = row[3]
extra_params['max_length'] = row[3]
if field_type == 'DecimalField':
extra_params['max_digits'] = row[4]
@ -1141,8 +1141,8 @@ def get_validation_errors(outfile, app=None):
for f in opts.fields:
if f.name == 'id' and not f.primary_key and opts.pk.name == 'id':
e.add(opts, '"%s": You can\'t use "id" as a field name, because each model automatically gets an "id" field if none of the fields have primary_key=True. You need to either remove/rename your "id" field or add primary_key=True to a field.' % f.name)
if isinstance(f, models.CharField) and f.maxlength in (None, 0):
e.add(opts, '"%s": CharFields require a "maxlength" attribute.' % f.name)
if isinstance(f, models.CharField) and f.max_length in (None, 0):
e.add(opts, '"%s": CharFields require a "max_length" attribute.' % f.name)
if isinstance(f, models.DecimalField):
if f.decimal_places is None:
e.add(opts, '"%s": DecimalFields require a "decimal_places" attribute.' % f.name)
@ -1167,11 +1167,11 @@ def get_validation_errors(outfile, app=None):
if f.db_index not in (None, True, False):
e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name)
# Check that maxlength <= 255 if using older MySQL versions.
# Check that max_length <= 255 if using older MySQL versions.
if settings.DATABASE_ENGINE == 'mysql':
db_version = connection.get_server_version()
if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.maxlength > 255:
e.add(opts, '"%s": %s cannot have a "maxlength" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]])))
if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.max_length > 255:
e.add(opts, '"%s": %s cannot have a "max_length" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]])))
# Check to see if the related field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
@ -1406,7 +1406,7 @@ def createcachetable(tablename):
from django.db import backend, connection, transaction, models
fields = (
# "key" is a reserved word in MySQL, so use "cache_key" instead.
models.CharField(name='cache_key', maxlength=255, unique=True, primary_key=True),
models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
models.TextField(name='value'),
models.DateTimeField(name='expires', db_index=True),
)
@ -1454,6 +1454,10 @@ def run_shell(use_plain=False):
shell.mainloop()
except ImportError:
import code
# Set up a dictionary to serve as the environment for the shell, so
# that tab completion works on objects that are imported at runtime.
# See ticket 5082.
imported_objects = {}
try: # Try activating rlcompleter, because it's handy.
import readline
except ImportError:
@ -1462,8 +1466,9 @@ def run_shell(use_plain=False):
# We don't have to wrap the following import in a 'try', because
# we already know 'readline' was imported successfully.
import rlcompleter
readline.set_completer(rlcompleter.Completer(imported_objects).complete)
readline.parse_and_bind("tab:complete")
code.interact()
code.interact(local=imported_objects)
run_shell.args = '[--plain]'
def dbshell():
@ -1578,7 +1583,7 @@ def load_data(fixture_labels, verbosity=1):
print "Installing %s fixture '%s' from %s." % \
(format, fixture_name, humanize(fixture_dir))
try:
objects = serializers.deserialize(format, fixture)
objects = serializers.deserialize(format, fixture)
for obj in objects:
count[0] += 1
models.add(obj.object.__class__)

View File

@ -442,7 +442,7 @@ def isValidFloat(field_data, all_data):
try:
float(data)
except ValueError:
raise ValidationError, ugettext("Please enter a valid floating point number.")
raise ValidationError, _("Please enter a valid floating point number.")
class HasAllowableSize(object):
"""

View File

@ -1,8 +1,8 @@
DATA_TYPES = {
'AutoField': 'int IDENTITY (1, 1)',
'BooleanField': 'bit',
'CharField': 'varchar(%(maxlength)s)',
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'smalldatetime',
'DateTimeField': 'smalldatetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
@ -17,7 +17,7 @@ DATA_TYPES = {
'PhoneNumberField': 'varchar(20)',
'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(column)s] CHECK ([%(column)s] > 0)',
'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(column)s] CHECK ([%(column)s] > 0)',
'SlugField': 'varchar(%(maxlength)s)',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'text',
'TimeField': 'time',

View File

@ -5,8 +5,8 @@
DATA_TYPES = {
'AutoField': 'integer AUTO_INCREMENT',
'BooleanField': 'bool',
'CharField': 'varchar(%(maxlength)s)',
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
@ -21,7 +21,7 @@ DATA_TYPES = {
'PhoneNumberField': 'varchar(20)',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(maxlength)s)',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',

View File

@ -5,8 +5,8 @@
DATA_TYPES = {
'AutoField': 'integer AUTO_INCREMENT',
'BooleanField': 'bool',
'CharField': 'varchar(%(maxlength)s)',
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
@ -21,7 +21,7 @@ DATA_TYPES = {
'PhoneNumberField': 'varchar(20)',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(maxlength)s)',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',

View File

@ -8,8 +8,8 @@ from django.core import management
DATA_TYPES = {
'AutoField': 'NUMBER(11)',
'BooleanField': 'NUMBER(1) CHECK (%(column)s IN (0,1))',
'CharField': 'NVARCHAR2(%(maxlength)s)',
'CommaSeparatedIntegerField': 'VARCHAR2(%(maxlength)s)',
'CharField': 'NVARCHAR2(%(max_length)s)',
'CommaSeparatedIntegerField': 'VARCHAR2(%(max_length)s)',
'DateField': 'DATE',
'DateTimeField': 'TIMESTAMP',
'DecimalField': 'NUMBER(%(max_digits)s, %(decimal_places)s)',

View File

@ -5,8 +5,8 @@
DATA_TYPES = {
'AutoField': 'serial',
'BooleanField': 'boolean',
'CharField': 'varchar(%(maxlength)s)',
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'timestamp with time zone',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
@ -21,7 +21,7 @@ DATA_TYPES = {
'PhoneNumberField': 'varchar(20)',
'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)',
'PositiveSmallIntegerField': 'smallint CHECK ("%(column)s" >= 0)',
'SlugField': 'varchar(%(maxlength)s)',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'text',
'TimeField': 'time',

View File

@ -4,8 +4,8 @@
DATA_TYPES = {
'AutoField': 'integer',
'BooleanField': 'bool',
'CharField': 'varchar(%(maxlength)s)',
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'decimal',
@ -20,7 +20,7 @@ DATA_TYPES = {
'PhoneNumberField': 'varchar(20)',
'PositiveIntegerField': 'integer unsigned',
'PositiveSmallIntegerField': 'smallint unsigned',
'SlugField': 'varchar(%(maxlength)s)',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'text',
'TimeField': 'time',

View File

@ -137,7 +137,7 @@ class FlexibleFieldLookupDict:
import re
m = re.search(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$', key)
if m:
return ('CharField', {'maxlength': int(m.group(1))})
return ('CharField', {'max_length': int(m.group(1))})
raise KeyError
DATA_TYPES_REVERSE = FlexibleFieldLookupDict()

View File

@ -11,6 +11,7 @@ from django.utils.itercompat import tee
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy, ugettext as _
from django.utils.encoding import smart_unicode, force_unicode, smart_str
from django.utils.maxlength import LegacyMaxlength
import datetime, os, time
try:
import decimal
@ -63,6 +64,9 @@ def manipulator_validator_unique(f, opts, self, field_data, all_data):
# getattr(obj, opts.pk.attname)
class Field(object):
# Provide backwards compatibility for the maxlength attribute and
# argument for this class and all subclasses.
__metaclass__ = LegacyMaxlength
# Designates whether empty strings fundamentally are allowed at the
# database level.
@ -72,7 +76,7 @@ class Field(object):
creation_counter = 0
def __init__(self, verbose_name=None, name=None, primary_key=False,
maxlength=None, unique=False, blank=False, null=False, db_index=False,
max_length=None, unique=False, blank=False, null=False, db_index=False,
core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True,
prepopulate_from=None, unique_for_date=None, unique_for_month=None,
unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
@ -80,7 +84,7 @@ class Field(object):
self.name = name
self.verbose_name = verbose_name
self.primary_key = primary_key
self.maxlength, self.unique = maxlength, unique
self.max_length, self.unique = max_length, unique
self.blank, self.null = blank, null
# Oracle treats the empty string ('') as null, so coerce the null
# option whenever '' is a possible value.
@ -245,8 +249,8 @@ class Field(object):
def prepare_field_objs_and_params(self, manipulator, name_prefix):
params = {'validator_list': self.validator_list[:]}
if self.maxlength and not self.choices: # Don't give SelectFields a maxlength parameter.
params['maxlength'] = self.maxlength
if self.max_length and not self.choices: # Don't give SelectFields a max_length parameter.
params['max_length'] = self.max_length
if self.choices:
if self.radio_admin:
@ -377,6 +381,9 @@ class Field(object):
return self._choices
choices = property(_get_choices)
def save_form_data(self, instance, data):
setattr(instance, self.name, data)
def formfield(self, form_class=forms.CharField, **kwargs):
"Returns a django.newforms.Field instance for this database Field."
defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
@ -462,7 +469,7 @@ class CharField(Field):
return smart_unicode(value)
def formfield(self, **kwargs):
defaults = {'max_length': self.maxlength}
defaults = {'max_length': self.max_length}
defaults.update(kwargs)
return super(CharField, self).formfield(**defaults)
@ -671,7 +678,7 @@ class DecimalField(Field):
class EmailField(CharField):
def __init__(self, *args, **kwargs):
kwargs['maxlength'] = 75
kwargs['max_length'] = 75
CharField.__init__(self, *args, **kwargs)
def get_internal_type(self):
@ -693,6 +700,13 @@ class FileField(Field):
self.upload_to = upload_to
Field.__init__(self, verbose_name, name, **kwargs)
def get_db_prep_save(self, value):
"Returns field's value prepared for saving into a database."
# Need to convert UploadedFile objects provided via a form to unicode for database insertion
if value is None:
return None
return unicode(value)
def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
if not self.blank:
@ -769,6 +783,19 @@ class FileField(Field):
f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
return os.path.normpath(f)
def save_form_data(self, instance, data):
if data:
getattr(instance, "save_%s_file" % self.name)(os.path.join(self.upload_to, data.filename), data.content, save=False)
def formfield(self, **kwargs):
defaults = {'form_class': forms.FileField}
# If a file has been provided previously, then the form doesn't require
# that a new file is provided this time.
if 'initial' in kwargs:
defaults['required'] = False
defaults.update(kwargs)
return super(FileField, self).formfield(**defaults)
class FilePathField(Field):
def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs):
self.path, self.match, self.recursive = path, match, recursive
@ -817,6 +844,10 @@ class ImageField(FileField):
setattr(new_object, self.height_field, getattr(original_object, self.height_field))
new_object.save()
def formfield(self, **kwargs):
defaults = {'form_class': forms.ImageField}
return super(ImageField, self).formfield(**defaults)
class IntegerField(Field):
empty_strings_allowed = False
def get_manipulator_field_objs(self):
@ -830,7 +861,7 @@ class IntegerField(Field):
class IPAddressField(Field):
empty_strings_allowed = False
def __init__(self, *args, **kwargs):
kwargs['maxlength'] = 15
kwargs['max_length'] = 15
Field.__init__(self, *args, **kwargs)
def get_manipulator_field_objs(self):
@ -878,7 +909,7 @@ class PositiveSmallIntegerField(IntegerField):
class SlugField(Field):
def __init__(self, *args, **kwargs):
kwargs['maxlength'] = kwargs.get('maxlength', 50)
kwargs['max_length'] = kwargs.get('max_length', 50)
kwargs.setdefault('validator_list', []).append(validators.isSlug)
# Set db_index=True unless it's been set manually.
if 'db_index' not in kwargs:
@ -964,7 +995,7 @@ class TimeField(Field):
class URLField(CharField):
def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
kwargs['maxlength'] = kwargs.get('maxlength', 200)
kwargs['max_length'] = kwargs.get('max_length', 200)
if verify_exists:
kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
self.verify_exists = verify_exists

View File

@ -756,6 +756,9 @@ class ManyToManyField(RelatedField, Field):
"Returns the value of this field in the given model instance."
return getattr(obj, self.attname).all()
def save_form_data(self, instance, data):
setattr(instance, self.attname, data)
def formfield(self, **kwargs):
defaults = {'form_class': forms.ModelMultipleChoiceField, 'queryset': self.rel.to._default_manager.all()}
defaults.update(kwargs)

View File

@ -53,7 +53,7 @@ class SelectDateWidget(Widget):
return u'\n'.join(output)
def value_from_datadict(self, data, name):
def value_from_datadict(self, data, files, name):
y, m, d = data.get(self.year_field % name), data.get(self.month_field % name), data.get(self.day_field % name)
if y and m and d:
return '%s-%s-%s' % (y, m, d)

View File

@ -7,10 +7,10 @@ import re
import time
from django.utils.translation import ugettext
from django.utils.encoding import smart_unicode
from django.utils.encoding import StrAndUnicode, smart_unicode
from util import ErrorList, ValidationError
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
try:
from decimal import Decimal, DecimalException
@ -22,7 +22,7 @@ __all__ = (
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
'DEFAULT_TIME_INPUT_FORMATS', 'TimeField',
'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField',
'RegexField', 'EmailField', 'URLField', 'BooleanField',
'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField',
'ChoiceField', 'NullBooleanField', 'MultipleChoiceField',
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
'SplitDateTimeField',
@ -120,6 +120,7 @@ class CharField(Field):
def widget_attrs(self, widget):
if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)):
# The HTML attribute is maxlength, not max_length.
return {'maxlength': str(self.max_length)}
class IntegerField(Field):
@ -347,6 +348,55 @@ except ImportError:
# It's OK if Django settings aren't configured.
URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
class UploadedFile(StrAndUnicode):
"A wrapper for files uploaded in a FileField"
def __init__(self, filename, content):
self.filename = filename
self.content = content
def __unicode__(self):
"""
The unicode representation is the filename, so that the pre-database-insertion
logic can use UploadedFile objects
"""
return self.filename
class FileField(Field):
widget = FileInput
def __init__(self, *args, **kwargs):
super(FileField, self).__init__(*args, **kwargs)
def clean(self, data):
super(FileField, self).clean(data)
if not self.required and data in EMPTY_VALUES:
return None
try:
f = UploadedFile(data['filename'], data['content'])
except TypeError:
raise ValidationError(ugettext(u"No file was submitted. Check the encoding type on the form."))
except KeyError:
raise ValidationError(ugettext(u"No file was submitted."))
if not f.content:
raise ValidationError(ugettext(u"The submitted file is empty."))
return f
class ImageField(FileField):
def clean(self, data):
"""
Checks that the file-upload field data contains a valid image (GIF, JPG,
PNG, possibly others -- whatever the Python Imaging Library supports).
"""
f = super(ImageField, self).clean(data)
if f is None:
return None
from PIL import Image
from cStringIO import StringIO
try:
Image.open(StringIO(f.content))
except IOError: # Python Imaging Library doesn't recognize it as an image
raise ValidationError(ugettext(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."))
return f
class URLField(RegexField):
def __init__(self, max_length=None, min_length=None, verify_exists=False,
validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs):

View File

@ -57,9 +57,10 @@ class BaseForm(StrAndUnicode):
# class is different than Form. See the comments by the Form class for more
# information. Any improvements to the form API should be made to *this*
# class, not to the Form class.
def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None):
self.is_bound = data is not None
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None):
self.is_bound = data is not None or files is not None
self.data = data or {}
self.files = files or {}
self.auto_id = auto_id
self.prefix = prefix
self.initial = initial or {}
@ -88,7 +89,7 @@ class BaseForm(StrAndUnicode):
return BoundField(self, field, name)
def _get_errors(self):
"Returns an ErrorDict for self.data"
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
@ -179,10 +180,10 @@ class BaseForm(StrAndUnicode):
return
self.cleaned_data = {}
for name, field in self.fields.items():
# value_from_datadict() gets the data from the dictionary.
# value_from_datadict() gets the data from the data dictionaries.
# Each widget type knows how to retrieve its own data, because some
# widgets split data over several HTML fields.
value = field.widget.value_from_datadict(self.data, self.add_prefix(name))
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
try:
value = field.clean(value)
self.cleaned_data[name] = value
@ -283,7 +284,7 @@ class BoundField(StrAndUnicode):
"""
Returns the data for this BoundField, or None if it wasn't given.
"""
return self.field.widget.value_from_datadict(self.form.data, self.html_name)
return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
data = property(_data)
def label_tag(self, contents=None, attrs=None):

View File

@ -34,18 +34,24 @@ def save_instance(form, instance, fields=None, fail_message='saved', commit=True
continue
if fields and f.name not in fields:
continue
setattr(instance, f.name, cleaned_data[f.name])
if commit:
instance.save()
f.save_form_data(instance, cleaned_data[f.name])
# Wrap up the saving of m2m data as a function
def save_m2m():
opts = instance.__class__._meta
cleaned_data = form.cleaned_data
for f in opts.many_to_many:
if fields and f.name not in fields:
continue
if f.name in cleaned_data:
setattr(instance, f.attname, cleaned_data[f.name])
# GOTCHA: If many-to-many data is given and commit=False, the many-to-many
# data will be lost. This happens because a many-to-many options cannot be
# set on an object until after it's saved. Maybe we should raise an
# exception in that case.
f.save_form_data(instance, cleaned_data[f.name])
if commit:
# If we are committing, save the instance and the m2m data immediately
instance.save()
save_m2m()
else:
# We're not committing. Add a method to the form to allow deferred
# saving of m2m data
form.save_m2m = save_m2m
return instance
def make_model_save(model, fields, fail_message):

View File

@ -47,7 +47,7 @@ class Widget(object):
attrs.update(extra_attrs)
return attrs
def value_from_datadict(self, data, name):
def value_from_datadict(self, data, files, name):
"""
Given a dictionary of data and this widget's name, returns the value
of this widget. Returns None if it's not provided.
@ -113,7 +113,7 @@ class MultipleHiddenInput(HiddenInput):
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
return u'\n'.join([(u'<input%s />' % flatatt(dict(value=force_unicode(v), **final_attrs))) for v in value])
def value_from_datadict(self, data, name):
def value_from_datadict(self, data, files, name):
if isinstance(data, MultiValueDict):
return data.getlist(name)
return data.get(name, None)
@ -121,6 +121,13 @@ class MultipleHiddenInput(HiddenInput):
class FileInput(Input):
input_type = 'file'
def render(self, name, value, attrs=None):
return super(FileInput, self).render(name, None, attrs=attrs)
def value_from_datadict(self, data, files, name):
"File widgets take data from FILES, not POST"
return files.get(name, None)
class Textarea(Widget):
def __init__(self, attrs=None):
# The 'rows' and 'cols' attributes are required for HTML correctness.
@ -188,7 +195,7 @@ class NullBooleanSelect(Select):
value = u'1'
return super(NullBooleanSelect, self).render(name, value, attrs, choices)
def value_from_datadict(self, data, name):
def value_from_datadict(self, data, files, name):
value = data.get(name, None)
return {u'2': True, u'3': False, True: True, False: False}.get(value, None)
@ -210,7 +217,7 @@ class SelectMultiple(Widget):
output.append(u'</select>')
return u'\n'.join(output)
def value_from_datadict(self, data, name):
def value_from_datadict(self, data, files, name):
if isinstance(data, MultiValueDict):
return data.getlist(name)
return data.get(name, None)
@ -377,8 +384,8 @@ class MultiWidget(Widget):
return id_
id_for_label = classmethod(id_for_label)
def value_from_datadict(self, data, name):
return [widget.value_from_datadict(data, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
def value_from_datadict(self, data, files, name):
return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
def format_output(self, rendered_widgets):
"""

View File

@ -4,6 +4,7 @@ from django.utils.html import escape
from django.conf import settings
from django.utils.translation import ugettext, ungettext
from django.utils.encoding import smart_unicode, force_unicode
from django.utils.maxlength import LegacyMaxlength
FORM_FIELD_ID_PREFIX = 'id_'
@ -302,6 +303,9 @@ class FormField(object):
Subclasses should also implement a render(data) method, which is responsible
for rending the form field in XHTML.
"""
# Provide backwards compatibility for the maxlength attribute and
# argument for this class and all subclasses.
__metaclass__ = LegacyMaxlength
def __str__(self):
return unicode(self).encode('utf-8')
@ -390,19 +394,19 @@ class FormField(object):
class TextField(FormField):
input_type = "text"
def __init__(self, field_name, length=30, maxlength=None, is_required=False, validator_list=None, member_name=None):
def __init__(self, field_name, length=30, max_length=None, is_required=False, validator_list=None, member_name=None):
if validator_list is None: validator_list = []
self.field_name = field_name
self.length, self.maxlength = length, maxlength
self.length, self.max_length = length, max_length
self.is_required = is_required
self.validator_list = [self.isValidLength, self.hasNoNewlines] + validator_list
if member_name != None:
self.member_name = member_name
def isValidLength(self, data, form):
if data and self.maxlength and len(smart_unicode(data)) > self.maxlength:
if data and self.max_length and len(smart_unicode(data)) > self.max_length:
raise validators.ValidationError, ungettext("Ensure your text is less than %s character.",
"Ensure your text is less than %s characters.", self.maxlength) % self.maxlength
"Ensure your text is less than %s characters.", self.max_length) % self.max_length
def hasNoNewlines(self, data, form):
if data and '\n' in data:
@ -411,12 +415,12 @@ class TextField(FormField):
def render(self, data):
if data is None:
data = u''
maxlength = u''
if self.maxlength:
maxlength = u'maxlength="%s" ' % self.maxlength
max_length = u''
if self.max_length:
max_length = u'maxlength="%s" ' % self.max_length
return u'<input type="%s" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \
(self.input_type, self.get_id(), self.__class__.__name__, self.is_required and u' required' or '',
self.field_name, self.length, escape(data), maxlength)
self.field_name, self.length, escape(data), max_length)
def html2python(data):
return data
@ -426,14 +430,14 @@ class PasswordField(TextField):
input_type = "password"
class LargeTextField(TextField):
def __init__(self, field_name, rows=10, cols=40, is_required=False, validator_list=None, maxlength=None):
def __init__(self, field_name, rows=10, cols=40, is_required=False, validator_list=None, max_length=None):
if validator_list is None: validator_list = []
self.field_name = field_name
self.rows, self.cols, self.is_required = rows, cols, is_required
self.validator_list = validator_list[:]
if maxlength:
if max_length:
self.validator_list.append(self.isValidLength)
self.maxlength = maxlength
self.max_length = max_length
def render(self, data):
if data is None:
@ -710,12 +714,12 @@ class ImageUploadField(FileUploadField):
####################
class IntegerField(TextField):
def __init__(self, field_name, length=10, maxlength=None, is_required=False, validator_list=None, member_name=None):
def __init__(self, field_name, length=10, max_length=None, is_required=False, validator_list=None, member_name=None):
if validator_list is None: validator_list = []
validator_list = [self.isInteger] + validator_list
if member_name is not None:
self.member_name = member_name
TextField.__init__(self, field_name, length, maxlength, is_required, validator_list)
TextField.__init__(self, field_name, length, max_length, is_required, validator_list)
def isInteger(self, field_data, all_data):
try:
@ -730,30 +734,30 @@ class IntegerField(TextField):
html2python = staticmethod(html2python)
class SmallIntegerField(IntegerField):
def __init__(self, field_name, length=5, maxlength=5, is_required=False, validator_list=None):
def __init__(self, field_name, length=5, max_length=5, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isSmallInteger] + validator_list
IntegerField.__init__(self, field_name, length, maxlength, is_required, validator_list)
IntegerField.__init__(self, field_name, length, max_length, is_required, validator_list)
def isSmallInteger(self, field_data, all_data):
if not -32768 <= int(field_data) <= 32767:
raise validators.CriticalValidationError, ugettext("Enter a whole number between -32,768 and 32,767.")
class PositiveIntegerField(IntegerField):
def __init__(self, field_name, length=10, maxlength=None, is_required=False, validator_list=None):
def __init__(self, field_name, length=10, max_length=None, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isPositive] + validator_list
IntegerField.__init__(self, field_name, length, maxlength, is_required, validator_list)
IntegerField.__init__(self, field_name, length, max_length, is_required, validator_list)
def isPositive(self, field_data, all_data):
if int(field_data) < 0:
raise validators.CriticalValidationError, ugettext("Enter a positive number.")
class PositiveSmallIntegerField(IntegerField):
def __init__(self, field_name, length=5, maxlength=None, is_required=False, validator_list=None):
def __init__(self, field_name, length=5, max_length=None, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isPositiveSmall] + validator_list
IntegerField.__init__(self, field_name, length, maxlength, is_required, validator_list)
IntegerField.__init__(self, field_name, length, max_length, is_required, validator_list)
def isPositiveSmall(self, field_data, all_data):
if not 0 <= int(field_data) <= 32767:
@ -806,10 +810,10 @@ class DecimalField(TextField):
class DatetimeField(TextField):
"""A FormField that automatically converts its data to a datetime.datetime object.
The data should be in the format YYYY-MM-DD HH:MM:SS."""
def __init__(self, field_name, length=30, maxlength=None, is_required=False, validator_list=None):
def __init__(self, field_name, length=30, max_length=None, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
self.field_name = field_name
self.length, self.maxlength = length, maxlength
self.length, self.max_length = length, max_length
self.is_required = is_required
self.validator_list = [validators.isValidANSIDatetime] + validator_list
@ -836,7 +840,7 @@ class DateField(TextField):
def __init__(self, field_name, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isValidDate] + validator_list
TextField.__init__(self, field_name, length=10, maxlength=10,
TextField.__init__(self, field_name, length=10, max_length=10,
is_required=is_required, validator_list=validator_list)
def isValidDate(self, field_data, all_data):
@ -861,7 +865,7 @@ class TimeField(TextField):
def __init__(self, field_name, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isValidTime] + validator_list
TextField.__init__(self, field_name, length=8, maxlength=8,
TextField.__init__(self, field_name, length=8, max_length=8,
is_required=is_required, validator_list=validator_list)
def isValidTime(self, field_data, all_data):
@ -893,10 +897,10 @@ class TimeField(TextField):
class EmailField(TextField):
"A convenience FormField for validating e-mail addresses"
def __init__(self, field_name, length=50, maxlength=75, is_required=False, validator_list=None):
def __init__(self, field_name, length=50, max_length=75, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isValidEmail] + validator_list
TextField.__init__(self, field_name, length, maxlength=maxlength,
TextField.__init__(self, field_name, length, max_length=max_length,
is_required=is_required, validator_list=validator_list)
def isValidEmail(self, field_data, all_data):
@ -907,10 +911,10 @@ class EmailField(TextField):
class URLField(TextField):
"A convenience FormField for validating URLs"
def __init__(self, field_name, length=50, maxlength=200, is_required=False, validator_list=None):
def __init__(self, field_name, length=50, max_length=200, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isValidURL] + validator_list
TextField.__init__(self, field_name, length=length, maxlength=maxlength,
TextField.__init__(self, field_name, length=length, max_length=max_length,
is_required=is_required, validator_list=validator_list)
def isValidURL(self, field_data, all_data):
@ -920,10 +924,10 @@ class URLField(TextField):
raise validators.CriticalValidationError, e.messages
class IPAddressField(TextField):
def __init__(self, field_name, length=15, maxlength=15, is_required=False, validator_list=None):
def __init__(self, field_name, length=15, max_length=15, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isValidIPAddress] + validator_list
TextField.__init__(self, field_name, length=length, maxlength=maxlength,
TextField.__init__(self, field_name, length=length, max_length=max_length,
is_required=is_required, validator_list=validator_list)
def isValidIPAddress(self, field_data, all_data):
@ -970,7 +974,7 @@ class PhoneNumberField(TextField):
def __init__(self, field_name, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isValidPhone] + validator_list
TextField.__init__(self, field_name, length=12, maxlength=12,
TextField.__init__(self, field_name, length=12, max_length=12,
is_required=is_required, validator_list=validator_list)
def isValidPhone(self, field_data, all_data):
@ -984,7 +988,7 @@ class USStateField(TextField):
def __init__(self, field_name, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isValidUSState] + validator_list
TextField.__init__(self, field_name, length=2, maxlength=2,
TextField.__init__(self, field_name, length=2, max_length=2,
is_required=is_required, validator_list=validator_list)
def isValidUSState(self, field_data, all_data):
@ -1001,10 +1005,10 @@ class USStateField(TextField):
class CommaSeparatedIntegerField(TextField):
"A convenience FormField for validating comma-separated integer fields"
def __init__(self, field_name, maxlength=None, is_required=False, validator_list=None):
def __init__(self, field_name, max_length=None, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
validator_list = [self.isCommaSeparatedIntegerList] + validator_list
TextField.__init__(self, field_name, length=20, maxlength=maxlength,
TextField.__init__(self, field_name, length=20, max_length=max_length,
is_required=is_required, validator_list=validator_list)
def isCommaSeparatedIntegerList(self, field_data, all_data):

View File

@ -649,8 +649,8 @@ def do_if(parser, token):
As you can see, the ``if`` tag can take an option ``{% else %}`` clause that
will be displayed if the test fails.
``if`` tags may use ``or`` or ``not`` to test a number of variables or to
negate a given variable::
``if`` tags may use ``or``, ``and`` or ``not`` to test a number of
variables or to negate a given variable::
{% if not athlete_list %}
There are no athletes.
@ -660,19 +660,32 @@ def do_if(parser, token):
There are some athletes or some coaches.
{% endif %}
{% if athlete_list and coach_list %}
Both atheletes and coaches are available.
{% endif %}
{% if not athlete_list or coach_list %}
There are no athletes, or there are some coaches.
{% endif %}
For simplicity, ``if`` tags do not allow ``and`` clauses. Use nested ``if``
tags instead::
{% if athlete_list %}
{% if coach_list %}
Number of athletes: {{ athlete_list|count }}.
Number of coaches: {{ coach_list|count }}.
{% endif %}
{% if athlete_list and not coach_list %}
There are some athletes and absolutely no coaches.
{% endif %}
``if`` tags do not allow ``and`` and ``or`` clauses with the same
tag, because the order of logic would be ambigous. For example,
this is invalid::
{% if athlete_list and coach_list or cheerleader_list %}
If you need to combine and and or to do advanced logic, just use
nested if tags. For example:
{% if athlete_list %}
{% if coach_list or cheerleader_list %}
We have athletes, and either coaches or cheerleaders!
{% endif %}
{% endif %}
"""
bits = token.contents.split()
del bits[0]

View File

@ -1,6 +1,5 @@
import types
import urllib
from django.conf import settings
from django.utils.functional import Promise
class StrAndUnicode(object):

67
django/utils/maxlength.py Normal file
View File

@ -0,0 +1,67 @@
"""
Utilities for providing backwards compatibility for the maxlength argument,
which has been replaced by max_length, see ticket #2101.
"""
from warnings import warn
def get_maxlength(self):
return self.max_length
def set_maxlength(self, value):
self.max_length = value
def legacy_maxlength(max_length, maxlength):
"""
Consolidates max_length and maxlength, providing backwards compatibilty
for the legacy "maxlength" argument.
If one of max_length or maxlength is given, then that value is returned.
If both are given, a TypeError is raised.
If maxlength is used at all, a deprecation warning is issued.
"""
if maxlength is not None:
warn("maxlength is deprecated, use max_length instead.",
PendingDeprecationWarning,
stacklevel=3)
if max_length is not None:
raise TypeError("field can not take both the max_length"
" argument and the legacy maxlength argument.")
max_length = maxlength
return max_length
def remove_maxlength(func):
"""
A decorator to be used on a class's __init__ that provides backwards
compatibilty for the legacy "maxlength" keyword argument, i.e.
name = models.CharField(maxlength=20)
It does this by changing the passed "maxlength" keyword argument
(if it exists) into a "max_length" keyword argument.
"""
def inner(self, *args, **kwargs):
max_length = kwargs.get('max_length', None)
# pop maxlength because we don't want this going to __init__.
maxlength = kwargs.pop('maxlength', None)
max_length = legacy_maxlength(max_length, maxlength)
# Only set the max_length keyword argument if we got a value back.
if max_length is not None:
kwargs['max_length'] = max_length
func(self, *args, **kwargs)
return inner
# This metaclass is used in two places, and should be removed when legacy
# support for maxlength is dropped.
# * oldforms.FormField
# * db.models.fields.Field
class LegacyMaxlength(type):
"""
Metaclass for providing backwards compatibility support for the
"maxlength" keyword argument.
"""
def __init__(cls, name, bases, attrs):
super(LegacyMaxlength, cls).__init__(name, bases, attrs)
# Decorate the class's __init__ to remove any maxlength keyword.
cls.__init__ = remove_maxlength(cls.__init__)
# Support accessing and setting to the legacy maxlength attribute.
cls.maxlength = property(get_maxlength, set_maxlength)

View File

@ -214,7 +214,7 @@ A framework for generating syndication feeds, in RSS and Atom, quite easily.
See the `syndication documentation`_.
.. _syndication documentation: ../syndication/
.. _syndication documentation: ../syndication_feeds/
Other add-ons
=============

View File

@ -82,9 +82,6 @@ that 90% of Django can be considered forwards-compatible at this point.
That said, these APIs should *not* be considered stable, and are likely to
change:
- `Forms and validation`_ will most likely be completely rewritten to
deemphasize Manipulators in favor of validation-aware models.
- `Serialization`_ is under heavy development; changes are likely.
- The `authentication`_ framework is changing to be far more flexible, and
@ -114,7 +111,7 @@ change:
.. _sending email: ../email/
.. _sessions: ../sessions/
.. _settings: ../settings/
.. _syndication: ../syndication/
.. _syndication: ../syndication_feeds/
.. _template language: ../templates/
.. _transactions: ../transactions/
.. _url dispatch: ../url_dispatch/

View File

@ -234,7 +234,7 @@ the setting and checking of these values behind the scenes.
Previous Django versions, such as 0.90, used simple MD5 hashes without password
salts. For backwards compatibility, those are still supported; they'll be
converted automatically to the new style the first time ``check_password()``
converted automatically to the new style the first time ``User.check_password()``
works correctly for a given user.
Anonymous users

View File

@ -340,14 +340,14 @@ Model style
Do this::
class Person(models.Model):
first_name = models.CharField(maxlength=20)
last_name = models.CharField(maxlength=40)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
Don't do this::
class Person(models.Model):
FirstName = models.CharField(maxlength=20)
Last_Name = models.CharField(maxlength=40)
FirstName = models.CharField(max_length=20)
Last_Name = models.CharField(max_length=40)
* The ``class Meta`` should appear *after* the fields are defined, with
a single blank line separating the fields and the class definition.
@ -355,8 +355,8 @@ Model style
Do this::
class Person(models.Model):
first_name = models.CharField(maxlength=20)
last_name = models.CharField(maxlength=40)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
@ -364,8 +364,8 @@ Model style
Don't do this::
class Person(models.Model):
first_name = models.CharField(maxlength=20)
last_name = models.CharField(maxlength=40)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
@ -375,8 +375,8 @@ Model style
class Meta:
verbose_name_plural = 'people'
first_name = models.CharField(maxlength=20)
last_name = models.CharField(maxlength=40)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
* The order of model inner classes and standard methods should be as
follows (noting that these are not all required):

View File

@ -124,7 +124,7 @@ Several other MySQLdb connection options may be useful, such as ``ssl``,
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
`MySQLdb documentation`_ for more details.
.. _settings documentation: http://www.djangoproject.com/documentation/settings/#database-engine
.. _settings documentation: ../settings/#database-engine
.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/

View File

@ -12,14 +12,14 @@ Throughout this reference, we'll refer to the following models, which comprise
a weblog application::
class Blog(models.Model):
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
tagline = models.TextField()
def __unicode__(self):
return self.name
class Author(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
email = models.EmailField()
def __unicode__(self):
@ -27,7 +27,7 @@ a weblog application::
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(maxlength=255)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateTimeField()
authors = models.ManyToManyField(Author)
@ -1503,7 +1503,7 @@ precede the definition of any keyword arguments. For example::
See the `OR lookups examples page`_ for more examples.
.. _OR lookups examples page: http://www.djangoproject.com/documentation/models/or_lookups/
.. _OR lookups examples page: ../models/or_lookups/
Related objects
===============
@ -1806,8 +1806,8 @@ following model::
('F', 'Female'),
)
class Person(models.Model):
name = models.CharField(maxlength=20)
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
name = models.CharField(max_length=20)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
...each ``Person`` instance will have a ``get_gender_display()`` method. Example::
@ -1834,7 +1834,7 @@ Note that in the case of identical date values, these methods will use the ID
as a fallback check. This guarantees that no records are skipped or duplicated.
For a full example, see the `lookup API sample model`_.
.. _lookup API sample model: http://www.djangoproject.com/documentation/models/lookup/
.. _lookup API sample model: ../models/lookup/
get_FOO_filename()
------------------

View File

@ -314,7 +314,7 @@ To send a text and HTML combination, you could write::
subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
text_content = 'This is an important message.'
html_content = '<p>This is an <strong>important</strong> message.'
html_content = '<p>This is an <strong>important</strong> message.</p>'
msg = EmailMultiAlternatives(subject, text_content, from_email, to)
msg.attach_alternative(html_content, "text/html")
msg.send()

View File

@ -42,7 +42,10 @@ Listen to his music. You'll like it.
Django is pronounced **JANG**-oh. Rhymes with FANG-oh. The "D" is silent.
We've also recorded an `audio clip of the pronunciation`_.
.. _Django Reinhardt: http://en.wikipedia.org/wiki/Django_Reinhardt
.. _audio clip of the pronunciation: http://red-bean.com/~adrian/django_pronunciation.mp3
Is Django stable?
-----------------

View File

@ -37,11 +37,11 @@ this document, we'll be working with the following model, a "place" object::
)
class Place(models.Model):
name = models.CharField(maxlength=100)
address = models.CharField(maxlength=100, blank=True)
city = models.CharField(maxlength=50, blank=True)
name = models.CharField(max_length=100)
address = models.CharField(max_length=100, blank=True)
city = models.CharField(max_length=50, blank=True)
state = models.USStateField()
zip_code = models.CharField(maxlength=5, blank=True)
zip_code = models.CharField(max_length=5, blank=True)
place_type = models.IntegerField(choices=PLACE_TYPES)
class Admin:
@ -388,7 +388,7 @@ for a "contact" form on a website::
def __init__(self):
self.fields = (
forms.EmailField(field_name="from", is_required=True),
forms.TextField(field_name="subject", length=30, maxlength=200, is_required=True),
forms.TextField(field_name="subject", length=30, max_length=200, is_required=True),
forms.SelectField(field_name="urgency", choices=urgency_choices),
forms.LargeTextField(field_name="contents", is_required=True),
)

View File

@ -22,7 +22,7 @@ A companion to this document is the `official repository of model examples`_.
``tests/modeltests`` directory.)
.. _Database API reference: ../db-api/
.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
.. _official repository of model examples: ../models/
Quick example
=============
@ -33,8 +33,8 @@ This example model defines a ``Person``, which has a ``first_name`` and
from django.db import models
class Person(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
``first_name`` and ``last_name`` are *fields* of the model. Each field is
specified as a class attribute, and each attribute maps to a database column.
@ -69,13 +69,13 @@ attributes.
Example::
class Musician(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
instrument = models.CharField(maxlength=100)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician)
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
@ -142,14 +142,18 @@ For large amounts of text, use ``TextField``.
The admin represents this as an ``<input type="text">`` (a single-line input).
``CharField`` has an extra required argument, ``maxlength``, the maximum length
(in characters) of the field. The maxlength is enforced at the database level
``CharField`` has an extra required argument, ``max_length``, the maximum length
(in characters) of the field. The max_length is enforced at the database level
and in Django's validation.
``CommaSeparatedIntegerField``
Django veterans: Note that the argument is now called ``max_length`` to
provide consistency throughout Django. There is full legacy support for
the old ``maxlength`` argument, but ``max_length`` is prefered.
``CommaSeparatedIntegerField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A field of integers separated by commas. As in ``CharField``, the ``maxlength``
A field of integers separated by commas. As in ``CharField``, the ``max_length``
argument is required.
``DateField``
@ -217,7 +221,7 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
~~~~~~~~~~~~~~
A ``CharField`` that checks that the value is a valid e-mail address.
This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
This doesn't accept ``max_length``; its ``max_length`` is automatically set to
75.
``FileField``
@ -400,7 +404,7 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
containing only letters, numbers, underscores or hyphens. They're generally
used in URLs.
Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
Like a CharField, you can specify ``max_length``. If ``max_length`` is
not specified, Django will use a default length of 50.
Implies ``db_index=True``.
@ -447,9 +451,9 @@ and doesn't give a 404 response).
The admin represents this as an ``<input type="text">`` (a single-line input).
``URLField`` takes an optional argument, ``maxlength``, the maximum length (in
characters) of the field. The maxlength is enforced at the database level and
in Django's validation. If you don't specify ``maxlength``, a default of 200
``URLField`` takes an optional argument, ``max_length``, the maximum length (in
characters) of the field. The maximum length is enforced at the database level and
in Django's validation. If you don't specify ``max_length``, a default of 200
is used.
``USStateField``
@ -536,7 +540,7 @@ The choices list can be defined either as part of your model class::
('M', 'Male'),
('F', 'Female'),
)
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
or outside your model class altogether::
@ -545,7 +549,7 @@ or outside your model class altogether::
('F', 'Female'),
)
class Foo(models.Model):
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
For each model field that has ``choices`` set, Django will add a method to
retrieve the human-readable name for the field's current value. See
@ -620,6 +624,12 @@ Extra "help" text to be displayed under the field on the object's admin
form. It's useful for documentation even if your object doesn't have an
admin form.
Note that this value is *not* HTML-escaped when it's displayed in the admin
interface. This lets you include HTML in ``help_text`` if you so desire. For
example::
help_text="Please use the following format: <em>YYYY-MM-DD</em>."
``primary_key``
~~~~~~~~~~~~~~~
@ -698,11 +708,11 @@ it using the field's attribute name, converting underscores to spaces.
In this example, the verbose name is ``"Person's first name"``::
first_name = models.CharField("Person's first name", maxlength=30)
first_name = models.CharField("Person's first name", max_length=30)
In this example, the verbose name is ``"first name"``::
first_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
``ForeignKey``, ``ManyToManyField`` and ``OneToOneField`` require the first
argument to be a model class, so use the ``verbose_name`` keyword argument::
@ -775,7 +785,7 @@ You can, of course, call the field whatever you want. For example::
See the `Many-to-one relationship model example`_ for a full example.
.. _Many-to-one relationship model example: http://www.djangoproject.com/documentation/models/many_to_one/
.. _Many-to-one relationship model example: ../models/many_to_one/
``ForeignKey`` fields take a number of extra arguments for defining how the
relationship should work. All are optional:
@ -902,7 +912,7 @@ set up above, the ``Pizza`` admin form would let users select the toppings.
See the `Many-to-many relationship model example`_ for a full example.
.. _Many-to-many relationship model example: http://www.djangoproject.com/documentation/models/many_to_many/
.. _Many-to-many relationship model example: ../models/many_to_many/
``ManyToManyField`` objects take a number of extra arguments for defining how
the relationship should work. All are optional:
@ -979,7 +989,7 @@ as a read-only field when you edit an object in the admin interface:
See the `One-to-one relationship model example`_ for a full example.
.. _One-to-one relationship model example: http://www.djangoproject.com/documentation/models/one_to_one/
.. _One-to-one relationship model example: ../models/one_to_one/
Custom field types
------------------
@ -1027,8 +1037,8 @@ Once you have ``MytypeField``, you can use it in any model, just like any other
``Field`` type::
class Person(models.Model):
name = models.CharField(maxlength=80)
gender = models.CharField(maxlength=1)
name = models.CharField(max_length=80)
gender = models.CharField(max_length=1)
something_else = MytypeField()
If you aim to build a database-agnostic application, you should account for
@ -1074,12 +1084,12 @@ time -- i.e., when the class is instantiated. To do that, just implement
# This is a much more flexible example.
class BetterCharField(models.Field):
def __init__(self, maxlength, *args, **kwargs):
self.maxlength = maxlength
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(BetterCharField, self).__init__(*args, **kwargs)
def db_type(self):
return 'char(%s)' % self.maxlength
return 'char(%s)' % self.max_length
# In the model:
class MyModel(models.Model):
@ -1096,7 +1106,7 @@ Meta options
Give your model metadata by using an inner ``class Meta``, like so::
class Foo(models.Model):
bar = models.CharField(maxlength=30)
bar = models.CharField(max_length=30)
class Meta:
# ...
@ -1186,7 +1196,7 @@ See `Specifying ordering`_ for more examples.
Note that, regardless of how many fields are in ``ordering``, the admin
site uses only the first field.
.. _Specifying ordering: http://www.djangoproject.com/documentation/models/ordering/
.. _Specifying ordering: ../models/ordering/
``permissions``
---------------
@ -1270,8 +1280,8 @@ If you want your model to be visible to Django's admin site, give your model an
inner ``"class Admin"``, like so::
class Person(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class Admin:
# Admin options go here
@ -1430,7 +1440,7 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
birthday = models.DateField()
class Admin:
@ -1447,9 +1457,9 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
color_code = models.CharField(maxlength=6)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
class Admin:
list_display = ('first_name', 'last_name', 'colored_name')
@ -1465,7 +1475,7 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
first_name = models.CharField(maxlength=50)
first_name = models.CharField(max_length=50)
birthday = models.DateField()
class Admin:
@ -1493,8 +1503,8 @@ A few special cases to note about ``list_display``:
For example::
class Person(models.Model):
first_name = models.CharField(maxlength=50)
color_code = models.CharField(maxlength=6)
first_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
class Admin:
list_display = ('first_name', 'colored_first_name')
@ -1744,13 +1754,13 @@ returns a list of all ``OpinionPoll`` objects, each with an extra
return result_list
class OpinionPoll(models.Model):
question = models.CharField(maxlength=200)
question = models.CharField(max_length=200)
poll_date = models.DateField()
objects = PollManager()
class Response(models.Model):
poll = models.ForeignKey(Poll)
person_name = models.CharField(maxlength=50)
person_name = models.CharField(max_length=50)
response = models.TextField()
With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
@ -1766,8 +1776,8 @@ A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
example, using this model::
class Book(models.Model):
title = models.CharField(maxlength=100)
author = models.CharField(maxlength=50)
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
...the statement ``Book.objects.all()`` will return all books in the database.
@ -1785,8 +1795,8 @@ all objects, and one that returns only the books by Roald Dahl::
# Then hook it into the Book model explicitly.
class Book(models.Model):
title = models.CharField(maxlength=100)
author = models.CharField(maxlength=50)
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
objects = models.Manager() # The default manager.
dahl_objects = DahlBookManager() # The Dahl-specific manager.
@ -1819,9 +1829,9 @@ For example::
return super(FemaleManager, self).get_query_set().filter(sex='F')
class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
sex = models.CharField(maxlength=1, choices=(('M', 'Male'), ('F', 'Female')))
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
people = models.Manager()
men = MaleManager()
women = FemaleManager()
@ -1851,11 +1861,11 @@ model.
For example, this model has a few custom methods::
class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()
address = models.CharField(maxlength=100)
city = models.CharField(maxlength=50)
address = models.CharField(max_length=100)
city = models.CharField(max_length=50)
state = models.USStateField() # Yes, this is America-centric...
def baby_boomer_status(self):
@ -1897,8 +1907,8 @@ Although this isn't required, it's strongly encouraged (see the description of
For example::
class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __str__(self):
# Note use of django.utils.encoding.smart_str() here because
@ -1915,8 +1925,8 @@ method for your model. The example in the previous section could be written
more simply as::
class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
@ -1942,10 +1952,12 @@ Django uses this in its admin interface. If an object defines
link that will jump you directly to the object's public view, according to
``get_absolute_url()``.
Also, a couple of other bits of Django, such as the syndication-feed framework,
Also, a couple of other bits of Django, such as the `syndication feed framework`_,
use ``get_absolute_url()`` as a convenience to reward people who've defined the
method.
.. syndication feed framework: ../syndication_feeds/
It's good practice to use ``get_absolute_url()`` in templates, instead of
hard-coding your objects' URLs. For example, this template code is bad::
@ -2056,7 +2068,7 @@ A classic use-case for overriding the built-in methods is if you want something
to happen whenever you save an object. For example::
class Blog(models.Model):
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self):
@ -2067,7 +2079,7 @@ to happen whenever you save an object. For example::
You can also prevent saving::
class Blog(models.Model):
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self):

View File

@ -641,7 +641,7 @@ the "Outputting forms as HTML" section above.
The simplest way to display a form's HTML is to use the variable on its own,
like this::
<form method="post">
<form method="post" action="">
<table>{{ form }}</table>
<input type="submit" />
</form>
@ -653,7 +653,7 @@ class' ``__str__()`` method calls its ``as_table()`` method.
The following is equivalent but a bit more explicit::
<form method="post">
<form method="post" action="">
<table>{{ form.as_table }}</table>
<input type="submit" />
</form>
@ -675,7 +675,7 @@ individual fields for complete template control over the form's design.
The easiest way is to iterate over the form's fields, with
``{% for field in form %}``. For example::
<form method="post">
<form method="post" action="">
<dl>
{% for field in form %}
<dt>{{ field.label }}</dt>
@ -696,7 +696,7 @@ Alternatively, you can arrange the form's fields explicitly, by name. Do that
by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
For example::
<form method="post">
<form method="post" action="">
<ul class="myformclass">
<li>{{ form.sender.label }} {{ form.sender }}</li>
<li class="helptext">{{ form.sender.help_text }}</li>
@ -710,6 +710,49 @@ For example::
</ul>
</form>
Binding uploaded files to a form
--------------------------------
**New in Django development version**
Dealing with forms that have ``FileField`` and ``ImageField`` fields
is a little more complicated than a normal form.
Firstly, in order to upload files, you'll need to make sure that your
``<form>`` element correctly defines the ``enctype`` as
``"multipart/form-data"``::
<form enctype="multipart/form-data" method="post" action="/foo/">
Secondly, when you use the form, you need to bind the file data. File
data is handled separately to normal form data, so when your form
contains a ``FileField`` and ``ImageField``, you will need to specify
a second argument when you bind your form. So if we extend our
ContactForm to include an ``ImageField`` called ``mugshot``, we
need to bind the file data containing the mugshot image::
# Bound form with an image field
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True}
>>> file_data = {'mugshot': {'filename':'face.jpg'
... 'content': <file data>}}
>>> f = ContactFormWithMugshot(data, file_data)
In practice, you will usually specify ``request.FILES`` as the source
of file data (just like you use ``request.POST`` as the source of
form data)::
# Bound form with an image field, data from the request
>>> f = ContactFormWithMugshot(request.POST, request.FILES)
Constructing an unbound form is the same as always -- just omit both
form data *and* file data:
# Unbound form with a image field
>>> f = ContactFormWithMugshot()
Subclassing forms
-----------------
@ -1099,6 +1142,54 @@ Has two optional arguments for validation, ``max_length`` and ``min_length``.
If provided, these arguments ensure that the string is at most or at least the
given length.
``FileField``
~~~~~~~~~~~~~
**New in Django development version**
* Default widget: ``FileInput``
* Empty value: ``None``
* Normalizes to: An ``UploadedFile`` object that wraps the file content
and file name into a single object.
* Validates that non-empty file data has been bound to the form.
An ``UploadedFile`` object has two attributes:
====================== =====================================================
Argument Description
====================== =====================================================
``filename`` The name of the file, provided by the uploading
client.
``content`` The array of bytes comprising the file content.
====================== =====================================================
The string representation of an ``UploadedFile`` is the same as the filename
attribute.
When you use a ``FileField`` on a form, you must also remember to
`bind the file data to the form`_.
.. _`bind the file data to the form`: `Binding uploaded files to a form`_
``ImageField``
~~~~~~~~~~~~~~
**New in Django development version**
* Default widget: ``FileInput``
* Empty value: ``None``
* Normalizes to: An ``UploadedFile`` object that wraps the file content
and file name into a single object.
* Validates that file data has been bound to the form, and that the
file is of an image format understood by PIL.
Using an ImageField requires that the `Python Imaging Library`_ is installed.
When you use a ``FileField`` on a form, you must also remember to
`bind the file data to the form`_.
.. _Python Imaging Library: http://www.pythonware.com/products/pil/
``IntegerField``
~~~~~~~~~~~~~~~~
@ -1222,7 +1313,7 @@ Custom form and field validation
Form validation happens when the data is cleaned. If you want to customise
this process, there are various places you can change, each one serving a
different purpose. Thee types of cleaning methods are run during form
different purpose. Three types of cleaning methods are run during form
processing. These are normally executed when you call the ``is_valid()``
method on a form. There are other things that can trigger cleaning and
validation (accessing the ``errors`` attribute or calling ``full_clean()``
@ -1372,17 +1463,17 @@ the full list of conversions:
``AutoField`` Not represented in the form
``BooleanField`` ``BooleanField``
``CharField`` ``CharField`` with ``max_length`` set to
the model field's ``maxlength``
the model field's ``max_length``
``CommaSeparatedIntegerField`` ``CharField``
``DateField`` ``DateField``
``DateTimeField`` ``DateTimeField``
``DecimalField`` ``DecimalField``
``EmailField`` ``EmailField``
``FileField`` ``CharField``
``FileField`` ``FileField``
``FilePathField`` ``CharField``
``FloatField`` ``FloatField``
``ForeignKey`` ``ModelChoiceField`` (see below)
``ImageField`` ``CharField``
``ImageField`` ``ImageField``
``IntegerField`` ``IntegerField``
``IPAddressField`` ``CharField``
``ManyToManyField`` ``ModelMultipleChoiceField`` (see
@ -1452,15 +1543,15 @@ Consider this set of models::
)
class Author(models.Model):
name = models.CharField(maxlength=100)
title = models.CharField(maxlength=3, choices=TITLE_CHOICES)
name = models.CharField(max_length=100)
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
birth_date = models.DateField(blank=True, null=True)
def __unicode__(self):
return self.name
class Book(models.Model):
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
With these models, a call to ``form_for_model(Author)`` would return a ``Form``
@ -1502,6 +1593,44 @@ the database. In this case, it's up to you to call ``save()`` on the resulting
model instance. This is useful if you want to do custom processing on the
object before saving it. ``commit`` is ``True`` by default.
Another side effect of using ``commit=False`` is seen when your model has
a many-to-many relation with another model. If your model has a many-to-many
relation and you specify ``commit=False`` when you save a form, Django cannot
immediately save the form data for the many-to-many relation. This is because
it isn't possible to save many-to-many data for an instance until the instance
exists in the database.
To work around this problem, every time you save a form using ``commit=False``,
Django adds a ``save_m2m()`` method to the form created by ``form_for_model``.
After you've manually saved the instance produced by the form, you can invoke
``save_m2m()`` to save the many-to-many form data. For example::
# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)
# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)
# Modify the author in some way.
>>> new_author.some_field = 'some_value'
# Save the new instance.
>>> new_author.save()
# Now, save the many-to-many data for the form.
>>> f.save_m2m()
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
When you use a simple ``save()`` on a form, all data -- including
many-to-many data -- is saved without the need for any additional method calls.
For example::
# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)
# Create and save the new author instance. There's no need to do anything else.
>>> new_author = f.save()
Using an alternate base class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -25,14 +25,14 @@ far, it's been solving two years' worth of database-schema problems. Here's a
quick example::
class Reporter(models.Model):
full_name = models.CharField(maxlength=70)
full_name = models.CharField(max_length=70)
def __unicode__(self):
return self.full_name
class Article(models.Model):
pub_date = models.DateTimeField()
headline = models.CharField(maxlength=200)
headline = models.CharField(max_length=200)
article = models.TextField()
reporter = models.ForeignKey(Reporter)
@ -134,7 +134,7 @@ your model classes::
class Article(models.Model):
pub_date = models.DateTimeField()
headline = models.CharField(maxlength=200)
headline = models.CharField(max_length=200)
article = models.TextField()
reporter = models.ForeignKey(Reporter)
class Admin: pass
@ -288,14 +288,16 @@ This has been only a quick overview of Django's functionality. Some more useful
features:
* A caching framework that integrates with memcached or other backends.
* A syndication framework that makes creating RSS and Atom feeds as easy as
* A `syndication framework`_ that makes creating RSS and Atom feeds as easy as
writing a small Python class.
* More sexy automatically-generated admin features -- this overview barely
scratched the surface.
.. _syndication framework: ../syndication_feeds/
The next obvious steps are for you to `download Django`_, read `the tutorial`_
and join `the community`_. Thanks for your interest!
.. _download Django: http://www.djangoproject.com/download/
.. _the tutorial: http://www.djangoproject.com/documentation/tutorial01/
.. _the tutorial: ../tutorial01/
.. _the community: http://www.djangoproject.com/community/

View File

@ -114,7 +114,7 @@ there's a #django channel on irc.freenode.net that is regularly populated by
Django users and developers from around the world. Friendly people are usually
available at any hour of the day -- to help, or just to chat.
.. _online: http://www.djangoproject.com/documentation/
.. _online: http://www.djangoproject.com/documentation/0.95/
.. _Django website: http://www.djangoproject.com/
.. _FAQ: http://www.djangoproject.com/documentation/faq/
.. _django-users: http://groups.google.com/group/django-users

View File

@ -297,7 +297,7 @@ In contrast to ``HttpRequest`` objects, which are created automatically by
Django, ``HttpResponse`` objects are your responsibility. Each view you write
is responsible for instantiating, populating and returning an ``HttpResponse``.
The ``HttpResponse`` class lives at ``django.http.HttpResponse``.
The ``HttpResponse`` class lives in the ``django.http`` module.
Usage
-----

View File

@ -21,7 +21,7 @@ you express this information in Python code.
It works much like Django's `syndication framework`_. To create a sitemap, just
write a ``Sitemap`` class and point to it in your URLconf_.
.. _syndication framework: ../syndication/
.. _syndication framework: ../syndication_feeds/
.. _URLconf: ../url_dispatch/
Installation

View File

@ -46,7 +46,7 @@ that's represented by a ``ManyToManyField`` in the ``Article`` model::
from django.contrib.sites.models import Site
class Article(models.Model):
headline = models.CharField(maxlength=200)
headline = models.CharField(max_length=200)
# ...
sites = models.ManyToManyField(Site)
@ -87,7 +87,7 @@ like this::
from django.contrib.sites.models import Site
class Article(models.Model):
headline = models.CharField(maxlength=200)
headline = models.CharField(max_length=200)
# ...
site = models.ForeignKey(Site)
@ -229,7 +229,7 @@ Use ``CurrentSiteManager`` by adding it to your model explicitly. For example::
class Photo(models.Model):
photo = models.FileField(upload_to='/home/photos')
photographer_name = models.CharField(maxlength=100)
photographer_name = models.CharField(max_length=100)
pub_date = models.DateField()
site = models.ForeignKey(Site)
objects = models.Manager()
@ -257,7 +257,7 @@ this::
class Photo(models.Model):
photo = models.FileField(upload_to='/home/photos')
photographer_name = models.CharField(maxlength=100)
photographer_name = models.CharField(max_length=100)
pub_date = models.DateField()
publish_on = models.ForeignKey(Site)
objects = models.Manager()
@ -318,7 +318,7 @@ Here's how Django uses the sites framework:
.. _redirects framework: ../redirects/
.. _flatpages framework: ../flatpages/
.. _syndication framework: ../syndication/
.. _syndication framework: ../syndication_feeds/
.. _authentication framework: ../authentication/
``RequestSite`` objects

View File

@ -79,8 +79,8 @@ For example::
'The cat says "meow"'
"""
name = models.CharField(maxlength=20)
sound = models.CharField(maxlength=20)
name = models.CharField(max_length=20)
sound = models.CharField(max_length=20)
def speak(self):
return 'The %s says "%s"' % (self.name, self.sound)

View File

@ -251,12 +251,12 @@ These concepts are represented by simple Python classes. Edit the
from django.db import models
class Poll(models.Model):
question = models.CharField(maxlength=200)
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(maxlength=200)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
The code is straightforward. Each model is represented by a class that
@ -279,7 +279,7 @@ name for ``Poll.pub_date``. For all other fields in this model, the field's
machine-readable name will suffice as its human-readable name.
Some ``Field`` classes have required elements. ``CharField``, for example,
requires that you give it a ``maxlength``. That's used not only in the database
requires that you give it a ``max_length``. That's used not only in the database
schema, but in validation, as we'll soon see.
Finally, note a relationship is defined, using ``models.ForeignKey``. That tells

View File

@ -240,7 +240,7 @@ default, provide enough fields for 3 Choices."
Then change the other fields in ``Choice`` to give them ``core=True``::
choice = models.CharField(maxlength=200, core=True)
choice = models.CharField(max_length=200, core=True)
votes = models.IntegerField(core=True)
This tells Django: "When you edit a Choice on the Poll admin page, the 'choice'

View File

@ -356,7 +356,8 @@ Use the template system
=======================
Back to the ``detail()`` view for our poll application. Given the context
variable ``poll``, here's what the template might look like::
variable ``poll``, here's what the "polls/detail.html" template might look
like::
<h1>{{ poll.question }}</h1>
<ul>

View File

@ -8,8 +8,8 @@ application and will focus on simple form processing and cutting down our code.
Write a simple form
===================
Let's update our poll detail template from the last tutorial, so that the
template contains an HTML ``<form>`` element::
Let's update our poll detail template ("polls/detail.html") from the last
tutorial, so that the template contains an HTML ``<form>`` element::
<h1>{{ poll.question }}</h1>
@ -213,7 +213,7 @@ objects" and "display a detail page for a particular type of object."
a way to refer to its URL later on (see `naming URL patterns`_ for more on
named patterns).
.. _naming URL patterns: http://www.djangoproject.com/documentation/url_dispatch/#naming-url-patterns
.. _naming URL patterns: ../url_dispatch/#naming-url-patterns
By default, the ``object_detail`` generic view uses a template called
``<app name>/<model name>_detail.html``. In our case, it'll use the template

View File

@ -404,7 +404,7 @@ This technique is used in `generic views`_ and in the `syndication framework`_
to pass metadata and options to views.
.. _generic views: ../generic_views/
.. _syndication framework: ../syndication/
.. _syndication framework: ../syndication_feeds/
.. admonition:: Dealing with conflicts

View File

@ -8,7 +8,7 @@ This is a basic model with only two non-primary-key fields.
from django.db import models
class Article(models.Model):
headline = models.CharField(maxlength=100, default='Default headline')
headline = models.CharField(max_length=100, default='Default headline')
pub_date = models.DateTimeField()
class Meta:

View File

@ -17,8 +17,8 @@ GENDER_CHOICES = (
)
class Person(models.Model):
name = models.CharField(maxlength=20)
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
name = models.CharField(max_length=20)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
def __unicode__(self):
return self.name

View File

@ -18,8 +18,8 @@ ManyToMany field. This has no effect on the API for querying the database.
from django.db import models
class Author(models.Model):
first_name = models.CharField(maxlength=30, db_column='firstname')
last_name = models.CharField(maxlength=30, db_column='last')
first_name = models.CharField(max_length=30, db_column='firstname')
last_name = models.CharField(max_length=30, db_column='last')
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
@ -29,7 +29,7 @@ class Author(models.Model):
ordering = ('last_name','first_name')
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
authors = models.ManyToManyField(Author, db_table='my_m2m_table')
def __unicode__(self):

View File

@ -18,8 +18,8 @@ class PersonManager(models.Manager):
return self.filter(fun=True)
class Person(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
fun = models.BooleanField()
objects = PersonManager()
@ -33,8 +33,8 @@ class PublishedBookManager(models.Manager):
return super(PublishedBookManager, self).get_query_set().filter(is_published=True)
class Book(models.Model):
title = models.CharField(maxlength=50)
author = models.CharField(maxlength=30)
title = models.CharField(max_length=50)
author = models.CharField(max_length=30)
is_published = models.BooleanField()
published_objects = PublishedBookManager()
authors = models.ManyToManyField(Person, related_name='books')
@ -49,7 +49,7 @@ class FastCarManager(models.Manager):
return super(FastCarManager, self).get_query_set().filter(top_speed__gt=150)
class Car(models.Model):
name = models.CharField(maxlength=10)
name = models.CharField(max_length=10)
mileage = models.IntegerField()
top_speed = models.IntegerField(help_text="In miles per hour.")
cars = models.Manager()

View File

@ -8,7 +8,7 @@ from django.db import models
import datetime
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateField()
def __unicode__(self):

View File

@ -8,10 +8,10 @@ this behavior by explicitly adding ``primary_key=True`` to a field.
from django.db import models
class Employee(models.Model):
employee_code = models.CharField(maxlength=10, primary_key=True,
employee_code = models.CharField(max_length=10, primary_key=True,
db_column = 'code')
first_name = models.CharField(maxlength=20)
last_name = models.CharField(maxlength=20)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
class Meta:
ordering = ('last_name', 'first_name')
@ -19,7 +19,7 @@ class Employee(models.Model):
return u"%s %s" % (self.first_name, self.last_name)
class Business(models.Model):
name = models.CharField(maxlength=20, primary_key=True)
name = models.CharField(max_length=20, primary_key=True)
employees = models.ManyToManyField(Employee)
class Meta:
verbose_name_plural = 'businesses'

View File

@ -13,7 +13,7 @@ from django.db import models
from datetime import datetime
class Article(models.Model):
headline = models.CharField(maxlength=100, default='Default headline')
headline = models.CharField(max_length=100, default='Default headline')
pub_date = models.DateTimeField(default=datetime.now)
def __unicode__(self):

View File

@ -11,7 +11,7 @@ FIXTURE_DIRS setting.
from django.db import models
class Article(models.Model):
headline = models.CharField(maxlength=100, default='Default headline')
headline = models.CharField(max_length=100, default='Default headline')
pub_date = models.DateTimeField()
def __unicode__(self):

View File

@ -28,8 +28,8 @@ class TaggedItem(models.Model):
return self.tag
class Animal(models.Model):
common_name = models.CharField(maxlength=150)
latin_name = models.CharField(maxlength=150)
common_name = models.CharField(max_length=150)
latin_name = models.CharField(max_length=150)
tags = generic.GenericRelation(TaggedItem)
@ -37,7 +37,7 @@ class Animal(models.Model):
return self.common_name
class Vegetable(models.Model):
name = models.CharField(maxlength=150)
name = models.CharField(max_length=150)
is_yucky = models.BooleanField(default=True)
tags = generic.GenericRelation(TaggedItem)
@ -46,7 +46,7 @@ class Vegetable(models.Model):
return self.name
class Mineral(models.Model):
name = models.CharField(maxlength=150)
name = models.CharField(max_length=150)
hardness = models.PositiveSmallIntegerField()
# note the lack of an explicit GenericRelation here...

View File

@ -11,7 +11,7 @@ into the future."
from django.db import models
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateField()
expire_date = models.DateField()
class Meta:
@ -21,7 +21,7 @@ class Article(models.Model):
return self.headline
class Person(models.Model):
name = models.CharField(maxlength=30)
name = models.CharField(max_length=30)
birthday = models.DateField()
# Note that this model doesn't have "get_latest_by" set.

View File

@ -15,7 +15,7 @@ from django.http import Http404
from django.shortcuts import get_object_or_404, get_list_or_404
class Author(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
def __unicode__(self):
return self.name
@ -26,7 +26,7 @@ class ArticleManager(models.Manager):
class Article(models.Model):
authors = models.ManyToManyField(Author)
title = models.CharField(maxlength=50)
title = models.CharField(max_length=50)
objects = models.Manager()
by_a_sir = ArticleManager()

View File

@ -8,8 +8,8 @@ parameters. If an object isn't found, it creates one with the given parameters.
from django.db import models
class Person(models.Model):
first_name = models.CharField(maxlength=100)
last_name = models.CharField(maxlength=100)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
birthday = models.DateField()
def __unicode__(self):

View File

@ -10,26 +10,26 @@ class FieldErrors(models.Model):
charfield = models.CharField()
decimalfield = models.DecimalField()
filefield = models.FileField()
prepopulate = models.CharField(maxlength=10, prepopulate_from='bad')
choices = models.CharField(maxlength=10, choices='bad')
choices2 = models.CharField(maxlength=10, choices=[(1,2,3),(1,2,3)])
index = models.CharField(maxlength=10, db_index='bad')
prepopulate = models.CharField(max_length=10, prepopulate_from='bad')
choices = models.CharField(max_length=10, choices='bad')
choices2 = models.CharField(max_length=10, choices=[(1,2,3),(1,2,3)])
index = models.CharField(max_length=10, db_index='bad')
class Target(models.Model):
tgt_safe = models.CharField(maxlength=10)
clash1 = models.CharField(maxlength=10)
clash2 = models.CharField(maxlength=10)
tgt_safe = models.CharField(max_length=10)
clash1 = models.CharField(max_length=10)
clash2 = models.CharField(max_length=10)
clash1_set = models.CharField(maxlength=10)
clash1_set = models.CharField(max_length=10)
class Clash1(models.Model):
src_safe = models.CharField(maxlength=10, core=True)
src_safe = models.CharField(max_length=10, core=True)
foreign = models.ForeignKey(Target)
m2m = models.ManyToManyField(Target)
class Clash2(models.Model):
src_safe = models.CharField(maxlength=10, core=True)
src_safe = models.CharField(max_length=10, core=True)
foreign_1 = models.ForeignKey(Target, related_name='id')
foreign_2 = models.ForeignKey(Target, related_name='src_safe')
@ -38,7 +38,7 @@ class Clash2(models.Model):
m2m_2 = models.ManyToManyField(Target, related_name='src_safe')
class Target2(models.Model):
clash3 = models.CharField(maxlength=10)
clash3 = models.CharField(max_length=10)
foreign_tgt = models.ForeignKey(Target)
clashforeign_set = models.ForeignKey(Target)
@ -46,7 +46,7 @@ class Target2(models.Model):
clashm2m_set = models.ManyToManyField(Target)
class Clash3(models.Model):
src_safe = models.CharField(maxlength=10, core=True)
src_safe = models.CharField(max_length=10, core=True)
foreign_1 = models.ForeignKey(Target2, related_name='foreign_tgt')
foreign_2 = models.ForeignKey(Target2, related_name='m2m_tgt')
@ -61,16 +61,16 @@ class ClashM2M(models.Model):
m2m = models.ManyToManyField(Target2)
class SelfClashForeign(models.Model):
src_safe = models.CharField(maxlength=10, core=True)
selfclashforeign = models.CharField(maxlength=10)
src_safe = models.CharField(max_length=10, core=True)
selfclashforeign = models.CharField(max_length=10)
selfclashforeign_set = models.ForeignKey("SelfClashForeign")
foreign_1 = models.ForeignKey("SelfClashForeign", related_name='id')
foreign_2 = models.ForeignKey("SelfClashForeign", related_name='src_safe')
class ValidM2M(models.Model):
src_safe = models.CharField(maxlength=10)
validm2m = models.CharField(maxlength=10)
src_safe = models.CharField(max_length=10)
validm2m = models.CharField(max_length=10)
# M2M fields are symmetrical by default. Symmetrical M2M fields
# on self don't require a related accessor, so many potential
@ -84,8 +84,8 @@ class ValidM2M(models.Model):
m2m_4 = models.ManyToManyField('self')
class SelfClashM2M(models.Model):
src_safe = models.CharField(maxlength=10)
selfclashm2m = models.CharField(maxlength=10)
src_safe = models.CharField(max_length=10)
selfclashm2m = models.CharField(max_length=10)
# Non-symmetrical M2M fields _do_ have related accessors, so
# there is potential for clashes.
@ -100,14 +100,14 @@ class SelfClashM2M(models.Model):
class Model(models.Model):
"But it's valid to call a model Model."
year = models.PositiveIntegerField() #1960
make = models.CharField(maxlength=10) #Aston Martin
name = models.CharField(maxlength=10) #DB 4 GT
make = models.CharField(max_length=10) #Aston Martin
name = models.CharField(max_length=10) #DB 4 GT
class Car(models.Model):
colour = models.CharField(maxlength=5)
colour = models.CharField(max_length=5)
model = models.ForeignKey(Model)
model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "maxlength" attribute.
model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute.
invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute.

View File

@ -8,7 +8,7 @@ from django.db import models
from django.conf import settings
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateTimeField()
class Meta:
ordering = ('-pub_date', 'headline')

View File

@ -7,7 +7,7 @@ Make sure to set ``related_name`` if you use relationships to the same table.
from django.db import models
class User(models.Model):
username = models.CharField(maxlength=20)
username = models.CharField(max_length=20)
class Issue(models.Model):
num = models.IntegerField()

View File

@ -13,14 +13,14 @@ writer").
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateField()
def __unicode__(self):
@ -29,7 +29,7 @@ class Article(models.Model):
class Writer(models.Model):
reporter = models.ForeignKey(Reporter)
article = models.ForeignKey(Article)
position = models.CharField(maxlength=100)
position = models.CharField(max_length=100)
def __unicode__(self):
return u'%s (%s)' % (self.reporter, self.position)

View File

@ -10,7 +10,7 @@ Set ``related_name`` to designate what the reverse relationship is called.
from django.db import models
class Category(models.Model):
name = models.CharField(maxlength=20)
name = models.CharField(max_length=20)
class Meta:
ordering = ('name',)
@ -18,7 +18,7 @@ class Category(models.Model):
return self.name
class Article(models.Model):
headline = models.CharField(maxlength=50)
headline = models.CharField(max_length=50)
pub_date = models.DateTimeField()
primary_categories = models.ManyToManyField(Category, related_name='primary_article_set')
secondary_categories = models.ManyToManyField(Category, related_name='secondary_article_set')

View File

@ -15,7 +15,7 @@ there will be a clash, and tests that symmetry is preserved where appropriate.
from django.db import models
class Person(models.Model):
name = models.CharField(maxlength=20)
name = models.CharField(max_length=20)
friends = models.ManyToManyField('self')
idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers')

View File

@ -13,7 +13,7 @@ Set ``related_name`` to designate what the reverse relationship is called.
from django.db import models
class Category(models.Model):
name = models.CharField(maxlength=20)
name = models.CharField(max_length=20)
parent = models.ForeignKey('self', null=True, related_name='child_set')
def __unicode__(self):

View File

@ -10,7 +10,7 @@ Set ``related_name`` to designate what the reverse relationship is called.
from django.db import models
class Person(models.Model):
full_name = models.CharField(maxlength=20)
full_name = models.CharField(max_length=20)
mother = models.ForeignKey('self', null=True, related_name='mothers_child_set')
father = models.ForeignKey('self', null=True, related_name='fathers_child_set')

View File

@ -7,14 +7,14 @@ Each model gets an AddManipulator and ChangeManipulator by default.
from django.db import models
class Musician(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
class Album(models.Model):
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
musician = models.ForeignKey(Musician)
release_date = models.DateField(blank=True, null=True)

View File

@ -10,7 +10,7 @@ and a publication has multiple articles.
from django.db import models
class Publication(models.Model):
title = models.CharField(maxlength=30)
title = models.CharField(max_length=30)
def __unicode__(self):
return self.title
@ -19,7 +19,7 @@ class Publication(models.Model):
ordering = ('title',)
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
def __unicode__(self):

View File

@ -7,15 +7,15 @@ To define a many-to-one relationship, use ``ForeignKey()`` .
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter)

View File

@ -8,13 +8,13 @@ To define a many-to-one relationship that can have a null foreign key, use
from django.db import models
class Reporter(models.Model):
name = models.CharField(maxlength=30)
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
reporter = models.ForeignKey(Reporter, null=True)
class Meta:

View File

@ -31,20 +31,20 @@ ARTICLE_STATUS = (
)
class Category(models.Model):
name = models.CharField(maxlength=20)
url = models.CharField('The URL', maxlength=40)
name = models.CharField(max_length=20)
url = models.CharField('The URL', max_length=40)
def __unicode__(self):
return self.name
class Writer(models.Model):
name = models.CharField(maxlength=50, help_text='Use both first and last names.')
name = models.CharField(max_length=50, help_text='Use both first and last names.')
def __unicode__(self):
return self.name
class Article(models.Model):
headline = models.CharField(maxlength=50)
headline = models.CharField(max_length=50)
pub_date = models.DateField()
created = models.DateField(editable=False)
writer = models.ForeignKey(Writer)
@ -63,7 +63,7 @@ class Article(models.Model):
class PhoneNumber(models.Model):
phone = models.PhoneNumberField()
description = models.CharField(maxlength=20)
description = models.CharField(max_length=20)
def __unicode__(self):
return self.phone
@ -332,6 +332,28 @@ Create a new article, with no categories, via the form.
>>> new_art.categories.all()
[]
Create a new article, with categories, via the form, but use commit=False.
The m2m data won't be saved until save_m2m() is invoked on the form.
>>> ArticleForm = form_for_model(Article)
>>> f = ArticleForm({'headline': u'The walrus was Paul', 'pub_date': u'1967-11-01',
... 'writer': u'1', 'article': u'Test.', 'categories': [u'1', u'2']})
>>> new_art = f.save(commit=False)
# Manually save the instance
>>> new_art.save()
>>> new_art.id
4
# The instance doesn't have m2m data yet
>>> new_art = Article.objects.get(id=4)
>>> new_art.categories.all()
[]
# Save the m2m data on the form
>>> f.save_m2m()
>>> new_art.categories.all()
[<Category: Entertainment>, <Category: It's a test>]
Here, we define a custom Form. Because it happens to have the same fields as
the Category model, we can use save_instance() to apply its changes to an
existing Category instance.

View File

@ -7,8 +7,8 @@ Model inheritance isn't yet supported.
from django.db import models
class Place(models.Model):
name = models.CharField(maxlength=50)
address = models.CharField(maxlength=80)
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
def __unicode__(self):
return u"%s the place" % self.name

View File

@ -7,11 +7,11 @@ To define a many-to-one relationship, use ``ForeignKey()`` .
from django.db.models import *
class Parent(Model):
name = CharField(maxlength=100, core=True)
name = CharField(max_length=100, core=True)
bestchild = ForeignKey("Child", null=True, related_name="favoured_by")
class Child(Model):
name = CharField(maxlength=100)
name = CharField(max_length=100)
parent = ForeignKey(Parent)
__test__ = {'API_TESTS':"""

View File

@ -9,8 +9,8 @@ In this example, a ``Place`` optionally can be a ``Restaurant``.
from django.db import models
class Place(models.Model):
name = models.CharField(maxlength=50)
address = models.CharField(maxlength=80)
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
def __unicode__(self):
return u"%s the place" % self.name
@ -25,18 +25,18 @@ class Restaurant(models.Model):
class Waiter(models.Model):
restaurant = models.ForeignKey(Restaurant)
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
def __unicode__(self):
return u"%s the waiter at %s" % (self.name, self.restaurant)
class ManualPrimaryKey(models.Model):
primary_key = models.CharField(maxlength=10, primary_key=True)
name = models.CharField(maxlength = 50)
primary_key = models.CharField(max_length=10, primary_key=True)
name = models.CharField(max_length = 50)
class RelatedModel(models.Model):
link = models.OneToOneField(ManualPrimaryKey)
name = models.CharField(maxlength = 50)
name = models.CharField(max_length = 50)
__test__ = {'API_TESTS':"""
# Create a couple of Places.

View File

@ -14,7 +14,7 @@ a get_sql method).
from django.db import models
class Article(models.Model):
headline = models.CharField(maxlength=50)
headline = models.CharField(max_length=50)
pub_date = models.DateTimeField()
class Meta:

View File

@ -16,7 +16,7 @@ undefined -- not random, just undefined.
from django.db import models
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateTimeField()
class Meta:
ordering = ('-pub_date', 'headline')

View File

@ -9,7 +9,7 @@ objects into easily readable pages.
from django.db import models
class Article(models.Model):
headline = models.CharField(maxlength=100, default='Default headline')
headline = models.CharField(max_length=100, default='Default headline')
pub_date = models.DateTimeField()
def __unicode__(self):

View File

@ -7,8 +7,8 @@ Use properties on models just like on any other Python object.
from django.db import models
class Person(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def _get_full_name(self):
return "%s %s" % (self.first_name, self.last_name)

View File

@ -10,14 +10,14 @@ reserved-name usage.
from django.db import models
class Thing(models.Model):
when = models.CharField(maxlength=1, primary_key=True)
join = models.CharField(maxlength=1)
like = models.CharField(maxlength=1)
drop = models.CharField(maxlength=1)
alter = models.CharField(maxlength=1)
having = models.CharField(maxlength=1)
where = models.DateField(maxlength=1)
has_hyphen = models.CharField(maxlength=1, db_column='has-hyphen')
when = models.CharField(max_length=1, primary_key=True)
join = models.CharField(max_length=1)
like = models.CharField(max_length=1)
drop = models.CharField(max_length=1)
alter = models.CharField(max_length=1)
having = models.CharField(max_length=1)
where = models.DateField(max_length=1)
has_hyphen = models.CharField(max_length=1, db_column='has-hyphen')
class Meta:
db_table = 'select'

View File

@ -7,20 +7,20 @@ This demonstrates the reverse lookup features of the database API.
from django.db import models
class User(models.Model):
name = models.CharField(maxlength=200)
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name
class Poll(models.Model):
question = models.CharField(maxlength=200)
question = models.CharField(max_length=200)
creator = models.ForeignKey(User)
def __unicode__(self):
return self.question
class Choice(models.Model):
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
poll = models.ForeignKey(Poll, related_name="poll_choice")
related_poll = models.ForeignKey(Poll, related_name="related_choice")

View File

@ -8,8 +8,8 @@ the methods.
from django.db import models
class Person(models.Model):
first_name = models.CharField(maxlength=20)
last_name = models.CharField(maxlength=20)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)

View File

@ -12,48 +12,48 @@ from django.db import models
# Who remembers high school biology?
class Domain(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class Kingdom(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
domain = models.ForeignKey(Domain)
def __unicode__(self):
return self.name
class Phylum(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
kingdom = models.ForeignKey(Kingdom)
def __unicode__(self):
return self.name
class Klass(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
phylum = models.ForeignKey(Phylum)
def __unicode__(self):
return self.name
class Order(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
klass = models.ForeignKey(Klass)
def __unicode__(self):
return self.name
class Family(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
order = models.ForeignKey(Order)
def __unicode__(self):
return self.name
class Genus(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
family = models.ForeignKey(Family)
def __unicode__(self):
return self.name
class Species(models.Model):
name = models.CharField(maxlength=50)
name = models.CharField(max_length=50)
genus = models.ForeignKey(Genus)
def __unicode__(self):
return self.name

View File

@ -8,7 +8,7 @@ to and from "flat" data (i.e. strings).
from django.db import models
class Category(models.Model):
name = models.CharField(maxlength=20)
name = models.CharField(max_length=20)
class Meta:
ordering = ('name',)
@ -17,7 +17,7 @@ class Category(models.Model):
return self.name
class Author(models.Model):
name = models.CharField(maxlength=20)
name = models.CharField(max_length=20)
class Meta:
ordering = ('name',)
@ -27,7 +27,7 @@ class Author(models.Model):
class Article(models.Model):
author = models.ForeignKey(Author)
headline = models.CharField(maxlength=50)
headline = models.CharField(max_length=50)
pub_date = models.DateTimeField()
categories = models.ManyToManyField(Category)

View File

@ -17,7 +17,7 @@ if you prefer. You must be careful to encode the results correctly, though.
from django.db import models
class Article(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateTimeField()
def __str__(self):
@ -26,7 +26,7 @@ class Article(models.Model):
return self.headline
class InternationalArticle(models.Model):
headline = models.CharField(maxlength=100)
headline = models.CharField(max_length=100)
pub_date = models.DateTimeField()
def __unicode__(self):

View File

@ -10,8 +10,8 @@ manually.
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
def __unicode__(self):

View File

@ -12,7 +12,7 @@ from django.db import models
class Person(models.Model):
is_child = models.BooleanField()
name = models.CharField(maxlength=20)
name = models.CharField(max_length=20)
birthdate = models.DateField()
favorite_moment = models.DateTimeField()
email = models.EmailField()

View File

@ -2,7 +2,7 @@ import tempfile
from django.db import models
class Photo(models.Model):
title = models.CharField(maxlength=30)
title = models.CharField(max_length=30)
image = models.FileField(upload_to=tempfile.gettempdir())
# Support code for the tests; this keeps track of how many times save() gets

View File

@ -7,7 +7,7 @@ from django.db import models
from django.conf import settings
class Donut(models.Model):
name = models.CharField(maxlength=100)
name = models.CharField(max_length=100)
is_frosted = models.BooleanField(default=False)
has_sprinkles = models.NullBooleanField()
baked_date = models.DateField(null=True)

View File

@ -2,21 +2,21 @@ from django.db import models
from django.contrib.auth.models import User
class Animal(models.Model):
name = models.CharField(maxlength=150)
latin_name = models.CharField(maxlength=150)
name = models.CharField(max_length=150)
latin_name = models.CharField(max_length=150)
def __unicode__(self):
return self.common_name
class Plant(models.Model):
name = models.CharField(maxlength=150)
name = models.CharField(max_length=150)
class Meta:
# For testing when upper case letter in app name; regression for #4057
db_table = "Fixtures_regress_plant"
class Stuff(models.Model):
name = models.CharField(maxlength=20, null=True)
name = models.CharField(max_length=20, null=True)
owner = models.ForeignKey(User, null=True)
def __unicode__(self):

View File

@ -173,27 +173,29 @@ u'<input type="hidden" class="special" value="foo@example.com" name="email" />'
# FileInput Widget ############################################################
FileInput widgets don't ever show the value, because the old value is of no use
if you are updating the form or if the provided file generated an error.
>>> w = FileInput()
>>> w.render('email', '')
u'<input type="file" name="email" />'
>>> w.render('email', None)
u'<input type="file" name="email" />'
>>> w.render('email', 'test@example.com')
u'<input type="file" name="email" value="test@example.com" />'
u'<input type="file" name="email" />'
>>> w.render('email', 'some "quoted" & ampersanded value')
u'<input type="file" name="email" value="some &quot;quoted&quot; &amp; ampersanded value" />'
u'<input type="file" name="email" />'
>>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
u'<input type="file" name="email" value="test@example.com" class="fun" />'
u'<input type="file" name="email" class="fun" />'
You can also pass 'attrs' to the constructor:
>>> w = FileInput(attrs={'class': 'fun'})
>>> w.render('email', '')
u'<input type="file" class="fun" name="email" />'
>>> w.render('email', 'foo@example.com')
u'<input type="file" class="fun" value="foo@example.com" name="email" />'
u'<input type="file" class="fun" name="email" />'
>>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
u'<input type="file" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'
u'<input type="file" class="fun" name="email" />'
# Textarea Widget #############################################################
@ -1532,6 +1534,42 @@ Traceback (most recent call last):
...
ValidationError: [u'Ensure this value has at most 15 characters (it has 20).']
# FileField ##################################################################
>>> f = FileField()
>>> f.clean('')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean({})
Traceback (most recent call last):
...
ValidationError: [u'No file was submitted.']
>>> f.clean('some content that is not a file')
Traceback (most recent call last):
...
ValidationError: [u'No file was submitted. Check the encoding type on the form.']
>>> f.clean({'filename': 'name', 'content':None})
Traceback (most recent call last):
...
ValidationError: [u'The submitted file is empty.']
>>> f.clean({'filename': 'name', 'content':''})
Traceback (most recent call last):
...
ValidationError: [u'The submitted file is empty.']
>>> type(f.clean({'filename': 'name', 'content':'Some File Content'}))
<class 'django.newforms.fields.UploadedFile'>
# URLField ##################################################################
>>> f = URLField()
@ -2573,7 +2611,7 @@ Instances of a dynamic Form do not persist fields from one Form instance to
the next.
>>> class MyForm(Form):
... def __init__(self, data=None, auto_id=False, field_list=[]):
... Form.__init__(self, data, auto_id)
... Form.__init__(self, data, auto_id=auto_id)
... for field in field_list:
... self.fields[field[0]] = field[1]
>>> field_list = [('field1', CharField()), ('field2', CharField())]
@ -2591,7 +2629,7 @@ the next.
... default_field_1 = CharField()
... default_field_2 = CharField()
... def __init__(self, data=None, auto_id=False, field_list=[]):
... Form.__init__(self, data, auto_id)
... Form.__init__(self, data, auto_id=auto_id)
... for field in field_list:
... self.fields[field[0]] = field[1]
>>> field_list = [('field1', CharField()), ('field2', CharField())]
@ -3246,6 +3284,35 @@ is different than its data. This is handled transparently, though.
<option value="3" selected="selected">No</option>
</select>
# Forms with FileFields ################################################
FileFields are a special case because they take their data from the request.FILES,
not request.POST.
>>> class FileForm(Form):
... file1 = FileField()
>>> f = FileForm(auto_id=False)
>>> print f
<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>
>>> f = FileForm(data={}, files={}, auto_id=False)
>>> print f
<tr><th>File1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="file" name="file1" /></td></tr>
>>> f = FileForm(data={}, files={'file1': {'filename': 'name', 'content':''}}, auto_id=False)
>>> print f
<tr><th>File1:</th><td><ul class="errorlist"><li>The submitted file is empty.</li></ul><input type="file" name="file1" /></td></tr>
>>> f = FileForm(data={}, files={'file1': 'something that is not a file'}, auto_id=False)
>>> print f
<tr><th>File1:</th><td><ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul><input type="file" name="file1" /></td></tr>
>>> f = FileForm(data={}, files={'file1': {'filename': 'name', 'content':'some content'}}, auto_id=False)
>>> print f
<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>
>>> f.is_valid()
True
# Basic form processing in a view #############################################
>>> from django.template import Template, Context

Some files were not shown because too many files have changed in this diff Show More