diff options
Diffstat (limited to 'django/forms')
-rw-r--r-- | django/forms/fields.py | 16 | ||||
-rw-r--r-- | django/forms/formsets.py | 18 | ||||
-rw-r--r-- | django/forms/models.py | 30 | ||||
-rw-r--r-- | django/forms/util.py | 1 |
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): |