mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +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:
parent
0af6ed0c48
commit
5aa0172558
2
AUTHORS
2
AUTHORS
@ -45,6 +45,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Marty Alchin <gulopine@gamemusic.org>
|
Marty Alchin <gulopine@gamemusic.org>
|
||||||
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
|
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
|
||||||
AgarFu <heaven@croasanaso.sytes.net>
|
AgarFu <heaven@croasanaso.sytes.net>
|
||||||
|
Derek Anderson <public@kered.org>
|
||||||
Andreas
|
Andreas
|
||||||
andy@jadedplanet.net
|
andy@jadedplanet.net
|
||||||
Fabrice Aneche <akh@nobugware.com>
|
Fabrice Aneche <akh@nobugware.com>
|
||||||
@ -96,6 +97,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Maximillian Dornseif <md@hudora.de>
|
Maximillian Dornseif <md@hudora.de>
|
||||||
Jeremy Dunck <http://dunck.us/>
|
Jeremy Dunck <http://dunck.us/>
|
||||||
Andrew Durdin <adurdin@gmail.com>
|
Andrew Durdin <adurdin@gmail.com>
|
||||||
|
dusk@woofle.net
|
||||||
Andy Dustman <farcepest@gmail.com>
|
Andy Dustman <farcepest@gmail.com>
|
||||||
Clint Ecker
|
Clint Ecker
|
||||||
enlight
|
enlight
|
||||||
|
@ -18,7 +18,7 @@ class LogEntry(models.Model):
|
|||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
content_type = models.ForeignKey(ContentType, blank=True, null=True)
|
content_type = models.ForeignKey(ContentType, blank=True, null=True)
|
||||||
object_id = models.TextField(_('object id'), 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'))
|
action_flag = models.PositiveSmallIntegerField(_('action flag'))
|
||||||
change_message = models.TextField(_('change message'), blank=True)
|
change_message = models.TextField(_('change message'), blank=True)
|
||||||
objects = LogEntryManager()
|
objects = LogEntryManager()
|
||||||
|
@ -192,7 +192,7 @@ def auto_populated_field_script(auto_pop_fields, change = False):
|
|||||||
t.append(u'document.getElementById("id_%s").onkeyup = function() {' \
|
t.append(u'document.getElementById("id_%s").onkeyup = function() {' \
|
||||||
' var e = document.getElementById("id_%s");' \
|
' var e = document.getElementById("id_%s");' \
|
||||||
' if(!e._changed) { e.value = URLify(%s, %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)
|
return u''.join(t)
|
||||||
auto_populated_field_script = register.simple_tag(auto_populated_field_script)
|
auto_populated_field_script = register.simple_tag(auto_populated_field_script)
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ def get_return_data_type(func_name):
|
|||||||
DATA_TYPE_MAPPING = {
|
DATA_TYPE_MAPPING = {
|
||||||
'AutoField' : _('Integer'),
|
'AutoField' : _('Integer'),
|
||||||
'BooleanField' : _('Boolean (Either True or False)'),
|
'BooleanField' : _('Boolean (Either True or False)'),
|
||||||
'CharField' : _('String (up to %(maxlength)s)'),
|
'CharField' : _('String (up to %(max_length)s)'),
|
||||||
'CommaSeparatedIntegerField': _('Comma-separated integers'),
|
'CommaSeparatedIntegerField': _('Comma-separated integers'),
|
||||||
'DateField' : _('Date (without time)'),
|
'DateField' : _('Date (without time)'),
|
||||||
'DateTimeField' : _('Date (with time)'),
|
'DateTimeField' : _('Date (with time)'),
|
||||||
@ -310,7 +310,7 @@ DATA_TYPE_MAPPING = {
|
|||||||
'PhoneNumberField' : _('Phone number'),
|
'PhoneNumberField' : _('Phone number'),
|
||||||
'PositiveIntegerField' : _('Integer'),
|
'PositiveIntegerField' : _('Integer'),
|
||||||
'PositiveSmallIntegerField' : _('Integer'),
|
'PositiveSmallIntegerField' : _('Integer'),
|
||||||
'SlugField' : _('String (up to %(maxlength)s)'),
|
'SlugField' : _('String (up to %(max_length)s)'),
|
||||||
'SmallIntegerField' : _('Integer'),
|
'SmallIntegerField' : _('Integer'),
|
||||||
'TextField' : _('Text'),
|
'TextField' : _('Text'),
|
||||||
'TimeField' : _('Time'),
|
'TimeField' : _('Time'),
|
||||||
|
@ -673,7 +673,7 @@ class ChangeList(object):
|
|||||||
try:
|
try:
|
||||||
attr = getattr(lookup_opts.admin.manager.model, field_name)
|
attr = getattr(lookup_opts.admin.manager.model, field_name)
|
||||||
order_field = attr.admin_order_field
|
order_field = attr.admin_order_field
|
||||||
except IndexError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if not isinstance(f.rel, models.ManyToOneRel) or not f.null:
|
if not isinstance(f.rel, models.ManyToOneRel) or not f.null:
|
||||||
|
@ -10,10 +10,10 @@ class UserCreationForm(oldforms.Manipulator):
|
|||||||
"A form that creates a user, with no privileges, from the given username and password."
|
"A form that creates a user, with no privileges, from the given username and password."
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.fields = (
|
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]),
|
validator_list=[validators.isAlphaNumeric, self.isValidUsername]),
|
||||||
oldforms.PasswordField(field_name='password1', 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, maxlength=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."))]),
|
validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,9 +42,9 @@ class AuthenticationForm(oldforms.Manipulator):
|
|||||||
"""
|
"""
|
||||||
self.request = request
|
self.request = request
|
||||||
self.fields = [
|
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]),
|
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
|
self.user_cache = None
|
||||||
|
|
||||||
@ -111,11 +111,11 @@ class PasswordChangeForm(oldforms.Manipulator):
|
|||||||
def __init__(self, user):
|
def __init__(self, user):
|
||||||
self.user = user
|
self.user = user
|
||||||
self.fields = (
|
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]),
|
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."))]),
|
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):
|
def isValidOldPassword(self, new_data, all_data):
|
||||||
@ -133,8 +133,8 @@ class AdminPasswordChangeForm(oldforms.Manipulator):
|
|||||||
def __init__(self, user):
|
def __init__(self, user):
|
||||||
self.user = user
|
self.user = user
|
||||||
self.fields = (
|
self.fields = (
|
||||||
oldforms.PasswordField(field_name='password1', 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, maxlength=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."))]),
|
validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@ class Permission(models.Model):
|
|||||||
|
|
||||||
Three basic permissions -- add, change and delete -- are automatically created for each Django 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)
|
content_type = models.ForeignKey(ContentType)
|
||||||
codename = models.CharField(_('codename'), maxlength=100)
|
codename = models.CharField(_('codename'), max_length=100)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('permission')
|
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.
|
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)
|
permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -108,11 +108,11 @@ class User(models.Model):
|
|||||||
|
|
||||||
Username and password are required. Other fields are optional.
|
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)."))
|
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'), maxlength=30, blank=True)
|
first_name = models.CharField(_('first name'), max_length=30, blank=True)
|
||||||
last_name = models.CharField(_('last name'), maxlength=30, blank=True)
|
last_name = models.CharField(_('last name'), max_length=30, blank=True)
|
||||||
email = models.EmailField(_('e-mail address'), 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_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_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."))
|
is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))
|
||||||
|
@ -65,8 +65,8 @@ class Comment(models.Model):
|
|||||||
user = models.ForeignKey(User, raw_id_admin=True)
|
user = models.ForeignKey(User, raw_id_admin=True)
|
||||||
content_type = models.ForeignKey(ContentType)
|
content_type = models.ForeignKey(ContentType)
|
||||||
object_id = models.IntegerField(_('object ID'))
|
object_id = models.IntegerField(_('object ID'))
|
||||||
headline = models.CharField(_('headline'), maxlength=255, blank=True)
|
headline = models.CharField(_('headline'), max_length=255, blank=True)
|
||||||
comment = models.TextField(_('comment'), maxlength=3000)
|
comment = models.TextField(_('comment'), max_length=3000)
|
||||||
rating1 = models.PositiveSmallIntegerField(_('rating #1'), blank=True, null=True)
|
rating1 = models.PositiveSmallIntegerField(_('rating #1'), blank=True, null=True)
|
||||||
rating2 = models.PositiveSmallIntegerField(_('rating #2'), blank=True, null=True)
|
rating2 = models.PositiveSmallIntegerField(_('rating #2'), blank=True, null=True)
|
||||||
rating3 = models.PositiveSmallIntegerField(_('rating #3'), 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.
|
# A FreeComment is a comment by a non-registered user.
|
||||||
content_type = models.ForeignKey(ContentType)
|
content_type = models.ForeignKey(ContentType)
|
||||||
object_id = models.IntegerField(_('object ID'))
|
object_id = models.IntegerField(_('object ID'))
|
||||||
comment = models.TextField(_('comment'), maxlength=3000)
|
comment = models.TextField(_('comment'), max_length=3000)
|
||||||
person_name = models.CharField(_("person's name"), maxlength=50)
|
person_name = models.CharField(_("person's name"), max_length=50)
|
||||||
submit_date = models.DateTimeField(_('date/time submitted'), auto_now_add=True)
|
submit_date = models.DateTimeField(_('date/time submitted'), auto_now_add=True)
|
||||||
is_public = models.BooleanField(_('is public'))
|
is_public = models.BooleanField(_('is public'))
|
||||||
ip_address = models.IPAddressField(_('ip address'))
|
ip_address = models.IPAddressField(_('ip address'))
|
||||||
|
@ -29,7 +29,7 @@ class PublicCommentManipulator(AuthenticationForm):
|
|||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
self.fields.extend([
|
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]),
|
validator_list=[self.hasNoProfanities]),
|
||||||
oldforms.RadioSelectField(field_name="rating1", choices=choices,
|
oldforms.RadioSelectField(field_name="rating1", choices=choices,
|
||||||
is_required=ratings_required and num_rating_choices > 0,
|
is_required=ratings_required and num_rating_choices > 0,
|
||||||
@ -122,9 +122,9 @@ class PublicFreeCommentManipulator(oldforms.Manipulator):
|
|||||||
"Manipulator that handles public free (unregistered) comments"
|
"Manipulator that handles public free (unregistered) comments"
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.fields = (
|
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]),
|
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]),
|
validator_list=[self.hasNoProfanities]),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ class ContentTypeManager(models.Manager):
|
|||||||
CONTENT_TYPE_CACHE = {}
|
CONTENT_TYPE_CACHE = {}
|
||||||
|
|
||||||
class ContentType(models.Model):
|
class ContentType(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
app_label = models.CharField(maxlength=100)
|
app_label = models.CharField(max_length=100)
|
||||||
model = models.CharField(_('python model class name'), maxlength=100)
|
model = models.CharField(_('python model class name'), max_length=100)
|
||||||
objects = ContentTypeManager()
|
objects = ContentTypeManager()
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('content type')
|
verbose_name = _('content type')
|
||||||
|
@ -4,12 +4,12 @@ from django.contrib.sites.models import Site
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
class FlatPage(models.Model):
|
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."))
|
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'))
|
content = models.TextField(_('content'))
|
||||||
enable_comments = models.BooleanField(_('enable comments'))
|
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'."))
|
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."))
|
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)
|
sites = models.ManyToManyField(Site)
|
||||||
|
@ -4,9 +4,9 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
class Redirect(models.Model):
|
class Redirect(models.Model):
|
||||||
site = models.ForeignKey(Site, radio_admin=models.VERTICAL)
|
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/'."))
|
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://'."))
|
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -65,7 +65,7 @@ class Session(models.Model):
|
|||||||
the sessions documentation that is shipped with Django (also available
|
the sessions documentation that is shipped with Django (also available
|
||||||
on the Django website).
|
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'))
|
session_data = models.TextField(_('session data'))
|
||||||
expire_date = models.DateTimeField(_('expire date'))
|
expire_date = models.DateTimeField(_('expire date'))
|
||||||
objects = SessionManager()
|
objects = SessionManager()
|
||||||
|
@ -12,8 +12,8 @@ class SiteManager(models.Manager):
|
|||||||
return self.get(pk=sid)
|
return self.get(pk=sid)
|
||||||
|
|
||||||
class Site(models.Model):
|
class Site(models.Model):
|
||||||
domain = models.CharField(_('domain name'), maxlength=100)
|
domain = models.CharField(_('domain name'), max_length=100)
|
||||||
name = models.CharField(_('display name'), maxlength=50)
|
name = models.CharField(_('display name'), max_length=50)
|
||||||
objects = SiteManager()
|
objects = SiteManager()
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'django_site'
|
db_table = 'django_site'
|
||||||
|
@ -1064,9 +1064,9 @@ def inspectdb():
|
|||||||
field_type, new_params = field_type
|
field_type, new_params = field_type
|
||||||
extra_params.update(new_params)
|
extra_params.update(new_params)
|
||||||
|
|
||||||
# Add maxlength for all CharFields.
|
# Add max_length for all CharFields.
|
||||||
if field_type == 'CharField' and row[3]:
|
if field_type == 'CharField' and row[3]:
|
||||||
extra_params['maxlength'] = row[3]
|
extra_params['max_length'] = row[3]
|
||||||
|
|
||||||
if field_type == 'DecimalField':
|
if field_type == 'DecimalField':
|
||||||
extra_params['max_digits'] = row[4]
|
extra_params['max_digits'] = row[4]
|
||||||
@ -1141,8 +1141,8 @@ def get_validation_errors(outfile, app=None):
|
|||||||
for f in opts.fields:
|
for f in opts.fields:
|
||||||
if f.name == 'id' and not f.primary_key and opts.pk.name == 'id':
|
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)
|
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):
|
if isinstance(f, models.CharField) and f.max_length in (None, 0):
|
||||||
e.add(opts, '"%s": CharFields require a "maxlength" attribute.' % f.name)
|
e.add(opts, '"%s": CharFields require a "max_length" attribute.' % f.name)
|
||||||
if isinstance(f, models.DecimalField):
|
if isinstance(f, models.DecimalField):
|
||||||
if f.decimal_places is None:
|
if f.decimal_places is None:
|
||||||
e.add(opts, '"%s": DecimalFields require a "decimal_places" attribute.' % f.name)
|
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):
|
if f.db_index not in (None, True, False):
|
||||||
e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name)
|
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':
|
if settings.DATABASE_ENGINE == 'mysql':
|
||||||
db_version = connection.get_server_version()
|
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:
|
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 "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]])))
|
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
|
# Check to see if the related field will clash with any
|
||||||
# existing fields, m2m fields, m2m related objects or related objects
|
# 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
|
from django.db import backend, connection, transaction, models
|
||||||
fields = (
|
fields = (
|
||||||
# "key" is a reserved word in MySQL, so use "cache_key" instead.
|
# "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.TextField(name='value'),
|
||||||
models.DateTimeField(name='expires', db_index=True),
|
models.DateTimeField(name='expires', db_index=True),
|
||||||
)
|
)
|
||||||
@ -1454,6 +1454,10 @@ def run_shell(use_plain=False):
|
|||||||
shell.mainloop()
|
shell.mainloop()
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import code
|
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.
|
try: # Try activating rlcompleter, because it's handy.
|
||||||
import readline
|
import readline
|
||||||
except ImportError:
|
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 don't have to wrap the following import in a 'try', because
|
||||||
# we already know 'readline' was imported successfully.
|
# we already know 'readline' was imported successfully.
|
||||||
import rlcompleter
|
import rlcompleter
|
||||||
|
readline.set_completer(rlcompleter.Completer(imported_objects).complete)
|
||||||
readline.parse_and_bind("tab:complete")
|
readline.parse_and_bind("tab:complete")
|
||||||
code.interact()
|
code.interact(local=imported_objects)
|
||||||
run_shell.args = '[--plain]'
|
run_shell.args = '[--plain]'
|
||||||
|
|
||||||
def dbshell():
|
def dbshell():
|
||||||
@ -1578,7 +1583,7 @@ def load_data(fixture_labels, verbosity=1):
|
|||||||
print "Installing %s fixture '%s' from %s." % \
|
print "Installing %s fixture '%s' from %s." % \
|
||||||
(format, fixture_name, humanize(fixture_dir))
|
(format, fixture_name, humanize(fixture_dir))
|
||||||
try:
|
try:
|
||||||
objects = serializers.deserialize(format, fixture)
|
objects = serializers.deserialize(format, fixture)
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
count[0] += 1
|
count[0] += 1
|
||||||
models.add(obj.object.__class__)
|
models.add(obj.object.__class__)
|
||||||
|
@ -442,7 +442,7 @@ def isValidFloat(field_data, all_data):
|
|||||||
try:
|
try:
|
||||||
float(data)
|
float(data)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValidationError, ugettext("Please enter a valid floating point number.")
|
raise ValidationError, _("Please enter a valid floating point number.")
|
||||||
|
|
||||||
class HasAllowableSize(object):
|
class HasAllowableSize(object):
|
||||||
"""
|
"""
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
DATA_TYPES = {
|
DATA_TYPES = {
|
||||||
'AutoField': 'int IDENTITY (1, 1)',
|
'AutoField': 'int IDENTITY (1, 1)',
|
||||||
'BooleanField': 'bit',
|
'BooleanField': 'bit',
|
||||||
'CharField': 'varchar(%(maxlength)s)',
|
'CharField': 'varchar(%(max_length)s)',
|
||||||
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
|
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
|
||||||
'DateField': 'smalldatetime',
|
'DateField': 'smalldatetime',
|
||||||
'DateTimeField': 'smalldatetime',
|
'DateTimeField': 'smalldatetime',
|
||||||
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
||||||
@ -17,7 +17,7 @@ DATA_TYPES = {
|
|||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(column)s] CHECK ([%(column)s] > 0)',
|
'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(column)s] CHECK ([%(column)s] > 0)',
|
||||||
'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_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',
|
'SmallIntegerField': 'smallint',
|
||||||
'TextField': 'text',
|
'TextField': 'text',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
DATA_TYPES = {
|
DATA_TYPES = {
|
||||||
'AutoField': 'integer AUTO_INCREMENT',
|
'AutoField': 'integer AUTO_INCREMENT',
|
||||||
'BooleanField': 'bool',
|
'BooleanField': 'bool',
|
||||||
'CharField': 'varchar(%(maxlength)s)',
|
'CharField': 'varchar(%(max_length)s)',
|
||||||
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
|
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
|
||||||
'DateField': 'date',
|
'DateField': 'date',
|
||||||
'DateTimeField': 'datetime',
|
'DateTimeField': 'datetime',
|
||||||
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
||||||
@ -21,7 +21,7 @@ DATA_TYPES = {
|
|||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
'PositiveIntegerField': 'integer UNSIGNED',
|
'PositiveIntegerField': 'integer UNSIGNED',
|
||||||
'PositiveSmallIntegerField': 'smallint UNSIGNED',
|
'PositiveSmallIntegerField': 'smallint UNSIGNED',
|
||||||
'SlugField': 'varchar(%(maxlength)s)',
|
'SlugField': 'varchar(%(max_length)s)',
|
||||||
'SmallIntegerField': 'smallint',
|
'SmallIntegerField': 'smallint',
|
||||||
'TextField': 'longtext',
|
'TextField': 'longtext',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
DATA_TYPES = {
|
DATA_TYPES = {
|
||||||
'AutoField': 'integer AUTO_INCREMENT',
|
'AutoField': 'integer AUTO_INCREMENT',
|
||||||
'BooleanField': 'bool',
|
'BooleanField': 'bool',
|
||||||
'CharField': 'varchar(%(maxlength)s)',
|
'CharField': 'varchar(%(max_length)s)',
|
||||||
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
|
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
|
||||||
'DateField': 'date',
|
'DateField': 'date',
|
||||||
'DateTimeField': 'datetime',
|
'DateTimeField': 'datetime',
|
||||||
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
||||||
@ -21,7 +21,7 @@ DATA_TYPES = {
|
|||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
'PositiveIntegerField': 'integer UNSIGNED',
|
'PositiveIntegerField': 'integer UNSIGNED',
|
||||||
'PositiveSmallIntegerField': 'smallint UNSIGNED',
|
'PositiveSmallIntegerField': 'smallint UNSIGNED',
|
||||||
'SlugField': 'varchar(%(maxlength)s)',
|
'SlugField': 'varchar(%(max_length)s)',
|
||||||
'SmallIntegerField': 'smallint',
|
'SmallIntegerField': 'smallint',
|
||||||
'TextField': 'longtext',
|
'TextField': 'longtext',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
|
@ -8,8 +8,8 @@ from django.core import management
|
|||||||
DATA_TYPES = {
|
DATA_TYPES = {
|
||||||
'AutoField': 'NUMBER(11)',
|
'AutoField': 'NUMBER(11)',
|
||||||
'BooleanField': 'NUMBER(1) CHECK (%(column)s IN (0,1))',
|
'BooleanField': 'NUMBER(1) CHECK (%(column)s IN (0,1))',
|
||||||
'CharField': 'NVARCHAR2(%(maxlength)s)',
|
'CharField': 'NVARCHAR2(%(max_length)s)',
|
||||||
'CommaSeparatedIntegerField': 'VARCHAR2(%(maxlength)s)',
|
'CommaSeparatedIntegerField': 'VARCHAR2(%(max_length)s)',
|
||||||
'DateField': 'DATE',
|
'DateField': 'DATE',
|
||||||
'DateTimeField': 'TIMESTAMP',
|
'DateTimeField': 'TIMESTAMP',
|
||||||
'DecimalField': 'NUMBER(%(max_digits)s, %(decimal_places)s)',
|
'DecimalField': 'NUMBER(%(max_digits)s, %(decimal_places)s)',
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
DATA_TYPES = {
|
DATA_TYPES = {
|
||||||
'AutoField': 'serial',
|
'AutoField': 'serial',
|
||||||
'BooleanField': 'boolean',
|
'BooleanField': 'boolean',
|
||||||
'CharField': 'varchar(%(maxlength)s)',
|
'CharField': 'varchar(%(max_length)s)',
|
||||||
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
|
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
|
||||||
'DateField': 'date',
|
'DateField': 'date',
|
||||||
'DateTimeField': 'timestamp with time zone',
|
'DateTimeField': 'timestamp with time zone',
|
||||||
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
||||||
@ -21,7 +21,7 @@ DATA_TYPES = {
|
|||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)',
|
'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)',
|
||||||
'PositiveSmallIntegerField': 'smallint CHECK ("%(column)s" >= 0)',
|
'PositiveSmallIntegerField': 'smallint CHECK ("%(column)s" >= 0)',
|
||||||
'SlugField': 'varchar(%(maxlength)s)',
|
'SlugField': 'varchar(%(max_length)s)',
|
||||||
'SmallIntegerField': 'smallint',
|
'SmallIntegerField': 'smallint',
|
||||||
'TextField': 'text',
|
'TextField': 'text',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
DATA_TYPES = {
|
DATA_TYPES = {
|
||||||
'AutoField': 'integer',
|
'AutoField': 'integer',
|
||||||
'BooleanField': 'bool',
|
'BooleanField': 'bool',
|
||||||
'CharField': 'varchar(%(maxlength)s)',
|
'CharField': 'varchar(%(max_length)s)',
|
||||||
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
|
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
|
||||||
'DateField': 'date',
|
'DateField': 'date',
|
||||||
'DateTimeField': 'datetime',
|
'DateTimeField': 'datetime',
|
||||||
'DecimalField': 'decimal',
|
'DecimalField': 'decimal',
|
||||||
@ -20,7 +20,7 @@ DATA_TYPES = {
|
|||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
'PositiveIntegerField': 'integer unsigned',
|
'PositiveIntegerField': 'integer unsigned',
|
||||||
'PositiveSmallIntegerField': 'smallint unsigned',
|
'PositiveSmallIntegerField': 'smallint unsigned',
|
||||||
'SlugField': 'varchar(%(maxlength)s)',
|
'SlugField': 'varchar(%(max_length)s)',
|
||||||
'SmallIntegerField': 'smallint',
|
'SmallIntegerField': 'smallint',
|
||||||
'TextField': 'text',
|
'TextField': 'text',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
|
@ -137,7 +137,7 @@ class FlexibleFieldLookupDict:
|
|||||||
import re
|
import re
|
||||||
m = re.search(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$', key)
|
m = re.search(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$', key)
|
||||||
if m:
|
if m:
|
||||||
return ('CharField', {'maxlength': int(m.group(1))})
|
return ('CharField', {'max_length': int(m.group(1))})
|
||||||
raise KeyError
|
raise KeyError
|
||||||
|
|
||||||
DATA_TYPES_REVERSE = FlexibleFieldLookupDict()
|
DATA_TYPES_REVERSE = FlexibleFieldLookupDict()
|
||||||
|
@ -11,6 +11,7 @@ from django.utils.itercompat import tee
|
|||||||
from django.utils.text import capfirst
|
from django.utils.text import capfirst
|
||||||
from django.utils.translation import ugettext_lazy, ugettext as _
|
from django.utils.translation import ugettext_lazy, ugettext as _
|
||||||
from django.utils.encoding import smart_unicode, force_unicode, smart_str
|
from django.utils.encoding import smart_unicode, force_unicode, smart_str
|
||||||
|
from django.utils.maxlength import LegacyMaxlength
|
||||||
import datetime, os, time
|
import datetime, os, time
|
||||||
try:
|
try:
|
||||||
import decimal
|
import decimal
|
||||||
@ -63,6 +64,9 @@ def manipulator_validator_unique(f, opts, self, field_data, all_data):
|
|||||||
# getattr(obj, opts.pk.attname)
|
# getattr(obj, opts.pk.attname)
|
||||||
|
|
||||||
class Field(object):
|
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
|
# Designates whether empty strings fundamentally are allowed at the
|
||||||
# database level.
|
# database level.
|
||||||
@ -72,7 +76,7 @@ class Field(object):
|
|||||||
creation_counter = 0
|
creation_counter = 0
|
||||||
|
|
||||||
def __init__(self, verbose_name=None, name=None, primary_key=False,
|
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,
|
core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True,
|
||||||
prepopulate_from=None, unique_for_date=None, unique_for_month=None,
|
prepopulate_from=None, unique_for_date=None, unique_for_month=None,
|
||||||
unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
|
unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
|
||||||
@ -80,7 +84,7 @@ class Field(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.verbose_name = verbose_name
|
self.verbose_name = verbose_name
|
||||||
self.primary_key = primary_key
|
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
|
self.blank, self.null = blank, null
|
||||||
# Oracle treats the empty string ('') as null, so coerce the null
|
# Oracle treats the empty string ('') as null, so coerce the null
|
||||||
# option whenever '' is a possible value.
|
# option whenever '' is a possible value.
|
||||||
@ -245,8 +249,8 @@ class Field(object):
|
|||||||
|
|
||||||
def prepare_field_objs_and_params(self, manipulator, name_prefix):
|
def prepare_field_objs_and_params(self, manipulator, name_prefix):
|
||||||
params = {'validator_list': self.validator_list[:]}
|
params = {'validator_list': self.validator_list[:]}
|
||||||
if self.maxlength and not self.choices: # Don't give SelectFields a maxlength parameter.
|
if self.max_length and not self.choices: # Don't give SelectFields a max_length parameter.
|
||||||
params['maxlength'] = self.maxlength
|
params['max_length'] = self.max_length
|
||||||
|
|
||||||
if self.choices:
|
if self.choices:
|
||||||
if self.radio_admin:
|
if self.radio_admin:
|
||||||
@ -377,6 +381,9 @@ class Field(object):
|
|||||||
return self._choices
|
return self._choices
|
||||||
choices = property(_get_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):
|
def formfield(self, form_class=forms.CharField, **kwargs):
|
||||||
"Returns a django.newforms.Field instance for this database Field."
|
"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}
|
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)
|
return smart_unicode(value)
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
defaults = {'max_length': self.maxlength}
|
defaults = {'max_length': self.max_length}
|
||||||
defaults.update(kwargs)
|
defaults.update(kwargs)
|
||||||
return super(CharField, self).formfield(**defaults)
|
return super(CharField, self).formfield(**defaults)
|
||||||
|
|
||||||
@ -671,7 +678,7 @@ class DecimalField(Field):
|
|||||||
|
|
||||||
class EmailField(CharField):
|
class EmailField(CharField):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
kwargs['maxlength'] = 75
|
kwargs['max_length'] = 75
|
||||||
CharField.__init__(self, *args, **kwargs)
|
CharField.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def get_internal_type(self):
|
def get_internal_type(self):
|
||||||
@ -693,6 +700,13 @@ class FileField(Field):
|
|||||||
self.upload_to = upload_to
|
self.upload_to = upload_to
|
||||||
Field.__init__(self, verbose_name, name, **kwargs)
|
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):
|
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)
|
field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
|
||||||
if not self.blank:
|
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)))
|
f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
|
||||||
return os.path.normpath(f)
|
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):
|
class FilePathField(Field):
|
||||||
def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs):
|
def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs):
|
||||||
self.path, self.match, self.recursive = path, match, recursive
|
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))
|
setattr(new_object, self.height_field, getattr(original_object, self.height_field))
|
||||||
new_object.save()
|
new_object.save()
|
||||||
|
|
||||||
|
def formfield(self, **kwargs):
|
||||||
|
defaults = {'form_class': forms.ImageField}
|
||||||
|
return super(ImageField, self).formfield(**defaults)
|
||||||
|
|
||||||
class IntegerField(Field):
|
class IntegerField(Field):
|
||||||
empty_strings_allowed = False
|
empty_strings_allowed = False
|
||||||
def get_manipulator_field_objs(self):
|
def get_manipulator_field_objs(self):
|
||||||
@ -830,7 +861,7 @@ class IntegerField(Field):
|
|||||||
class IPAddressField(Field):
|
class IPAddressField(Field):
|
||||||
empty_strings_allowed = False
|
empty_strings_allowed = False
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
kwargs['maxlength'] = 15
|
kwargs['max_length'] = 15
|
||||||
Field.__init__(self, *args, **kwargs)
|
Field.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def get_manipulator_field_objs(self):
|
def get_manipulator_field_objs(self):
|
||||||
@ -878,7 +909,7 @@ class PositiveSmallIntegerField(IntegerField):
|
|||||||
|
|
||||||
class SlugField(Field):
|
class SlugField(Field):
|
||||||
def __init__(self, *args, **kwargs):
|
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)
|
kwargs.setdefault('validator_list', []).append(validators.isSlug)
|
||||||
# Set db_index=True unless it's been set manually.
|
# Set db_index=True unless it's been set manually.
|
||||||
if 'db_index' not in kwargs:
|
if 'db_index' not in kwargs:
|
||||||
@ -964,7 +995,7 @@ class TimeField(Field):
|
|||||||
|
|
||||||
class URLField(CharField):
|
class URLField(CharField):
|
||||||
def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
|
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:
|
if verify_exists:
|
||||||
kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
|
kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
|
||||||
self.verify_exists = verify_exists
|
self.verify_exists = verify_exists
|
||||||
|
@ -756,6 +756,9 @@ class ManyToManyField(RelatedField, Field):
|
|||||||
"Returns the value of this field in the given model instance."
|
"Returns the value of this field in the given model instance."
|
||||||
return getattr(obj, self.attname).all()
|
return getattr(obj, self.attname).all()
|
||||||
|
|
||||||
|
def save_form_data(self, instance, data):
|
||||||
|
setattr(instance, self.attname, data)
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
defaults = {'form_class': forms.ModelMultipleChoiceField, 'queryset': self.rel.to._default_manager.all()}
|
defaults = {'form_class': forms.ModelMultipleChoiceField, 'queryset': self.rel.to._default_manager.all()}
|
||||||
defaults.update(kwargs)
|
defaults.update(kwargs)
|
||||||
|
@ -53,7 +53,7 @@ class SelectDateWidget(Widget):
|
|||||||
|
|
||||||
return u'\n'.join(output)
|
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)
|
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:
|
if y and m and d:
|
||||||
return '%s-%s-%s' % (y, m, d)
|
return '%s-%s-%s' % (y, m, d)
|
||||||
|
@ -7,10 +7,10 @@ import re
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from django.utils.translation import ugettext
|
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 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:
|
try:
|
||||||
from decimal import Decimal, DecimalException
|
from decimal import Decimal, DecimalException
|
||||||
@ -22,7 +22,7 @@ __all__ = (
|
|||||||
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
|
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
|
||||||
'DEFAULT_TIME_INPUT_FORMATS', 'TimeField',
|
'DEFAULT_TIME_INPUT_FORMATS', 'TimeField',
|
||||||
'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField',
|
'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField',
|
||||||
'RegexField', 'EmailField', 'URLField', 'BooleanField',
|
'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField',
|
||||||
'ChoiceField', 'NullBooleanField', 'MultipleChoiceField',
|
'ChoiceField', 'NullBooleanField', 'MultipleChoiceField',
|
||||||
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
|
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
|
||||||
'SplitDateTimeField',
|
'SplitDateTimeField',
|
||||||
@ -120,6 +120,7 @@ class CharField(Field):
|
|||||||
|
|
||||||
def widget_attrs(self, widget):
|
def widget_attrs(self, widget):
|
||||||
if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)):
|
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)}
|
return {'maxlength': str(self.max_length)}
|
||||||
|
|
||||||
class IntegerField(Field):
|
class IntegerField(Field):
|
||||||
@ -347,6 +348,55 @@ except ImportError:
|
|||||||
# It's OK if Django settings aren't configured.
|
# It's OK if Django settings aren't configured.
|
||||||
URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
|
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):
|
class URLField(RegexField):
|
||||||
def __init__(self, max_length=None, min_length=None, verify_exists=False,
|
def __init__(self, max_length=None, min_length=None, verify_exists=False,
|
||||||
validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs):
|
validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs):
|
||||||
|
@ -57,9 +57,10 @@ class BaseForm(StrAndUnicode):
|
|||||||
# class is different than Form. See the comments by the Form class for more
|
# 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*
|
# information. Any improvements to the form API should be made to *this*
|
||||||
# class, not to the Form class.
|
# class, not to the Form class.
|
||||||
def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None):
|
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None):
|
||||||
self.is_bound = data is not None
|
self.is_bound = data is not None or files is not None
|
||||||
self.data = data or {}
|
self.data = data or {}
|
||||||
|
self.files = files or {}
|
||||||
self.auto_id = auto_id
|
self.auto_id = auto_id
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
self.initial = initial or {}
|
self.initial = initial or {}
|
||||||
@ -88,7 +89,7 @@ class BaseForm(StrAndUnicode):
|
|||||||
return BoundField(self, field, name)
|
return BoundField(self, field, name)
|
||||||
|
|
||||||
def _get_errors(self):
|
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:
|
if self._errors is None:
|
||||||
self.full_clean()
|
self.full_clean()
|
||||||
return self._errors
|
return self._errors
|
||||||
@ -179,10 +180,10 @@ class BaseForm(StrAndUnicode):
|
|||||||
return
|
return
|
||||||
self.cleaned_data = {}
|
self.cleaned_data = {}
|
||||||
for name, field in self.fields.items():
|
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
|
# Each widget type knows how to retrieve its own data, because some
|
||||||
# widgets split data over several HTML fields.
|
# 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:
|
try:
|
||||||
value = field.clean(value)
|
value = field.clean(value)
|
||||||
self.cleaned_data[name] = 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.
|
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)
|
data = property(_data)
|
||||||
|
|
||||||
def label_tag(self, contents=None, attrs=None):
|
def label_tag(self, contents=None, attrs=None):
|
||||||
|
@ -34,18 +34,24 @@ def save_instance(form, instance, fields=None, fail_message='saved', commit=True
|
|||||||
continue
|
continue
|
||||||
if fields and f.name not in fields:
|
if fields and f.name not in fields:
|
||||||
continue
|
continue
|
||||||
setattr(instance, f.name, cleaned_data[f.name])
|
f.save_form_data(instance, cleaned_data[f.name])
|
||||||
if commit:
|
# Wrap up the saving of m2m data as a function
|
||||||
instance.save()
|
def save_m2m():
|
||||||
|
opts = instance.__class__._meta
|
||||||
|
cleaned_data = form.cleaned_data
|
||||||
for f in opts.many_to_many:
|
for f in opts.many_to_many:
|
||||||
if fields and f.name not in fields:
|
if fields and f.name not in fields:
|
||||||
continue
|
continue
|
||||||
if f.name in cleaned_data:
|
if f.name in cleaned_data:
|
||||||
setattr(instance, f.attname, cleaned_data[f.name])
|
f.save_form_data(instance, cleaned_data[f.name])
|
||||||
# GOTCHA: If many-to-many data is given and commit=False, the many-to-many
|
if commit:
|
||||||
# data will be lost. This happens because a many-to-many options cannot be
|
# If we are committing, save the instance and the m2m data immediately
|
||||||
# set on an object until after it's saved. Maybe we should raise an
|
instance.save()
|
||||||
# exception in that case.
|
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
|
return instance
|
||||||
|
|
||||||
def make_model_save(model, fields, fail_message):
|
def make_model_save(model, fields, fail_message):
|
||||||
|
@ -47,7 +47,7 @@ class Widget(object):
|
|||||||
attrs.update(extra_attrs)
|
attrs.update(extra_attrs)
|
||||||
return 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
|
Given a dictionary of data and this widget's name, returns the value
|
||||||
of this widget. Returns None if it's not provided.
|
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)
|
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])
|
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):
|
if isinstance(data, MultiValueDict):
|
||||||
return data.getlist(name)
|
return data.getlist(name)
|
||||||
return data.get(name, None)
|
return data.get(name, None)
|
||||||
@ -121,6 +121,13 @@ class MultipleHiddenInput(HiddenInput):
|
|||||||
class FileInput(Input):
|
class FileInput(Input):
|
||||||
input_type = 'file'
|
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):
|
class Textarea(Widget):
|
||||||
def __init__(self, attrs=None):
|
def __init__(self, attrs=None):
|
||||||
# The 'rows' and 'cols' attributes are required for HTML correctness.
|
# The 'rows' and 'cols' attributes are required for HTML correctness.
|
||||||
@ -188,7 +195,7 @@ class NullBooleanSelect(Select):
|
|||||||
value = u'1'
|
value = u'1'
|
||||||
return super(NullBooleanSelect, self).render(name, value, attrs, choices)
|
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)
|
value = data.get(name, None)
|
||||||
return {u'2': True, u'3': False, True: True, False: False}.get(value, 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>')
|
output.append(u'</select>')
|
||||||
return u'\n'.join(output)
|
return u'\n'.join(output)
|
||||||
|
|
||||||
def value_from_datadict(self, data, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
if isinstance(data, MultiValueDict):
|
if isinstance(data, MultiValueDict):
|
||||||
return data.getlist(name)
|
return data.getlist(name)
|
||||||
return data.get(name, None)
|
return data.get(name, None)
|
||||||
@ -377,8 +384,8 @@ class MultiWidget(Widget):
|
|||||||
return id_
|
return id_
|
||||||
id_for_label = classmethod(id_for_label)
|
id_for_label = classmethod(id_for_label)
|
||||||
|
|
||||||
def value_from_datadict(self, data, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
return [widget.value_from_datadict(data, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
|
return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
|
||||||
|
|
||||||
def format_output(self, rendered_widgets):
|
def format_output(self, rendered_widgets):
|
||||||
"""
|
"""
|
||||||
|
@ -4,6 +4,7 @@ from django.utils.html import escape
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext, ungettext
|
from django.utils.translation import ugettext, ungettext
|
||||||
from django.utils.encoding import smart_unicode, force_unicode
|
from django.utils.encoding import smart_unicode, force_unicode
|
||||||
|
from django.utils.maxlength import LegacyMaxlength
|
||||||
|
|
||||||
FORM_FIELD_ID_PREFIX = 'id_'
|
FORM_FIELD_ID_PREFIX = 'id_'
|
||||||
|
|
||||||
@ -302,6 +303,9 @@ class FormField(object):
|
|||||||
Subclasses should also implement a render(data) method, which is responsible
|
Subclasses should also implement a render(data) method, which is responsible
|
||||||
for rending the form field in XHTML.
|
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):
|
def __str__(self):
|
||||||
return unicode(self).encode('utf-8')
|
return unicode(self).encode('utf-8')
|
||||||
@ -390,19 +394,19 @@ class FormField(object):
|
|||||||
|
|
||||||
class TextField(FormField):
|
class TextField(FormField):
|
||||||
input_type = "text"
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
self.field_name = field_name
|
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.is_required = is_required
|
||||||
self.validator_list = [self.isValidLength, self.hasNoNewlines] + validator_list
|
self.validator_list = [self.isValidLength, self.hasNoNewlines] + validator_list
|
||||||
if member_name != None:
|
if member_name != None:
|
||||||
self.member_name = member_name
|
self.member_name = member_name
|
||||||
|
|
||||||
def isValidLength(self, data, form):
|
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.",
|
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):
|
def hasNoNewlines(self, data, form):
|
||||||
if data and '\n' in data:
|
if data and '\n' in data:
|
||||||
@ -411,12 +415,12 @@ class TextField(FormField):
|
|||||||
def render(self, data):
|
def render(self, data):
|
||||||
if data is None:
|
if data is None:
|
||||||
data = u''
|
data = u''
|
||||||
maxlength = u''
|
max_length = u''
|
||||||
if self.maxlength:
|
if self.max_length:
|
||||||
maxlength = u'maxlength="%s" ' % self.maxlength
|
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/>' % \
|
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.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):
|
def html2python(data):
|
||||||
return data
|
return data
|
||||||
@ -426,14 +430,14 @@ class PasswordField(TextField):
|
|||||||
input_type = "password"
|
input_type = "password"
|
||||||
|
|
||||||
class LargeTextField(TextField):
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
self.field_name = field_name
|
self.field_name = field_name
|
||||||
self.rows, self.cols, self.is_required = rows, cols, is_required
|
self.rows, self.cols, self.is_required = rows, cols, is_required
|
||||||
self.validator_list = validator_list[:]
|
self.validator_list = validator_list[:]
|
||||||
if maxlength:
|
if max_length:
|
||||||
self.validator_list.append(self.isValidLength)
|
self.validator_list.append(self.isValidLength)
|
||||||
self.maxlength = maxlength
|
self.max_length = max_length
|
||||||
|
|
||||||
def render(self, data):
|
def render(self, data):
|
||||||
if data is None:
|
if data is None:
|
||||||
@ -710,12 +714,12 @@ class ImageUploadField(FileUploadField):
|
|||||||
####################
|
####################
|
||||||
|
|
||||||
class IntegerField(TextField):
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isInteger] + validator_list
|
validator_list = [self.isInteger] + validator_list
|
||||||
if member_name is not None:
|
if member_name is not None:
|
||||||
self.member_name = member_name
|
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):
|
def isInteger(self, field_data, all_data):
|
||||||
try:
|
try:
|
||||||
@ -730,57 +734,57 @@ class IntegerField(TextField):
|
|||||||
html2python = staticmethod(html2python)
|
html2python = staticmethod(html2python)
|
||||||
|
|
||||||
class SmallIntegerField(IntegerField):
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isSmallInteger] + 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):
|
def isSmallInteger(self, field_data, all_data):
|
||||||
if not -32768 <= int(field_data) <= 32767:
|
if not -32768 <= int(field_data) <= 32767:
|
||||||
raise validators.CriticalValidationError, ugettext("Enter a whole number between -32,768 and 32,767.")
|
raise validators.CriticalValidationError, ugettext("Enter a whole number between -32,768 and 32,767.")
|
||||||
|
|
||||||
class PositiveIntegerField(IntegerField):
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isPositive] + 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):
|
def isPositive(self, field_data, all_data):
|
||||||
if int(field_data) < 0:
|
if int(field_data) < 0:
|
||||||
raise validators.CriticalValidationError, ugettext("Enter a positive number.")
|
raise validators.CriticalValidationError, ugettext("Enter a positive number.")
|
||||||
|
|
||||||
class PositiveSmallIntegerField(IntegerField):
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isPositiveSmall] + 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):
|
def isPositiveSmall(self, field_data, all_data):
|
||||||
if not 0 <= int(field_data) <= 32767:
|
if not 0 <= int(field_data) <= 32767:
|
||||||
raise validators.CriticalValidationError, ugettext("Enter a whole number between 0 and 32,767.")
|
raise validators.CriticalValidationError, ugettext("Enter a whole number between 0 and 32,767.")
|
||||||
|
|
||||||
class FloatField(TextField):
|
class FloatField(TextField):
|
||||||
def __init__(self, field_name, is_required=False, validator_list=None):
|
def __init__(self, field_name, is_required=False, validator_list=None):
|
||||||
if validator_list is None: validator_list = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [validators.isValidFloat] + validator_list
|
validator_list = [validators.isValidFloat] + validator_list
|
||||||
TextField.__init__(self, field_name, is_required=is_required, validator_list=validator_list)
|
TextField.__init__(self, field_name, is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def html2python(data):
|
def html2python(data):
|
||||||
if data == '' or data is None:
|
if data == '' or data is None:
|
||||||
return None
|
return None
|
||||||
return float(data)
|
return float(data)
|
||||||
html2python = staticmethod(html2python)
|
html2python = staticmethod(html2python)
|
||||||
|
|
||||||
class DecimalField(TextField):
|
class DecimalField(TextField):
|
||||||
def __init__(self, field_name, max_digits, decimal_places, is_required=False, validator_list=None):
|
def __init__(self, field_name, max_digits, decimal_places, is_required=False, validator_list=None):
|
||||||
if validator_list is None: validator_list = []
|
if validator_list is None: validator_list = []
|
||||||
self.max_digits, self.decimal_places = max_digits, decimal_places
|
self.max_digits, self.decimal_places = max_digits, decimal_places
|
||||||
validator_list = [self.isValidDecimal] + validator_list
|
validator_list = [self.isValidDecimal] + validator_list
|
||||||
# Initialise the TextField, making sure it's large enough to fit the number with a - sign and a decimal point.
|
# Initialise the TextField, making sure it's large enough to fit the number with a - sign and a decimal point.
|
||||||
super(DecimalField, self).__init__(field_name, max_digits+2, max_digits+2, is_required, validator_list)
|
super(DecimalField, self).__init__(field_name, max_digits+2, max_digits+2, is_required, validator_list)
|
||||||
|
|
||||||
def isValidDecimal(self, field_data, all_data):
|
def isValidDecimal(self, field_data, all_data):
|
||||||
v = validators.IsValidDecimal(self.max_digits, self.decimal_places)
|
v = validators.IsValidDecimal(self.max_digits, self.decimal_places)
|
||||||
try:
|
try:
|
||||||
v(field_data, all_data)
|
v(field_data, all_data)
|
||||||
except validators.ValidationError, e:
|
except validators.ValidationError, e:
|
||||||
@ -789,14 +793,14 @@ class DecimalField(TextField):
|
|||||||
def html2python(data):
|
def html2python(data):
|
||||||
if data == '' or data is None:
|
if data == '' or data is None:
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
import decimal
|
import decimal
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from django.utils import _decimal as decimal
|
from django.utils import _decimal as decimal
|
||||||
try:
|
try:
|
||||||
return decimal.Decimal(data)
|
return decimal.Decimal(data)
|
||||||
except decimal.InvalidOperation, e:
|
except decimal.InvalidOperation, e:
|
||||||
raise ValueError, e
|
raise ValueError, e
|
||||||
html2python = staticmethod(html2python)
|
html2python = staticmethod(html2python)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
@ -806,10 +810,10 @@ class DecimalField(TextField):
|
|||||||
class DatetimeField(TextField):
|
class DatetimeField(TextField):
|
||||||
"""A FormField that automatically converts its data to a datetime.datetime object.
|
"""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."""
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
self.field_name = field_name
|
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.is_required = is_required
|
||||||
self.validator_list = [validators.isValidANSIDatetime] + validator_list
|
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):
|
def __init__(self, field_name, is_required=False, validator_list=None):
|
||||||
if validator_list is None: validator_list = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isValidDate] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isValidDate(self, field_data, all_data):
|
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):
|
def __init__(self, field_name, is_required=False, validator_list=None):
|
||||||
if validator_list is None: validator_list = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isValidTime] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isValidTime(self, field_data, all_data):
|
def isValidTime(self, field_data, all_data):
|
||||||
@ -893,10 +897,10 @@ class TimeField(TextField):
|
|||||||
|
|
||||||
class EmailField(TextField):
|
class EmailField(TextField):
|
||||||
"A convenience FormField for validating e-mail addresses"
|
"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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isValidEmail] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isValidEmail(self, field_data, all_data):
|
def isValidEmail(self, field_data, all_data):
|
||||||
@ -907,10 +911,10 @@ class EmailField(TextField):
|
|||||||
|
|
||||||
class URLField(TextField):
|
class URLField(TextField):
|
||||||
"A convenience FormField for validating URLs"
|
"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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isValidURL] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isValidURL(self, field_data, all_data):
|
def isValidURL(self, field_data, all_data):
|
||||||
@ -920,10 +924,10 @@ class URLField(TextField):
|
|||||||
raise validators.CriticalValidationError, e.messages
|
raise validators.CriticalValidationError, e.messages
|
||||||
|
|
||||||
class IPAddressField(TextField):
|
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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isValidIPAddress] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isValidIPAddress(self, field_data, all_data):
|
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):
|
def __init__(self, field_name, is_required=False, validator_list=None):
|
||||||
if validator_list is None: validator_list = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isValidPhone] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isValidPhone(self, field_data, all_data):
|
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):
|
def __init__(self, field_name, is_required=False, validator_list=None):
|
||||||
if validator_list is None: validator_list = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isValidUSState] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isValidUSState(self, field_data, all_data):
|
def isValidUSState(self, field_data, all_data):
|
||||||
@ -1001,10 +1005,10 @@ class USStateField(TextField):
|
|||||||
|
|
||||||
class CommaSeparatedIntegerField(TextField):
|
class CommaSeparatedIntegerField(TextField):
|
||||||
"A convenience FormField for validating comma-separated integer fields"
|
"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 = []
|
if validator_list is None: validator_list = []
|
||||||
validator_list = [self.isCommaSeparatedIntegerList] + 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)
|
is_required=is_required, validator_list=validator_list)
|
||||||
|
|
||||||
def isCommaSeparatedIntegerList(self, field_data, all_data):
|
def isCommaSeparatedIntegerList(self, field_data, all_data):
|
||||||
|
@ -649,8 +649,8 @@ def do_if(parser, token):
|
|||||||
As you can see, the ``if`` tag can take an option ``{% else %}`` clause that
|
As you can see, the ``if`` tag can take an option ``{% else %}`` clause that
|
||||||
will be displayed if the test fails.
|
will be displayed if the test fails.
|
||||||
|
|
||||||
``if`` tags may use ``or`` or ``not`` to test a number of variables or to
|
``if`` tags may use ``or``, ``and`` or ``not`` to test a number of
|
||||||
negate a given variable::
|
variables or to negate a given variable::
|
||||||
|
|
||||||
{% if not athlete_list %}
|
{% if not athlete_list %}
|
||||||
There are no athletes.
|
There are no athletes.
|
||||||
@ -660,19 +660,32 @@ def do_if(parser, token):
|
|||||||
There are some athletes or some coaches.
|
There are some athletes or some coaches.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if athlete_list and coach_list %}
|
||||||
|
Both atheletes and coaches are available.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if not athlete_list or coach_list %}
|
{% if not athlete_list or coach_list %}
|
||||||
There are no athletes, or there are some coaches.
|
There are no athletes, or there are some coaches.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
For simplicity, ``if`` tags do not allow ``and`` clauses. Use nested ``if``
|
{% if athlete_list and not coach_list %}
|
||||||
tags instead::
|
There are some athletes and absolutely no coaches.
|
||||||
|
|
||||||
{% if athlete_list %}
|
|
||||||
{% if coach_list %}
|
|
||||||
Number of athletes: {{ athlete_list|count }}.
|
|
||||||
Number of coaches: {{ coach_list|count }}.
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% 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()
|
bits = token.contents.split()
|
||||||
del bits[0]
|
del bits[0]
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import types
|
import types
|
||||||
import urllib
|
import urllib
|
||||||
from django.conf import settings
|
|
||||||
from django.utils.functional import Promise
|
from django.utils.functional import Promise
|
||||||
|
|
||||||
class StrAndUnicode(object):
|
class StrAndUnicode(object):
|
||||||
|
67
django/utils/maxlength.py
Normal file
67
django/utils/maxlength.py
Normal 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)
|
@ -214,7 +214,7 @@ A framework for generating syndication feeds, in RSS and Atom, quite easily.
|
|||||||
|
|
||||||
See the `syndication documentation`_.
|
See the `syndication documentation`_.
|
||||||
|
|
||||||
.. _syndication documentation: ../syndication/
|
.. _syndication documentation: ../syndication_feeds/
|
||||||
|
|
||||||
Other add-ons
|
Other add-ons
|
||||||
=============
|
=============
|
||||||
|
@ -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
|
That said, these APIs should *not* be considered stable, and are likely to
|
||||||
change:
|
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.
|
- `Serialization`_ is under heavy development; changes are likely.
|
||||||
|
|
||||||
- The `authentication`_ framework is changing to be far more flexible, and
|
- The `authentication`_ framework is changing to be far more flexible, and
|
||||||
@ -114,7 +111,7 @@ change:
|
|||||||
.. _sending email: ../email/
|
.. _sending email: ../email/
|
||||||
.. _sessions: ../sessions/
|
.. _sessions: ../sessions/
|
||||||
.. _settings: ../settings/
|
.. _settings: ../settings/
|
||||||
.. _syndication: ../syndication/
|
.. _syndication: ../syndication_feeds/
|
||||||
.. _template language: ../templates/
|
.. _template language: ../templates/
|
||||||
.. _transactions: ../transactions/
|
.. _transactions: ../transactions/
|
||||||
.. _url dispatch: ../url_dispatch/
|
.. _url dispatch: ../url_dispatch/
|
||||||
|
@ -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
|
Previous Django versions, such as 0.90, used simple MD5 hashes without password
|
||||||
salts. For backwards compatibility, those are still supported; they'll be
|
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.
|
works correctly for a given user.
|
||||||
|
|
||||||
Anonymous users
|
Anonymous users
|
||||||
|
@ -340,14 +340,14 @@ Model style
|
|||||||
Do this::
|
Do this::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=20)
|
first_name = models.CharField(max_length=20)
|
||||||
last_name = models.CharField(maxlength=40)
|
last_name = models.CharField(max_length=40)
|
||||||
|
|
||||||
Don't do this::
|
Don't do this::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
FirstName = models.CharField(maxlength=20)
|
FirstName = models.CharField(max_length=20)
|
||||||
Last_Name = models.CharField(maxlength=40)
|
Last_Name = models.CharField(max_length=40)
|
||||||
|
|
||||||
* The ``class Meta`` should appear *after* the fields are defined, with
|
* The ``class Meta`` should appear *after* the fields are defined, with
|
||||||
a single blank line separating the fields and the class definition.
|
a single blank line separating the fields and the class definition.
|
||||||
@ -355,8 +355,8 @@ Model style
|
|||||||
Do this::
|
Do this::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=20)
|
first_name = models.CharField(max_length=20)
|
||||||
last_name = models.CharField(maxlength=40)
|
last_name = models.CharField(max_length=40)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = 'people'
|
verbose_name_plural = 'people'
|
||||||
@ -364,8 +364,8 @@ Model style
|
|||||||
Don't do this::
|
Don't do this::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=20)
|
first_name = models.CharField(max_length=20)
|
||||||
last_name = models.CharField(maxlength=40)
|
last_name = models.CharField(max_length=40)
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = 'people'
|
verbose_name_plural = 'people'
|
||||||
|
|
||||||
@ -375,8 +375,8 @@ Model style
|
|||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = 'people'
|
verbose_name_plural = 'people'
|
||||||
|
|
||||||
first_name = models.CharField(maxlength=20)
|
first_name = models.CharField(max_length=20)
|
||||||
last_name = models.CharField(maxlength=40)
|
last_name = models.CharField(max_length=40)
|
||||||
|
|
||||||
* The order of model inner classes and standard methods should be as
|
* The order of model inner classes and standard methods should be as
|
||||||
follows (noting that these are not all required):
|
follows (noting that these are not all required):
|
||||||
|
@ -124,7 +124,7 @@ Several other MySQLdb connection options may be useful, such as ``ssl``,
|
|||||||
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
|
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
|
||||||
`MySQLdb documentation`_ for more details.
|
`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
|
.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
|
||||||
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/
|
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ Throughout this reference, we'll refer to the following models, which comprise
|
|||||||
a weblog application::
|
a weblog application::
|
||||||
|
|
||||||
class Blog(models.Model):
|
class Blog(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
tagline = models.TextField()
|
tagline = models.TextField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
@ -27,7 +27,7 @@ a weblog application::
|
|||||||
|
|
||||||
class Entry(models.Model):
|
class Entry(models.Model):
|
||||||
blog = models.ForeignKey(Blog)
|
blog = models.ForeignKey(Blog)
|
||||||
headline = models.CharField(maxlength=255)
|
headline = models.CharField(max_length=255)
|
||||||
body_text = models.TextField()
|
body_text = models.TextField()
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
authors = models.ManyToManyField(Author)
|
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.
|
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
|
Related objects
|
||||||
===============
|
===============
|
||||||
@ -1806,8 +1806,8 @@ following model::
|
|||||||
('F', 'Female'),
|
('F', 'Female'),
|
||||||
)
|
)
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
|
||||||
|
|
||||||
...each ``Person`` instance will have a ``get_gender_display()`` method. Example::
|
...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.
|
as a fallback check. This guarantees that no records are skipped or duplicated.
|
||||||
For a full example, see the `lookup API sample model`_.
|
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()
|
get_FOO_filename()
|
||||||
------------------
|
------------------
|
||||||
|
@ -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'
|
subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
|
||||||
text_content = 'This is an important message.'
|
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 = EmailMultiAlternatives(subject, text_content, from_email, to)
|
||||||
msg.attach_alternative(html_content, "text/html")
|
msg.attach_alternative(html_content, "text/html")
|
||||||
msg.send()
|
msg.send()
|
||||||
|
@ -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.
|
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
|
.. _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?
|
Is Django stable?
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -37,11 +37,11 @@ this document, we'll be working with the following model, a "place" object::
|
|||||||
)
|
)
|
||||||
|
|
||||||
class Place(models.Model):
|
class Place(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
address = models.CharField(maxlength=100, blank=True)
|
address = models.CharField(max_length=100, blank=True)
|
||||||
city = models.CharField(maxlength=50, blank=True)
|
city = models.CharField(max_length=50, blank=True)
|
||||||
state = models.USStateField()
|
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)
|
place_type = models.IntegerField(choices=PLACE_TYPES)
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
@ -388,7 +388,7 @@ for a "contact" form on a website::
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.fields = (
|
self.fields = (
|
||||||
forms.EmailField(field_name="from", is_required=True),
|
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.SelectField(field_name="urgency", choices=urgency_choices),
|
||||||
forms.LargeTextField(field_name="contents", is_required=True),
|
forms.LargeTextField(field_name="contents", is_required=True),
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,7 @@ A companion to this document is the `official repository of model examples`_.
|
|||||||
``tests/modeltests`` directory.)
|
``tests/modeltests`` directory.)
|
||||||
|
|
||||||
.. _Database API reference: ../db-api/
|
.. _Database API reference: ../db-api/
|
||||||
.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
|
.. _official repository of model examples: ../models/
|
||||||
|
|
||||||
Quick example
|
Quick example
|
||||||
=============
|
=============
|
||||||
@ -33,8 +33,8 @@ This example model defines a ``Person``, which has a ``first_name`` and
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
|
|
||||||
``first_name`` and ``last_name`` are *fields* of the model. Each field is
|
``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.
|
specified as a class attribute, and each attribute maps to a database column.
|
||||||
@ -69,13 +69,13 @@ attributes.
|
|||||||
Example::
|
Example::
|
||||||
|
|
||||||
class Musician(models.Model):
|
class Musician(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
last_name = models.CharField(maxlength=50)
|
last_name = models.CharField(max_length=50)
|
||||||
instrument = models.CharField(maxlength=100)
|
instrument = models.CharField(max_length=100)
|
||||||
|
|
||||||
class Album(models.Model):
|
class Album(models.Model):
|
||||||
artist = models.ForeignKey(Musician)
|
artist = models.ForeignKey(Musician)
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
release_date = models.DateField()
|
release_date = models.DateField()
|
||||||
num_stars = models.IntegerField()
|
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).
|
The admin represents this as an ``<input type="text">`` (a single-line input).
|
||||||
|
|
||||||
``CharField`` has an extra required argument, ``maxlength``, the maximum length
|
``CharField`` has an extra required argument, ``max_length``, the maximum length
|
||||||
(in characters) of the field. The maxlength is enforced at the database level
|
(in characters) of the field. The max_length is enforced at the database level
|
||||||
and in Django's validation.
|
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.
|
argument is required.
|
||||||
|
|
||||||
``DateField``
|
``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.
|
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.
|
75.
|
||||||
|
|
||||||
``FileField``
|
``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
|
containing only letters, numbers, underscores or hyphens. They're generally
|
||||||
used in URLs.
|
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.
|
not specified, Django will use a default length of 50.
|
||||||
|
|
||||||
Implies ``db_index=True``.
|
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).
|
The admin represents this as an ``<input type="text">`` (a single-line input).
|
||||||
|
|
||||||
``URLField`` takes an optional argument, ``maxlength``, the maximum length (in
|
``URLField`` takes an optional argument, ``max_length``, the maximum length (in
|
||||||
characters) of the field. The maxlength is enforced at the database level and
|
characters) of the field. The maximum length is enforced at the database level and
|
||||||
in Django's validation. If you don't specify ``maxlength``, a default of 200
|
in Django's validation. If you don't specify ``max_length``, a default of 200
|
||||||
is used.
|
is used.
|
||||||
|
|
||||||
``USStateField``
|
``USStateField``
|
||||||
@ -536,7 +540,7 @@ The choices list can be defined either as part of your model class::
|
|||||||
('M', 'Male'),
|
('M', 'Male'),
|
||||||
('F', 'Female'),
|
('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::
|
or outside your model class altogether::
|
||||||
|
|
||||||
@ -545,7 +549,7 @@ or outside your model class altogether::
|
|||||||
('F', 'Female'),
|
('F', 'Female'),
|
||||||
)
|
)
|
||||||
class Foo(models.Model):
|
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
|
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
|
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
|
form. It's useful for documentation even if your object doesn't have an
|
||||||
admin form.
|
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``
|
``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"``::
|
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"``::
|
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
|
``ForeignKey``, ``ManyToManyField`` and ``OneToOneField`` require the first
|
||||||
argument to be a model class, so use the ``verbose_name`` keyword argument::
|
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.
|
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
|
``ForeignKey`` fields take a number of extra arguments for defining how the
|
||||||
relationship should work. All are optional:
|
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.
|
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
|
``ManyToManyField`` objects take a number of extra arguments for defining how
|
||||||
the relationship should work. All are optional:
|
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.
|
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
|
Custom field types
|
||||||
------------------
|
------------------
|
||||||
@ -1027,8 +1037,8 @@ Once you have ``MytypeField``, you can use it in any model, just like any other
|
|||||||
``Field`` type::
|
``Field`` type::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(maxlength=80)
|
name = models.CharField(max_length=80)
|
||||||
gender = models.CharField(maxlength=1)
|
gender = models.CharField(max_length=1)
|
||||||
something_else = MytypeField()
|
something_else = MytypeField()
|
||||||
|
|
||||||
If you aim to build a database-agnostic application, you should account for
|
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.
|
# This is a much more flexible example.
|
||||||
class BetterCharField(models.Field):
|
class BetterCharField(models.Field):
|
||||||
def __init__(self, maxlength, *args, **kwargs):
|
def __init__(self, max_length, *args, **kwargs):
|
||||||
self.maxlength = maxlength
|
self.max_length = max_length
|
||||||
super(BetterCharField, self).__init__(*args, **kwargs)
|
super(BetterCharField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def db_type(self):
|
def db_type(self):
|
||||||
return 'char(%s)' % self.maxlength
|
return 'char(%s)' % self.max_length
|
||||||
|
|
||||||
# In the model:
|
# In the model:
|
||||||
class MyModel(models.Model):
|
class MyModel(models.Model):
|
||||||
@ -1096,7 +1106,7 @@ Meta options
|
|||||||
Give your model metadata by using an inner ``class Meta``, like so::
|
Give your model metadata by using an inner ``class Meta``, like so::
|
||||||
|
|
||||||
class Foo(models.Model):
|
class Foo(models.Model):
|
||||||
bar = models.CharField(maxlength=30)
|
bar = models.CharField(max_length=30)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
# ...
|
# ...
|
||||||
@ -1186,7 +1196,7 @@ See `Specifying ordering`_ for more examples.
|
|||||||
Note that, regardless of how many fields are in ``ordering``, the admin
|
Note that, regardless of how many fields are in ``ordering``, the admin
|
||||||
site uses only the first field.
|
site uses only the first field.
|
||||||
|
|
||||||
.. _Specifying ordering: http://www.djangoproject.com/documentation/models/ordering/
|
.. _Specifying ordering: ../models/ordering/
|
||||||
|
|
||||||
``permissions``
|
``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::
|
inner ``"class Admin"``, like so::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
# Admin options go here
|
# Admin options go here
|
||||||
@ -1430,7 +1440,7 @@ A few special cases to note about ``list_display``:
|
|||||||
Here's a full example model::
|
Here's a full example model::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
birthday = models.DateField()
|
birthday = models.DateField()
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
@ -1447,9 +1457,9 @@ A few special cases to note about ``list_display``:
|
|||||||
Here's a full example model::
|
Here's a full example model::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
last_name = models.CharField(maxlength=50)
|
last_name = models.CharField(max_length=50)
|
||||||
color_code = models.CharField(maxlength=6)
|
color_code = models.CharField(max_length=6)
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
list_display = ('first_name', 'last_name', 'colored_name')
|
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::
|
Here's a full example model::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
birthday = models.DateField()
|
birthday = models.DateField()
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
@ -1493,8 +1503,8 @@ A few special cases to note about ``list_display``:
|
|||||||
For example::
|
For example::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
color_code = models.CharField(maxlength=6)
|
color_code = models.CharField(max_length=6)
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
list_display = ('first_name', 'colored_first_name')
|
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
|
return result_list
|
||||||
|
|
||||||
class OpinionPoll(models.Model):
|
class OpinionPoll(models.Model):
|
||||||
question = models.CharField(maxlength=200)
|
question = models.CharField(max_length=200)
|
||||||
poll_date = models.DateField()
|
poll_date = models.DateField()
|
||||||
objects = PollManager()
|
objects = PollManager()
|
||||||
|
|
||||||
class Response(models.Model):
|
class Response(models.Model):
|
||||||
poll = models.ForeignKey(Poll)
|
poll = models.ForeignKey(Poll)
|
||||||
person_name = models.CharField(maxlength=50)
|
person_name = models.CharField(max_length=50)
|
||||||
response = models.TextField()
|
response = models.TextField()
|
||||||
|
|
||||||
With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
|
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::
|
example, using this model::
|
||||||
|
|
||||||
class Book(models.Model):
|
class Book(models.Model):
|
||||||
title = models.CharField(maxlength=100)
|
title = models.CharField(max_length=100)
|
||||||
author = models.CharField(maxlength=50)
|
author = models.CharField(max_length=50)
|
||||||
|
|
||||||
...the statement ``Book.objects.all()`` will return all books in the database.
|
...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.
|
# Then hook it into the Book model explicitly.
|
||||||
class Book(models.Model):
|
class Book(models.Model):
|
||||||
title = models.CharField(maxlength=100)
|
title = models.CharField(max_length=100)
|
||||||
author = models.CharField(maxlength=50)
|
author = models.CharField(max_length=50)
|
||||||
|
|
||||||
objects = models.Manager() # The default manager.
|
objects = models.Manager() # The default manager.
|
||||||
dahl_objects = DahlBookManager() # The Dahl-specific manager.
|
dahl_objects = DahlBookManager() # The Dahl-specific manager.
|
||||||
@ -1819,9 +1829,9 @@ For example::
|
|||||||
return super(FemaleManager, self).get_query_set().filter(sex='F')
|
return super(FemaleManager, self).get_query_set().filter(sex='F')
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
last_name = models.CharField(maxlength=50)
|
last_name = models.CharField(max_length=50)
|
||||||
sex = models.CharField(maxlength=1, choices=(('M', 'Male'), ('F', 'Female')))
|
sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
|
||||||
people = models.Manager()
|
people = models.Manager()
|
||||||
men = MaleManager()
|
men = MaleManager()
|
||||||
women = FemaleManager()
|
women = FemaleManager()
|
||||||
@ -1851,11 +1861,11 @@ model.
|
|||||||
For example, this model has a few custom methods::
|
For example, this model has a few custom methods::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
last_name = models.CharField(maxlength=50)
|
last_name = models.CharField(max_length=50)
|
||||||
birth_date = models.DateField()
|
birth_date = models.DateField()
|
||||||
address = models.CharField(maxlength=100)
|
address = models.CharField(max_length=100)
|
||||||
city = models.CharField(maxlength=50)
|
city = models.CharField(max_length=50)
|
||||||
state = models.USStateField() # Yes, this is America-centric...
|
state = models.USStateField() # Yes, this is America-centric...
|
||||||
|
|
||||||
def baby_boomer_status(self):
|
def baby_boomer_status(self):
|
||||||
@ -1897,8 +1907,8 @@ Although this isn't required, it's strongly encouraged (see the description of
|
|||||||
For example::
|
For example::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
last_name = models.CharField(maxlength=50)
|
last_name = models.CharField(max_length=50)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# Note use of django.utils.encoding.smart_str() here because
|
# 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::
|
more simply as::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=50)
|
first_name = models.CharField(max_length=50)
|
||||||
last_name = models.CharField(maxlength=50)
|
last_name = models.CharField(max_length=50)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'%s %s' % (self.first_name, self.last_name)
|
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
|
link that will jump you directly to the object's public view, according to
|
||||||
``get_absolute_url()``.
|
``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
|
use ``get_absolute_url()`` as a convenience to reward people who've defined the
|
||||||
method.
|
method.
|
||||||
|
|
||||||
|
.. syndication feed framework: ../syndication_feeds/
|
||||||
|
|
||||||
It's good practice to use ``get_absolute_url()`` in templates, instead of
|
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::
|
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::
|
to happen whenever you save an object. For example::
|
||||||
|
|
||||||
class Blog(models.Model):
|
class Blog(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
tagline = models.TextField()
|
tagline = models.TextField()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -2067,7 +2079,7 @@ to happen whenever you save an object. For example::
|
|||||||
You can also prevent saving::
|
You can also prevent saving::
|
||||||
|
|
||||||
class Blog(models.Model):
|
class Blog(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
tagline = models.TextField()
|
tagline = models.TextField()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
@ -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,
|
The simplest way to display a form's HTML is to use the variable on its own,
|
||||||
like this::
|
like this::
|
||||||
|
|
||||||
<form method="post">
|
<form method="post" action="">
|
||||||
<table>{{ form }}</table>
|
<table>{{ form }}</table>
|
||||||
<input type="submit" />
|
<input type="submit" />
|
||||||
</form>
|
</form>
|
||||||
@ -653,7 +653,7 @@ class' ``__str__()`` method calls its ``as_table()`` method.
|
|||||||
|
|
||||||
The following is equivalent but a bit more explicit::
|
The following is equivalent but a bit more explicit::
|
||||||
|
|
||||||
<form method="post">
|
<form method="post" action="">
|
||||||
<table>{{ form.as_table }}</table>
|
<table>{{ form.as_table }}</table>
|
||||||
<input type="submit" />
|
<input type="submit" />
|
||||||
</form>
|
</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
|
The easiest way is to iterate over the form's fields, with
|
||||||
``{% for field in form %}``. For example::
|
``{% for field in form %}``. For example::
|
||||||
|
|
||||||
<form method="post">
|
<form method="post" action="">
|
||||||
<dl>
|
<dl>
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
<dt>{{ field.label }}</dt>
|
<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.
|
by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
<form method="post">
|
<form method="post" action="">
|
||||||
<ul class="myformclass">
|
<ul class="myformclass">
|
||||||
<li>{{ form.sender.label }} {{ form.sender }}</li>
|
<li>{{ form.sender.label }} {{ form.sender }}</li>
|
||||||
<li class="helptext">{{ form.sender.help_text }}</li>
|
<li class="helptext">{{ form.sender.help_text }}</li>
|
||||||
@ -710,6 +710,49 @@ For example::
|
|||||||
</ul>
|
</ul>
|
||||||
</form>
|
</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
|
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
|
If provided, these arguments ensure that the string is at most or at least the
|
||||||
given length.
|
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``
|
``IntegerField``
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -1222,7 +1313,7 @@ Custom form and field validation
|
|||||||
|
|
||||||
Form validation happens when the data is cleaned. If you want to customise
|
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
|
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()``
|
processing. These are normally executed when you call the ``is_valid()``
|
||||||
method on a form. There are other things that can trigger cleaning and
|
method on a form. There are other things that can trigger cleaning and
|
||||||
validation (accessing the ``errors`` attribute or calling ``full_clean()``
|
validation (accessing the ``errors`` attribute or calling ``full_clean()``
|
||||||
@ -1372,17 +1463,17 @@ the full list of conversions:
|
|||||||
``AutoField`` Not represented in the form
|
``AutoField`` Not represented in the form
|
||||||
``BooleanField`` ``BooleanField``
|
``BooleanField`` ``BooleanField``
|
||||||
``CharField`` ``CharField`` with ``max_length`` set to
|
``CharField`` ``CharField`` with ``max_length`` set to
|
||||||
the model field's ``maxlength``
|
the model field's ``max_length``
|
||||||
``CommaSeparatedIntegerField`` ``CharField``
|
``CommaSeparatedIntegerField`` ``CharField``
|
||||||
``DateField`` ``DateField``
|
``DateField`` ``DateField``
|
||||||
``DateTimeField`` ``DateTimeField``
|
``DateTimeField`` ``DateTimeField``
|
||||||
``DecimalField`` ``DecimalField``
|
``DecimalField`` ``DecimalField``
|
||||||
``EmailField`` ``EmailField``
|
``EmailField`` ``EmailField``
|
||||||
``FileField`` ``CharField``
|
``FileField`` ``FileField``
|
||||||
``FilePathField`` ``CharField``
|
``FilePathField`` ``CharField``
|
||||||
``FloatField`` ``FloatField``
|
``FloatField`` ``FloatField``
|
||||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
``ForeignKey`` ``ModelChoiceField`` (see below)
|
||||||
``ImageField`` ``CharField``
|
``ImageField`` ``ImageField``
|
||||||
``IntegerField`` ``IntegerField``
|
``IntegerField`` ``IntegerField``
|
||||||
``IPAddressField`` ``CharField``
|
``IPAddressField`` ``CharField``
|
||||||
``ManyToManyField`` ``ModelMultipleChoiceField`` (see
|
``ManyToManyField`` ``ModelMultipleChoiceField`` (see
|
||||||
@ -1452,15 +1543,15 @@ Consider this set of models::
|
|||||||
)
|
)
|
||||||
|
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
title = models.CharField(maxlength=3, choices=TITLE_CHOICES)
|
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
|
||||||
birth_date = models.DateField(blank=True, null=True)
|
birth_date = models.DateField(blank=True, null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Book(models.Model):
|
class Book(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
authors = models.ManyToManyField(Author)
|
authors = models.ManyToManyField(Author)
|
||||||
|
|
||||||
With these models, a call to ``form_for_model(Author)`` would return a ``Form``
|
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
|
model instance. This is useful if you want to do custom processing on the
|
||||||
object before saving it. ``commit`` is ``True`` by default.
|
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
|
Using an alternate base class
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -25,14 +25,14 @@ far, it's been solving two years' worth of database-schema problems. Here's a
|
|||||||
quick example::
|
quick example::
|
||||||
|
|
||||||
class Reporter(models.Model):
|
class Reporter(models.Model):
|
||||||
full_name = models.CharField(maxlength=70)
|
full_name = models.CharField(max_length=70)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.full_name
|
return self.full_name
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
headline = models.CharField(maxlength=200)
|
headline = models.CharField(max_length=200)
|
||||||
article = models.TextField()
|
article = models.TextField()
|
||||||
reporter = models.ForeignKey(Reporter)
|
reporter = models.ForeignKey(Reporter)
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ your model classes::
|
|||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
headline = models.CharField(maxlength=200)
|
headline = models.CharField(max_length=200)
|
||||||
article = models.TextField()
|
article = models.TextField()
|
||||||
reporter = models.ForeignKey(Reporter)
|
reporter = models.ForeignKey(Reporter)
|
||||||
class Admin: pass
|
class Admin: pass
|
||||||
@ -288,14 +288,16 @@ This has been only a quick overview of Django's functionality. Some more useful
|
|||||||
features:
|
features:
|
||||||
|
|
||||||
* A caching framework that integrates with memcached or other backends.
|
* 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.
|
writing a small Python class.
|
||||||
* More sexy automatically-generated admin features -- this overview barely
|
* More sexy automatically-generated admin features -- this overview barely
|
||||||
scratched the surface.
|
scratched the surface.
|
||||||
|
|
||||||
|
.. _syndication framework: ../syndication_feeds/
|
||||||
|
|
||||||
The next obvious steps are for you to `download Django`_, read `the tutorial`_
|
The next obvious steps are for you to `download Django`_, read `the tutorial`_
|
||||||
and join `the community`_. Thanks for your interest!
|
and join `the community`_. Thanks for your interest!
|
||||||
|
|
||||||
.. _download Django: http://www.djangoproject.com/download/
|
.. _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/
|
.. _the community: http://www.djangoproject.com/community/
|
||||||
|
@ -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
|
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.
|
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/
|
.. _Django website: http://www.djangoproject.com/
|
||||||
.. _FAQ: http://www.djangoproject.com/documentation/faq/
|
.. _FAQ: http://www.djangoproject.com/documentation/faq/
|
||||||
.. _django-users: http://groups.google.com/group/django-users
|
.. _django-users: http://groups.google.com/group/django-users
|
||||||
|
@ -297,7 +297,7 @@ In contrast to ``HttpRequest`` objects, which are created automatically by
|
|||||||
Django, ``HttpResponse`` objects are your responsibility. Each view you write
|
Django, ``HttpResponse`` objects are your responsibility. Each view you write
|
||||||
is responsible for instantiating, populating and returning an ``HttpResponse``.
|
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
|
Usage
|
||||||
-----
|
-----
|
||||||
|
@ -21,7 +21,7 @@ you express this information in Python code.
|
|||||||
It works much like Django's `syndication framework`_. To create a sitemap, just
|
It works much like Django's `syndication framework`_. To create a sitemap, just
|
||||||
write a ``Sitemap`` class and point to it in your URLconf_.
|
write a ``Sitemap`` class and point to it in your URLconf_.
|
||||||
|
|
||||||
.. _syndication framework: ../syndication/
|
.. _syndication framework: ../syndication_feeds/
|
||||||
.. _URLconf: ../url_dispatch/
|
.. _URLconf: ../url_dispatch/
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
@ -46,7 +46,7 @@ that's represented by a ``ManyToManyField`` in the ``Article`` model::
|
|||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=200)
|
headline = models.CharField(max_length=200)
|
||||||
# ...
|
# ...
|
||||||
sites = models.ManyToManyField(Site)
|
sites = models.ManyToManyField(Site)
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ like this::
|
|||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=200)
|
headline = models.CharField(max_length=200)
|
||||||
# ...
|
# ...
|
||||||
site = models.ForeignKey(Site)
|
site = models.ForeignKey(Site)
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ Use ``CurrentSiteManager`` by adding it to your model explicitly. For example::
|
|||||||
|
|
||||||
class Photo(models.Model):
|
class Photo(models.Model):
|
||||||
photo = models.FileField(upload_to='/home/photos')
|
photo = models.FileField(upload_to='/home/photos')
|
||||||
photographer_name = models.CharField(maxlength=100)
|
photographer_name = models.CharField(max_length=100)
|
||||||
pub_date = models.DateField()
|
pub_date = models.DateField()
|
||||||
site = models.ForeignKey(Site)
|
site = models.ForeignKey(Site)
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
@ -257,7 +257,7 @@ this::
|
|||||||
|
|
||||||
class Photo(models.Model):
|
class Photo(models.Model):
|
||||||
photo = models.FileField(upload_to='/home/photos')
|
photo = models.FileField(upload_to='/home/photos')
|
||||||
photographer_name = models.CharField(maxlength=100)
|
photographer_name = models.CharField(max_length=100)
|
||||||
pub_date = models.DateField()
|
pub_date = models.DateField()
|
||||||
publish_on = models.ForeignKey(Site)
|
publish_on = models.ForeignKey(Site)
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
@ -318,7 +318,7 @@ Here's how Django uses the sites framework:
|
|||||||
|
|
||||||
.. _redirects framework: ../redirects/
|
.. _redirects framework: ../redirects/
|
||||||
.. _flatpages framework: ../flatpages/
|
.. _flatpages framework: ../flatpages/
|
||||||
.. _syndication framework: ../syndication/
|
.. _syndication framework: ../syndication_feeds/
|
||||||
.. _authentication framework: ../authentication/
|
.. _authentication framework: ../authentication/
|
||||||
|
|
||||||
``RequestSite`` objects
|
``RequestSite`` objects
|
||||||
|
@ -79,8 +79,8 @@ For example::
|
|||||||
'The cat says "meow"'
|
'The cat says "meow"'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
sound = models.CharField(maxlength=20)
|
sound = models.CharField(max_length=20)
|
||||||
|
|
||||||
def speak(self):
|
def speak(self):
|
||||||
return 'The %s says "%s"' % (self.name, self.sound)
|
return 'The %s says "%s"' % (self.name, self.sound)
|
||||||
|
@ -251,12 +251,12 @@ These concepts are represented by simple Python classes. Edit the
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Poll(models.Model):
|
class Poll(models.Model):
|
||||||
question = models.CharField(maxlength=200)
|
question = models.CharField(max_length=200)
|
||||||
pub_date = models.DateTimeField('date published')
|
pub_date = models.DateTimeField('date published')
|
||||||
|
|
||||||
class Choice(models.Model):
|
class Choice(models.Model):
|
||||||
poll = models.ForeignKey(Poll)
|
poll = models.ForeignKey(Poll)
|
||||||
choice = models.CharField(maxlength=200)
|
choice = models.CharField(max_length=200)
|
||||||
votes = models.IntegerField()
|
votes = models.IntegerField()
|
||||||
|
|
||||||
The code is straightforward. Each model is represented by a class that
|
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.
|
machine-readable name will suffice as its human-readable name.
|
||||||
|
|
||||||
Some ``Field`` classes have required elements. ``CharField``, for example,
|
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.
|
schema, but in validation, as we'll soon see.
|
||||||
|
|
||||||
Finally, note a relationship is defined, using ``models.ForeignKey``. That tells
|
Finally, note a relationship is defined, using ``models.ForeignKey``. That tells
|
||||||
|
@ -240,7 +240,7 @@ default, provide enough fields for 3 Choices."
|
|||||||
|
|
||||||
Then change the other fields in ``Choice`` to give them ``core=True``::
|
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)
|
votes = models.IntegerField(core=True)
|
||||||
|
|
||||||
This tells Django: "When you edit a Choice on the Poll admin page, the 'choice'
|
This tells Django: "When you edit a Choice on the Poll admin page, the 'choice'
|
||||||
|
@ -356,7 +356,8 @@ Use the template system
|
|||||||
=======================
|
=======================
|
||||||
|
|
||||||
Back to the ``detail()`` view for our poll application. Given the context
|
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>
|
<h1>{{ poll.question }}</h1>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -8,8 +8,8 @@ application and will focus on simple form processing and cutting down our code.
|
|||||||
Write a simple form
|
Write a simple form
|
||||||
===================
|
===================
|
||||||
|
|
||||||
Let's update our poll detail template from the last tutorial, so that the
|
Let's update our poll detail template ("polls/detail.html") from the last
|
||||||
template contains an HTML ``<form>`` element::
|
tutorial, so that the template contains an HTML ``<form>`` element::
|
||||||
|
|
||||||
<h1>{{ poll.question }}</h1>
|
<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
|
a way to refer to its URL later on (see `naming URL patterns`_ for more on
|
||||||
named patterns).
|
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
|
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
|
``<app name>/<model name>_detail.html``. In our case, it'll use the template
|
||||||
|
@ -404,7 +404,7 @@ This technique is used in `generic views`_ and in the `syndication framework`_
|
|||||||
to pass metadata and options to views.
|
to pass metadata and options to views.
|
||||||
|
|
||||||
.. _generic views: ../generic_views/
|
.. _generic views: ../generic_views/
|
||||||
.. _syndication framework: ../syndication/
|
.. _syndication framework: ../syndication_feeds/
|
||||||
|
|
||||||
.. admonition:: Dealing with conflicts
|
.. admonition:: Dealing with conflicts
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ This is a basic model with only two non-primary-key fields.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Article(models.Model):
|
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()
|
pub_date = models.DateTimeField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -17,8 +17,8 @@ GENDER_CHOICES = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -18,8 +18,8 @@ ManyToMany field. This has no effect on the API for querying the database.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
first_name = models.CharField(maxlength=30, db_column='firstname')
|
first_name = models.CharField(max_length=30, db_column='firstname')
|
||||||
last_name = models.CharField(maxlength=30, db_column='last')
|
last_name = models.CharField(max_length=30, db_column='last')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'%s %s' % (self.first_name, self.last_name)
|
return u'%s %s' % (self.first_name, self.last_name)
|
||||||
@ -29,7 +29,7 @@ class Author(models.Model):
|
|||||||
ordering = ('last_name','first_name')
|
ordering = ('last_name','first_name')
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
authors = models.ManyToManyField(Author, db_table='my_m2m_table')
|
authors = models.ManyToManyField(Author, db_table='my_m2m_table')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -18,8 +18,8 @@ class PersonManager(models.Manager):
|
|||||||
return self.filter(fun=True)
|
return self.filter(fun=True)
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
fun = models.BooleanField()
|
fun = models.BooleanField()
|
||||||
objects = PersonManager()
|
objects = PersonManager()
|
||||||
|
|
||||||
@ -33,8 +33,8 @@ class PublishedBookManager(models.Manager):
|
|||||||
return super(PublishedBookManager, self).get_query_set().filter(is_published=True)
|
return super(PublishedBookManager, self).get_query_set().filter(is_published=True)
|
||||||
|
|
||||||
class Book(models.Model):
|
class Book(models.Model):
|
||||||
title = models.CharField(maxlength=50)
|
title = models.CharField(max_length=50)
|
||||||
author = models.CharField(maxlength=30)
|
author = models.CharField(max_length=30)
|
||||||
is_published = models.BooleanField()
|
is_published = models.BooleanField()
|
||||||
published_objects = PublishedBookManager()
|
published_objects = PublishedBookManager()
|
||||||
authors = models.ManyToManyField(Person, related_name='books')
|
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)
|
return super(FastCarManager, self).get_query_set().filter(top_speed__gt=150)
|
||||||
|
|
||||||
class Car(models.Model):
|
class Car(models.Model):
|
||||||
name = models.CharField(maxlength=10)
|
name = models.CharField(max_length=10)
|
||||||
mileage = models.IntegerField()
|
mileage = models.IntegerField()
|
||||||
top_speed = models.IntegerField(help_text="In miles per hour.")
|
top_speed = models.IntegerField(help_text="In miles per hour.")
|
||||||
cars = models.Manager()
|
cars = models.Manager()
|
||||||
|
@ -8,7 +8,7 @@ from django.db import models
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateField()
|
pub_date = models.DateField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -8,10 +8,10 @@ this behavior by explicitly adding ``primary_key=True`` to a field.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Employee(models.Model):
|
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')
|
db_column = 'code')
|
||||||
first_name = models.CharField(maxlength=20)
|
first_name = models.CharField(max_length=20)
|
||||||
last_name = models.CharField(maxlength=20)
|
last_name = models.CharField(max_length=20)
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('last_name', 'first_name')
|
ordering = ('last_name', 'first_name')
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ class Employee(models.Model):
|
|||||||
return u"%s %s" % (self.first_name, self.last_name)
|
return u"%s %s" % (self.first_name, self.last_name)
|
||||||
|
|
||||||
class Business(models.Model):
|
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)
|
employees = models.ManyToManyField(Employee)
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = 'businesses'
|
verbose_name_plural = 'businesses'
|
||||||
|
@ -13,7 +13,7 @@ from django.db import models
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
class Article(models.Model):
|
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)
|
pub_date = models.DateTimeField(default=datetime.now)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -11,7 +11,7 @@ FIXTURE_DIRS setting.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Article(models.Model):
|
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()
|
pub_date = models.DateTimeField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -28,8 +28,8 @@ class TaggedItem(models.Model):
|
|||||||
return self.tag
|
return self.tag
|
||||||
|
|
||||||
class Animal(models.Model):
|
class Animal(models.Model):
|
||||||
common_name = models.CharField(maxlength=150)
|
common_name = models.CharField(max_length=150)
|
||||||
latin_name = models.CharField(maxlength=150)
|
latin_name = models.CharField(max_length=150)
|
||||||
|
|
||||||
tags = generic.GenericRelation(TaggedItem)
|
tags = generic.GenericRelation(TaggedItem)
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ class Animal(models.Model):
|
|||||||
return self.common_name
|
return self.common_name
|
||||||
|
|
||||||
class Vegetable(models.Model):
|
class Vegetable(models.Model):
|
||||||
name = models.CharField(maxlength=150)
|
name = models.CharField(max_length=150)
|
||||||
is_yucky = models.BooleanField(default=True)
|
is_yucky = models.BooleanField(default=True)
|
||||||
|
|
||||||
tags = generic.GenericRelation(TaggedItem)
|
tags = generic.GenericRelation(TaggedItem)
|
||||||
@ -46,7 +46,7 @@ class Vegetable(models.Model):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Mineral(models.Model):
|
class Mineral(models.Model):
|
||||||
name = models.CharField(maxlength=150)
|
name = models.CharField(max_length=150)
|
||||||
hardness = models.PositiveSmallIntegerField()
|
hardness = models.PositiveSmallIntegerField()
|
||||||
|
|
||||||
# note the lack of an explicit GenericRelation here...
|
# note the lack of an explicit GenericRelation here...
|
||||||
|
@ -11,7 +11,7 @@ into the future."
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateField()
|
pub_date = models.DateField()
|
||||||
expire_date = models.DateField()
|
expire_date = models.DateField()
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -21,7 +21,7 @@ class Article(models.Model):
|
|||||||
return self.headline
|
return self.headline
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(maxlength=30)
|
name = models.CharField(max_length=30)
|
||||||
birthday = models.DateField()
|
birthday = models.DateField()
|
||||||
|
|
||||||
# Note that this model doesn't have "get_latest_by" set.
|
# Note that this model doesn't have "get_latest_by" set.
|
||||||
|
@ -15,7 +15,7 @@ from django.http import Http404
|
|||||||
from django.shortcuts import get_object_or_404, get_list_or_404
|
from django.shortcuts import get_object_or_404, get_list_or_404
|
||||||
|
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -26,7 +26,7 @@ class ArticleManager(models.Manager):
|
|||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
authors = models.ManyToManyField(Author)
|
authors = models.ManyToManyField(Author)
|
||||||
title = models.CharField(maxlength=50)
|
title = models.CharField(max_length=50)
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
by_a_sir = ArticleManager()
|
by_a_sir = ArticleManager()
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ parameters. If an object isn't found, it creates one with the given parameters.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=100)
|
first_name = models.CharField(max_length=100)
|
||||||
last_name = models.CharField(maxlength=100)
|
last_name = models.CharField(max_length=100)
|
||||||
birthday = models.DateField()
|
birthday = models.DateField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -10,26 +10,26 @@ class FieldErrors(models.Model):
|
|||||||
charfield = models.CharField()
|
charfield = models.CharField()
|
||||||
decimalfield = models.DecimalField()
|
decimalfield = models.DecimalField()
|
||||||
filefield = models.FileField()
|
filefield = models.FileField()
|
||||||
prepopulate = models.CharField(maxlength=10, prepopulate_from='bad')
|
prepopulate = models.CharField(max_length=10, prepopulate_from='bad')
|
||||||
choices = models.CharField(maxlength=10, choices='bad')
|
choices = models.CharField(max_length=10, choices='bad')
|
||||||
choices2 = models.CharField(maxlength=10, choices=[(1,2,3),(1,2,3)])
|
choices2 = models.CharField(max_length=10, choices=[(1,2,3),(1,2,3)])
|
||||||
index = models.CharField(maxlength=10, db_index='bad')
|
index = models.CharField(max_length=10, db_index='bad')
|
||||||
|
|
||||||
class Target(models.Model):
|
class Target(models.Model):
|
||||||
tgt_safe = models.CharField(maxlength=10)
|
tgt_safe = models.CharField(max_length=10)
|
||||||
clash1 = models.CharField(maxlength=10)
|
clash1 = models.CharField(max_length=10)
|
||||||
clash2 = models.CharField(maxlength=10)
|
clash2 = models.CharField(max_length=10)
|
||||||
|
|
||||||
clash1_set = models.CharField(maxlength=10)
|
clash1_set = models.CharField(max_length=10)
|
||||||
|
|
||||||
class Clash1(models.Model):
|
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)
|
foreign = models.ForeignKey(Target)
|
||||||
m2m = models.ManyToManyField(Target)
|
m2m = models.ManyToManyField(Target)
|
||||||
|
|
||||||
class Clash2(models.Model):
|
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_1 = models.ForeignKey(Target, related_name='id')
|
||||||
foreign_2 = models.ForeignKey(Target, related_name='src_safe')
|
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')
|
m2m_2 = models.ManyToManyField(Target, related_name='src_safe')
|
||||||
|
|
||||||
class Target2(models.Model):
|
class Target2(models.Model):
|
||||||
clash3 = models.CharField(maxlength=10)
|
clash3 = models.CharField(max_length=10)
|
||||||
foreign_tgt = models.ForeignKey(Target)
|
foreign_tgt = models.ForeignKey(Target)
|
||||||
clashforeign_set = models.ForeignKey(Target)
|
clashforeign_set = models.ForeignKey(Target)
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class Target2(models.Model):
|
|||||||
clashm2m_set = models.ManyToManyField(Target)
|
clashm2m_set = models.ManyToManyField(Target)
|
||||||
|
|
||||||
class Clash3(models.Model):
|
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_1 = models.ForeignKey(Target2, related_name='foreign_tgt')
|
||||||
foreign_2 = models.ForeignKey(Target2, related_name='m2m_tgt')
|
foreign_2 = models.ForeignKey(Target2, related_name='m2m_tgt')
|
||||||
@ -61,16 +61,16 @@ class ClashM2M(models.Model):
|
|||||||
m2m = models.ManyToManyField(Target2)
|
m2m = models.ManyToManyField(Target2)
|
||||||
|
|
||||||
class SelfClashForeign(models.Model):
|
class SelfClashForeign(models.Model):
|
||||||
src_safe = models.CharField(maxlength=10, core=True)
|
src_safe = models.CharField(max_length=10, core=True)
|
||||||
selfclashforeign = models.CharField(maxlength=10)
|
selfclashforeign = models.CharField(max_length=10)
|
||||||
|
|
||||||
selfclashforeign_set = models.ForeignKey("SelfClashForeign")
|
selfclashforeign_set = models.ForeignKey("SelfClashForeign")
|
||||||
foreign_1 = models.ForeignKey("SelfClashForeign", related_name='id')
|
foreign_1 = models.ForeignKey("SelfClashForeign", related_name='id')
|
||||||
foreign_2 = models.ForeignKey("SelfClashForeign", related_name='src_safe')
|
foreign_2 = models.ForeignKey("SelfClashForeign", related_name='src_safe')
|
||||||
|
|
||||||
class ValidM2M(models.Model):
|
class ValidM2M(models.Model):
|
||||||
src_safe = models.CharField(maxlength=10)
|
src_safe = models.CharField(max_length=10)
|
||||||
validm2m = models.CharField(maxlength=10)
|
validm2m = models.CharField(max_length=10)
|
||||||
|
|
||||||
# M2M fields are symmetrical by default. Symmetrical M2M fields
|
# M2M fields are symmetrical by default. Symmetrical M2M fields
|
||||||
# on self don't require a related accessor, so many potential
|
# on self don't require a related accessor, so many potential
|
||||||
@ -84,8 +84,8 @@ class ValidM2M(models.Model):
|
|||||||
m2m_4 = models.ManyToManyField('self')
|
m2m_4 = models.ManyToManyField('self')
|
||||||
|
|
||||||
class SelfClashM2M(models.Model):
|
class SelfClashM2M(models.Model):
|
||||||
src_safe = models.CharField(maxlength=10)
|
src_safe = models.CharField(max_length=10)
|
||||||
selfclashm2m = models.CharField(maxlength=10)
|
selfclashm2m = models.CharField(max_length=10)
|
||||||
|
|
||||||
# Non-symmetrical M2M fields _do_ have related accessors, so
|
# Non-symmetrical M2M fields _do_ have related accessors, so
|
||||||
# there is potential for clashes.
|
# there is potential for clashes.
|
||||||
@ -100,14 +100,14 @@ class SelfClashM2M(models.Model):
|
|||||||
class Model(models.Model):
|
class Model(models.Model):
|
||||||
"But it's valid to call a model Model."
|
"But it's valid to call a model Model."
|
||||||
year = models.PositiveIntegerField() #1960
|
year = models.PositiveIntegerField() #1960
|
||||||
make = models.CharField(maxlength=10) #Aston Martin
|
make = models.CharField(max_length=10) #Aston Martin
|
||||||
name = models.CharField(maxlength=10) #DB 4 GT
|
name = models.CharField(max_length=10) #DB 4 GT
|
||||||
|
|
||||||
class Car(models.Model):
|
class Car(models.Model):
|
||||||
colour = models.CharField(maxlength=5)
|
colour = models.CharField(max_length=5)
|
||||||
model = models.ForeignKey(Model)
|
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 "decimal_places" attribute.
|
||||||
invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
|
invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
|
||||||
invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute.
|
invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute.
|
||||||
|
@ -8,7 +8,7 @@ from django.db import models
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('-pub_date', 'headline')
|
ordering = ('-pub_date', 'headline')
|
||||||
|
@ -7,7 +7,7 @@ Make sure to set ``related_name`` if you use relationships to the same table.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class User(models.Model):
|
class User(models.Model):
|
||||||
username = models.CharField(maxlength=20)
|
username = models.CharField(max_length=20)
|
||||||
|
|
||||||
class Issue(models.Model):
|
class Issue(models.Model):
|
||||||
num = models.IntegerField()
|
num = models.IntegerField()
|
||||||
|
@ -13,14 +13,14 @@ writer").
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Reporter(models.Model):
|
class Reporter(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s" % (self.first_name, self.last_name)
|
return u"%s %s" % (self.first_name, self.last_name)
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateField()
|
pub_date = models.DateField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
@ -29,7 +29,7 @@ class Article(models.Model):
|
|||||||
class Writer(models.Model):
|
class Writer(models.Model):
|
||||||
reporter = models.ForeignKey(Reporter)
|
reporter = models.ForeignKey(Reporter)
|
||||||
article = models.ForeignKey(Article)
|
article = models.ForeignKey(Article)
|
||||||
position = models.CharField(maxlength=100)
|
position = models.CharField(max_length=100)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'%s (%s)' % (self.reporter, self.position)
|
return u'%s (%s)' % (self.reporter, self.position)
|
||||||
|
@ -10,7 +10,7 @@ Set ``related_name`` to designate what the reverse relationship is called.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ class Category(models.Model):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=50)
|
headline = models.CharField(max_length=50)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
primary_categories = models.ManyToManyField(Category, related_name='primary_article_set')
|
primary_categories = models.ManyToManyField(Category, related_name='primary_article_set')
|
||||||
secondary_categories = models.ManyToManyField(Category, related_name='secondary_article_set')
|
secondary_categories = models.ManyToManyField(Category, related_name='secondary_article_set')
|
||||||
|
@ -15,7 +15,7 @@ there will be a clash, and tests that symmetry is preserved where appropriate.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
friends = models.ManyToManyField('self')
|
friends = models.ManyToManyField('self')
|
||||||
idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers')
|
idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers')
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ Set ``related_name`` to designate what the reverse relationship is called.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Category(models.Model):
|
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')
|
parent = models.ForeignKey('self', null=True, related_name='child_set')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -10,7 +10,7 @@ Set ``related_name`` to designate what the reverse relationship is called.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Person(models.Model):
|
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')
|
mother = models.ForeignKey('self', null=True, related_name='mothers_child_set')
|
||||||
father = models.ForeignKey('self', null=True, related_name='fathers_child_set')
|
father = models.ForeignKey('self', null=True, related_name='fathers_child_set')
|
||||||
|
|
||||||
|
@ -7,14 +7,14 @@ Each model gets an AddManipulator and ChangeManipulator by default.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Musician(models.Model):
|
class Musician(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s" % (self.first_name, self.last_name)
|
return u"%s %s" % (self.first_name, self.last_name)
|
||||||
|
|
||||||
class Album(models.Model):
|
class Album(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
musician = models.ForeignKey(Musician)
|
musician = models.ForeignKey(Musician)
|
||||||
release_date = models.DateField(blank=True, null=True)
|
release_date = models.DateField(blank=True, null=True)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ and a publication has multiple articles.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Publication(models.Model):
|
class Publication(models.Model):
|
||||||
title = models.CharField(maxlength=30)
|
title = models.CharField(max_length=30)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.title
|
return self.title
|
||||||
@ -19,7 +19,7 @@ class Publication(models.Model):
|
|||||||
ordering = ('title',)
|
ordering = ('title',)
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
publications = models.ManyToManyField(Publication)
|
publications = models.ManyToManyField(Publication)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -7,15 +7,15 @@ To define a many-to-one relationship, use ``ForeignKey()`` .
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Reporter(models.Model):
|
class Reporter(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s" % (self.first_name, self.last_name)
|
return u"%s %s" % (self.first_name, self.last_name)
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateField()
|
pub_date = models.DateField()
|
||||||
reporter = models.ForeignKey(Reporter)
|
reporter = models.ForeignKey(Reporter)
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@ To define a many-to-one relationship that can have a null foreign key, use
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Reporter(models.Model):
|
class Reporter(models.Model):
|
||||||
name = models.CharField(maxlength=30)
|
name = models.CharField(max_length=30)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
reporter = models.ForeignKey(Reporter, null=True)
|
reporter = models.ForeignKey(Reporter, null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -31,20 +31,20 @@ ARTICLE_STATUS = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
url = models.CharField('The URL', maxlength=40)
|
url = models.CharField('The URL', max_length=40)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Writer(models.Model):
|
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):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=50)
|
headline = models.CharField(max_length=50)
|
||||||
pub_date = models.DateField()
|
pub_date = models.DateField()
|
||||||
created = models.DateField(editable=False)
|
created = models.DateField(editable=False)
|
||||||
writer = models.ForeignKey(Writer)
|
writer = models.ForeignKey(Writer)
|
||||||
@ -63,7 +63,7 @@ class Article(models.Model):
|
|||||||
|
|
||||||
class PhoneNumber(models.Model):
|
class PhoneNumber(models.Model):
|
||||||
phone = models.PhoneNumberField()
|
phone = models.PhoneNumberField()
|
||||||
description = models.CharField(maxlength=20)
|
description = models.CharField(max_length=20)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.phone
|
return self.phone
|
||||||
@ -332,6 +332,28 @@ Create a new article, with no categories, via the form.
|
|||||||
>>> new_art.categories.all()
|
>>> 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
|
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
|
the Category model, we can use save_instance() to apply its changes to an
|
||||||
existing Category instance.
|
existing Category instance.
|
||||||
|
@ -7,8 +7,8 @@ Model inheritance isn't yet supported.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Place(models.Model):
|
class Place(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
address = models.CharField(maxlength=80)
|
address = models.CharField(max_length=80)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s the place" % self.name
|
return u"%s the place" % self.name
|
||||||
|
@ -7,11 +7,11 @@ To define a many-to-one relationship, use ``ForeignKey()`` .
|
|||||||
from django.db.models import *
|
from django.db.models import *
|
||||||
|
|
||||||
class Parent(Model):
|
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")
|
bestchild = ForeignKey("Child", null=True, related_name="favoured_by")
|
||||||
|
|
||||||
class Child(Model):
|
class Child(Model):
|
||||||
name = CharField(maxlength=100)
|
name = CharField(max_length=100)
|
||||||
parent = ForeignKey(Parent)
|
parent = ForeignKey(Parent)
|
||||||
|
|
||||||
__test__ = {'API_TESTS':"""
|
__test__ = {'API_TESTS':"""
|
||||||
|
@ -9,8 +9,8 @@ In this example, a ``Place`` optionally can be a ``Restaurant``.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Place(models.Model):
|
class Place(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
address = models.CharField(maxlength=80)
|
address = models.CharField(max_length=80)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s the place" % self.name
|
return u"%s the place" % self.name
|
||||||
@ -25,18 +25,18 @@ class Restaurant(models.Model):
|
|||||||
|
|
||||||
class Waiter(models.Model):
|
class Waiter(models.Model):
|
||||||
restaurant = models.ForeignKey(Restaurant)
|
restaurant = models.ForeignKey(Restaurant)
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s the waiter at %s" % (self.name, self.restaurant)
|
return u"%s the waiter at %s" % (self.name, self.restaurant)
|
||||||
|
|
||||||
class ManualPrimaryKey(models.Model):
|
class ManualPrimaryKey(models.Model):
|
||||||
primary_key = models.CharField(maxlength=10, primary_key=True)
|
primary_key = models.CharField(max_length=10, primary_key=True)
|
||||||
name = models.CharField(maxlength = 50)
|
name = models.CharField(max_length = 50)
|
||||||
|
|
||||||
class RelatedModel(models.Model):
|
class RelatedModel(models.Model):
|
||||||
link = models.OneToOneField(ManualPrimaryKey)
|
link = models.OneToOneField(ManualPrimaryKey)
|
||||||
name = models.CharField(maxlength = 50)
|
name = models.CharField(max_length = 50)
|
||||||
|
|
||||||
__test__ = {'API_TESTS':"""
|
__test__ = {'API_TESTS':"""
|
||||||
# Create a couple of Places.
|
# Create a couple of Places.
|
||||||
|
@ -14,7 +14,7 @@ a get_sql method).
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=50)
|
headline = models.CharField(max_length=50)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -16,7 +16,7 @@ undefined -- not random, just undefined.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('-pub_date', 'headline')
|
ordering = ('-pub_date', 'headline')
|
||||||
|
@ -9,7 +9,7 @@ objects into easily readable pages.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Article(models.Model):
|
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()
|
pub_date = models.DateTimeField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -7,8 +7,8 @@ Use properties on models just like on any other Python object.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
|
|
||||||
def _get_full_name(self):
|
def _get_full_name(self):
|
||||||
return "%s %s" % (self.first_name, self.last_name)
|
return "%s %s" % (self.first_name, self.last_name)
|
||||||
|
@ -10,14 +10,14 @@ reserved-name usage.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Thing(models.Model):
|
class Thing(models.Model):
|
||||||
when = models.CharField(maxlength=1, primary_key=True)
|
when = models.CharField(max_length=1, primary_key=True)
|
||||||
join = models.CharField(maxlength=1)
|
join = models.CharField(max_length=1)
|
||||||
like = models.CharField(maxlength=1)
|
like = models.CharField(max_length=1)
|
||||||
drop = models.CharField(maxlength=1)
|
drop = models.CharField(max_length=1)
|
||||||
alter = models.CharField(maxlength=1)
|
alter = models.CharField(max_length=1)
|
||||||
having = models.CharField(maxlength=1)
|
having = models.CharField(max_length=1)
|
||||||
where = models.DateField(maxlength=1)
|
where = models.DateField(max_length=1)
|
||||||
has_hyphen = models.CharField(maxlength=1, db_column='has-hyphen')
|
has_hyphen = models.CharField(max_length=1, db_column='has-hyphen')
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'select'
|
db_table = 'select'
|
||||||
|
|
||||||
|
@ -7,20 +7,20 @@ This demonstrates the reverse lookup features of the database API.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class User(models.Model):
|
class User(models.Model):
|
||||||
name = models.CharField(maxlength=200)
|
name = models.CharField(max_length=200)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Poll(models.Model):
|
class Poll(models.Model):
|
||||||
question = models.CharField(maxlength=200)
|
question = models.CharField(max_length=200)
|
||||||
creator = models.ForeignKey(User)
|
creator = models.ForeignKey(User)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.question
|
return self.question
|
||||||
|
|
||||||
class Choice(models.Model):
|
class Choice(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
poll = models.ForeignKey(Poll, related_name="poll_choice")
|
poll = models.ForeignKey(Poll, related_name="poll_choice")
|
||||||
related_poll = models.ForeignKey(Poll, related_name="related_choice")
|
related_poll = models.ForeignKey(Poll, related_name="related_choice")
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ the methods.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(maxlength=20)
|
first_name = models.CharField(max_length=20)
|
||||||
last_name = models.CharField(maxlength=20)
|
last_name = models.CharField(max_length=20)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s" % (self.first_name, self.last_name)
|
return u"%s %s" % (self.first_name, self.last_name)
|
||||||
|
@ -12,48 +12,48 @@ from django.db import models
|
|||||||
# Who remembers high school biology?
|
# Who remembers high school biology?
|
||||||
|
|
||||||
class Domain(models.Model):
|
class Domain(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Kingdom(models.Model):
|
class Kingdom(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
domain = models.ForeignKey(Domain)
|
domain = models.ForeignKey(Domain)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Phylum(models.Model):
|
class Phylum(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
kingdom = models.ForeignKey(Kingdom)
|
kingdom = models.ForeignKey(Kingdom)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Klass(models.Model):
|
class Klass(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
phylum = models.ForeignKey(Phylum)
|
phylum = models.ForeignKey(Phylum)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Order(models.Model):
|
class Order(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
klass = models.ForeignKey(Klass)
|
klass = models.ForeignKey(Klass)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Family(models.Model):
|
class Family(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
order = models.ForeignKey(Order)
|
order = models.ForeignKey(Order)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Genus(models.Model):
|
class Genus(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
family = models.ForeignKey(Family)
|
family = models.ForeignKey(Family)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Species(models.Model):
|
class Species(models.Model):
|
||||||
name = models.CharField(maxlength=50)
|
name = models.CharField(max_length=50)
|
||||||
genus = models.ForeignKey(Genus)
|
genus = models.ForeignKey(Genus)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -8,7 +8,7 @@ to and from "flat" data (i.e. strings).
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
@ -17,7 +17,7 @@ class Category(models.Model):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
@ -27,7 +27,7 @@ class Author(models.Model):
|
|||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
author = models.ForeignKey(Author)
|
author = models.ForeignKey(Author)
|
||||||
headline = models.CharField(maxlength=50)
|
headline = models.CharField(max_length=50)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
categories = models.ManyToManyField(Category)
|
categories = models.ManyToManyField(Category)
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ if you prefer. You must be careful to encode the results correctly, though.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -26,7 +26,7 @@ class Article(models.Model):
|
|||||||
return self.headline
|
return self.headline
|
||||||
|
|
||||||
class InternationalArticle(models.Model):
|
class InternationalArticle(models.Model):
|
||||||
headline = models.CharField(maxlength=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -10,8 +10,8 @@ manually.
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Reporter(models.Model):
|
class Reporter(models.Model):
|
||||||
first_name = models.CharField(maxlength=30)
|
first_name = models.CharField(max_length=30)
|
||||||
last_name = models.CharField(maxlength=30)
|
last_name = models.CharField(max_length=30)
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -12,7 +12,7 @@ from django.db import models
|
|||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
is_child = models.BooleanField()
|
is_child = models.BooleanField()
|
||||||
name = models.CharField(maxlength=20)
|
name = models.CharField(max_length=20)
|
||||||
birthdate = models.DateField()
|
birthdate = models.DateField()
|
||||||
favorite_moment = models.DateTimeField()
|
favorite_moment = models.DateTimeField()
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
|
@ -2,7 +2,7 @@ import tempfile
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Photo(models.Model):
|
class Photo(models.Model):
|
||||||
title = models.CharField(maxlength=30)
|
title = models.CharField(max_length=30)
|
||||||
image = models.FileField(upload_to=tempfile.gettempdir())
|
image = models.FileField(upload_to=tempfile.gettempdir())
|
||||||
|
|
||||||
# Support code for the tests; this keeps track of how many times save() gets
|
# Support code for the tests; this keeps track of how many times save() gets
|
||||||
|
@ -7,7 +7,7 @@ from django.db import models
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
class Donut(models.Model):
|
class Donut(models.Model):
|
||||||
name = models.CharField(maxlength=100)
|
name = models.CharField(max_length=100)
|
||||||
is_frosted = models.BooleanField(default=False)
|
is_frosted = models.BooleanField(default=False)
|
||||||
has_sprinkles = models.NullBooleanField()
|
has_sprinkles = models.NullBooleanField()
|
||||||
baked_date = models.DateField(null=True)
|
baked_date = models.DateField(null=True)
|
||||||
|
@ -2,21 +2,21 @@ from django.db import models
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
class Animal(models.Model):
|
class Animal(models.Model):
|
||||||
name = models.CharField(maxlength=150)
|
name = models.CharField(max_length=150)
|
||||||
latin_name = models.CharField(maxlength=150)
|
latin_name = models.CharField(max_length=150)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.common_name
|
return self.common_name
|
||||||
|
|
||||||
class Plant(models.Model):
|
class Plant(models.Model):
|
||||||
name = models.CharField(maxlength=150)
|
name = models.CharField(max_length=150)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
# For testing when upper case letter in app name; regression for #4057
|
# For testing when upper case letter in app name; regression for #4057
|
||||||
db_table = "Fixtures_regress_plant"
|
db_table = "Fixtures_regress_plant"
|
||||||
|
|
||||||
class Stuff(models.Model):
|
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)
|
owner = models.ForeignKey(User, null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -173,27 +173,29 @@ u'<input type="hidden" class="special" value="foo@example.com" name="email" />'
|
|||||||
|
|
||||||
# FileInput Widget ############################################################
|
# 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 = FileInput()
|
||||||
>>> w.render('email', '')
|
>>> w.render('email', '')
|
||||||
u'<input type="file" name="email" />'
|
u'<input type="file" name="email" />'
|
||||||
>>> w.render('email', None)
|
>>> w.render('email', None)
|
||||||
u'<input type="file" name="email" />'
|
u'<input type="file" name="email" />'
|
||||||
>>> w.render('email', 'test@example.com')
|
>>> 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')
|
>>> w.render('email', 'some "quoted" & ampersanded value')
|
||||||
u'<input type="file" name="email" value="some "quoted" & ampersanded value" />'
|
u'<input type="file" name="email" />'
|
||||||
>>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
|
>>> 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:
|
You can also pass 'attrs' to the constructor:
|
||||||
>>> w = FileInput(attrs={'class': 'fun'})
|
>>> w = FileInput(attrs={'class': 'fun'})
|
||||||
>>> w.render('email', '')
|
>>> w.render('email', '')
|
||||||
u'<input type="file" class="fun" name="email" />'
|
u'<input type="file" class="fun" name="email" />'
|
||||||
>>> w.render('email', 'foo@example.com')
|
>>> 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'})
|
>>> 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 #############################################################
|
# Textarea Widget #############################################################
|
||||||
|
|
||||||
@ -1532,6 +1534,42 @@ Traceback (most recent call last):
|
|||||||
...
|
...
|
||||||
ValidationError: [u'Ensure this value has at most 15 characters (it has 20).']
|
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 ##################################################################
|
# URLField ##################################################################
|
||||||
|
|
||||||
>>> f = URLField()
|
>>> f = URLField()
|
||||||
@ -2573,7 +2611,7 @@ Instances of a dynamic Form do not persist fields from one Form instance to
|
|||||||
the next.
|
the next.
|
||||||
>>> class MyForm(Form):
|
>>> class MyForm(Form):
|
||||||
... def __init__(self, data=None, auto_id=False, field_list=[]):
|
... 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:
|
... for field in field_list:
|
||||||
... self.fields[field[0]] = field[1]
|
... self.fields[field[0]] = field[1]
|
||||||
>>> field_list = [('field1', CharField()), ('field2', CharField())]
|
>>> field_list = [('field1', CharField()), ('field2', CharField())]
|
||||||
@ -2591,7 +2629,7 @@ the next.
|
|||||||
... default_field_1 = CharField()
|
... default_field_1 = CharField()
|
||||||
... default_field_2 = CharField()
|
... default_field_2 = CharField()
|
||||||
... def __init__(self, data=None, auto_id=False, field_list=[]):
|
... 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:
|
... for field in field_list:
|
||||||
... self.fields[field[0]] = field[1]
|
... self.fields[field[0]] = field[1]
|
||||||
>>> field_list = [('field1', CharField()), ('field2', CharField())]
|
>>> 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>
|
<option value="3" selected="selected">No</option>
|
||||||
</select>
|
</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 #############################################
|
# Basic form processing in a view #############################################
|
||||||
|
|
||||||
>>> from django.template import Template, Context
|
>>> from django.template import Template, Context
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user