summaryrefslogtreecommitdiff
path: root/django/forms
diff options
context:
space:
mode:
Diffstat (limited to 'django/forms')
-rw-r--r--django/forms/fields.py16
-rw-r--r--django/forms/formsets.py18
-rw-r--r--django/forms/models.py30
-rw-r--r--django/forms/util.py1
4 files changed, 40 insertions, 25 deletions
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 9df8955392..47ae5e11b2 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -7,6 +7,7 @@ import datetime
import os
import re
import time
+import urlparse
try:
from cStringIO import StringIO
except ImportError:
@@ -23,7 +24,7 @@ except NameError:
from sets import Set as set
from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import StrAndUnicode, smart_unicode, smart_str
+from django.utils.encoding import smart_unicode, smart_str
from util import ErrorList, ValidationError
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput
@@ -73,7 +74,10 @@ class Field(object):
if label is not None:
label = smart_unicode(label)
self.required, self.label, self.initial = required, label, initial
- self.help_text = smart_unicode(help_text or '')
+ if help_text is None:
+ self.help_text = u''
+ else:
+ self.help_text = smart_unicode(help_text)
widget = widget or self.widget
if isinstance(widget, type):
widget = widget()
@@ -503,6 +507,11 @@ class ImageField(FileField):
# but it must be called immediately after the constructor
trial_image = Image.open(file)
trial_image.verify()
+ except ImportError:
+ # Under PyPy, it is possible to import PIL. However, the underlying
+ # _imaging C module isn't available, so an ImportError will be
+ # raised. Catch and re-raise.
+ raise
except Exception: # Python Imaging Library doesn't recognize it as an image
raise ValidationError(self.error_messages['invalid_image'])
if hasattr(f, 'seek') and callable(f.seek):
@@ -534,6 +543,9 @@ class URLField(RegexField):
# If no URL scheme given, assume http://
if value and '://' not in value:
value = u'http://%s' % value
+ # If no URL path given, assume /
+ if value and not urlparse.urlsplit(value)[2]:
+ value += '/'
value = super(URLField, self).clean(value)
if value == u'':
return value
diff --git a/django/forms/formsets.py b/django/forms/formsets.py
index 1ae27bf58c..2f13bf5fed 100644
--- a/django/forms/formsets.py
+++ b/django/forms/formsets.py
@@ -2,7 +2,7 @@ from forms import Form
from django.utils.encoding import StrAndUnicode
from django.utils.safestring import mark_safe
from fields import IntegerField, BooleanField
-from widgets import Media, HiddenInput, TextInput
+from widgets import Media, HiddenInput
from util import ErrorList, ValidationError
__all__ = ('BaseFormSet', 'all_valid')
@@ -10,7 +10,6 @@ __all__ = ('BaseFormSet', 'all_valid')
# special field names
TOTAL_FORM_COUNT = 'TOTAL_FORMS'
INITIAL_FORM_COUNT = 'INITIAL_FORMS'
-MAX_FORM_COUNT = 'MAX_FORMS'
ORDERING_FIELD_NAME = 'ORDER'
DELETION_FIELD_NAME = 'DELETE'
@@ -23,7 +22,6 @@ class ManagementForm(Form):
def __init__(self, *args, **kwargs):
self.base_fields[TOTAL_FORM_COUNT] = IntegerField(widget=HiddenInput)
self.base_fields[INITIAL_FORM_COUNT] = IntegerField(widget=HiddenInput)
- self.base_fields[MAX_FORM_COUNT] = IntegerField(widget=HiddenInput)
super(ManagementForm, self).__init__(*args, **kwargs)
class BaseFormSet(StrAndUnicode):
@@ -47,23 +45,21 @@ class BaseFormSet(StrAndUnicode):
if self.management_form.is_valid():
self._total_form_count = self.management_form.cleaned_data[TOTAL_FORM_COUNT]
self._initial_form_count = self.management_form.cleaned_data[INITIAL_FORM_COUNT]
- self._max_form_count = self.management_form.cleaned_data[MAX_FORM_COUNT]
else:
raise ValidationError('ManagementForm data is missing or has been tampered with')
else:
if initial:
self._initial_form_count = len(initial)
- if self._initial_form_count > self._max_form_count and self._max_form_count > 0:
- self._initial_form_count = self._max_form_count
+ if self._initial_form_count > self.max_num and self.max_num > 0:
+ self._initial_form_count = self.max_num
self._total_form_count = self._initial_form_count + self.extra
else:
self._initial_form_count = 0
self._total_form_count = self.extra
- if self._total_form_count > self._max_form_count and self._max_form_count > 0:
- self._total_form_count = self._max_form_count
+ if self._total_form_count > self.max_num and self.max_num > 0:
+ self._total_form_count = self.max_num
initial = {TOTAL_FORM_COUNT: self._total_form_count,
- INITIAL_FORM_COUNT: self._initial_form_count,
- MAX_FORM_COUNT: self._max_form_count}
+ INITIAL_FORM_COUNT: self._initial_form_count}
self.management_form = ManagementForm(initial=initial, auto_id=self.auto_id, prefix=self.prefix)
# construct the forms in the formset
@@ -280,7 +276,7 @@ def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
"""Return a FormSet for the given form class."""
attrs = {'form': form, 'extra': extra,
'can_order': can_order, 'can_delete': can_delete,
- '_max_form_count': max_num}
+ 'max_num': max_num}
return type(form.__name__ + 'FormSet', (formset,), attrs)
def all_valid(formsets):
diff --git a/django/forms/models.py b/django/forms/models.py
index 43e2978ba8..1f807f2b42 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -8,7 +8,6 @@ from warnings import warn
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_unicode
from django.utils.datastructures import SortedDict
-from django.core.exceptions import ImproperlyConfigured
from util import ValidationError, ErrorList
from forms import BaseForm, get_declared_fields
@@ -260,8 +259,8 @@ class BaseModelForm(BaseForm):
# if initial was provided, it should override the values from instance
if initial is not None:
object_data.update(initial)
- BaseForm.__init__(self, data, files, auto_id, prefix, object_data,
- error_class, label_suffix, empty_permitted)
+ super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data,
+ error_class, label_suffix, empty_permitted)
def save(self, commit=True):
"""
@@ -306,8 +305,8 @@ class BaseModelFormSet(BaseFormSet):
queryset=None, **kwargs):
self.queryset = queryset
defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix}
- if self._max_form_count > 0:
- qs = self.get_queryset()[:self._max_form_count]
+ if self.max_num > 0:
+ qs = self.get_queryset()[:self.max_num]
else:
qs = self.get_queryset()
defaults['initial'] = [model_to_dict(obj) for obj in qs]
@@ -379,8 +378,9 @@ class BaseModelFormSet(BaseFormSet):
def add_fields(self, form, index):
"""Add a hidden field for the object's primary key."""
- self._pk_field_name = self.model._meta.pk.attname
- form.fields[self._pk_field_name] = IntegerField(required=False, widget=HiddenInput)
+ if self.model._meta.has_auto_field:
+ self._pk_field_name = self.model._meta.pk.attname
+ form.fields[self._pk_field_name] = IntegerField(required=False, widget=HiddenInput)
super(BaseModelFormSet, self).add_fields(form, index)
def modelformset_factory(model, form=ModelForm, formfield_callback=lambda f: f.formfield(),
@@ -402,13 +402,14 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=lambda f: f.f
class BaseInlineFormset(BaseModelFormSet):
"""A formset for child objects related to a parent."""
- def __init__(self, data=None, files=None, instance=None, save_as_new=False):
+ def __init__(self, data=None, files=None, instance=None,
+ save_as_new=False, prefix=None):
from django.db.models.fields.related import RelatedObject
self.instance = instance
self.save_as_new = save_as_new
# is there a better way to get the object descriptor?
self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
- super(BaseInlineFormset, self).__init__(data, files, prefix=self.rel_name)
+ super(BaseInlineFormset, self).__init__(data, files, prefix=prefix or self.rel_name)
def _construct_forms(self):
if self.save_as_new:
@@ -441,13 +442,20 @@ def _get_foreign_key(parent_model, model, fk_name=None):
fks_to_parent = [f for f in opts.fields if f.name == fk_name]
if len(fks_to_parent) == 1:
fk = fks_to_parent[0]
- if not isinstance(fk, ForeignKey) or fk.rel.to != parent_model:
+ if not isinstance(fk, ForeignKey) or \
+ (fk.rel.to != parent_model and
+ fk.rel.to not in parent_model._meta.parents.keys()):
raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model))
elif len(fks_to_parent) == 0:
raise Exception("%s has no field named '%s'" % (model, fk_name))
else:
# Try to discover what the ForeignKey from model to parent_model is
- fks_to_parent = [f for f in opts.fields if isinstance(f, ForeignKey) and f.rel.to == parent_model]
+ fks_to_parent = [
+ f for f in opts.fields
+ if isinstance(f, ForeignKey)
+ and (f.rel.to == parent_model
+ or f.rel.to in parent_model._meta.parents.keys())
+ ]
if len(fks_to_parent) == 1:
fk = fks_to_parent[0]
elif len(fks_to_parent) == 0:
diff --git a/django/forms/util.py b/django/forms/util.py
index b3edf41adf..3d80ad219f 100644
--- a/django/forms/util.py
+++ b/django/forms/util.py
@@ -1,6 +1,5 @@
from django.utils.html import escape
from django.utils.encoding import smart_unicode, StrAndUnicode, force_unicode
-from django.utils.functional import Promise
from django.utils.safestring import mark_safe
def flatatt(attrs):