diff options
Diffstat (limited to 'lib/python2.7/site-packages/django/forms/forms.py')
-rw-r--r-- | lib/python2.7/site-packages/django/forms/forms.py | 584 |
1 files changed, 0 insertions, 584 deletions
diff --git a/lib/python2.7/site-packages/django/forms/forms.py b/lib/python2.7/site-packages/django/forms/forms.py deleted file mode 100644 index 573215d..0000000 --- a/lib/python2.7/site-packages/django/forms/forms.py +++ /dev/null @@ -1,584 +0,0 @@ -""" -Form classes -""" - -from __future__ import absolute_import, unicode_literals - -import copy -import warnings - -from django.core.exceptions import ValidationError -from django.forms.fields import Field, FileField -from django.forms.util import flatatt, ErrorDict, ErrorList -from django.forms.widgets import Media, media_property, TextInput, Textarea -from django.utils.datastructures import SortedDict -from django.utils.html import conditional_escape, format_html -from django.utils.encoding import smart_text, force_text, python_2_unicode_compatible -from django.utils.safestring import mark_safe -from django.utils.translation import ugettext as _ -from django.utils import six - - -__all__ = ('BaseForm', 'Form') - -NON_FIELD_ERRORS = '__all__' - -def pretty_name(name): - """Converts 'first_name' to 'First name'""" - if not name: - return '' - return name.replace('_', ' ').capitalize() - -def get_declared_fields(bases, attrs, with_base_fields=True): - """ - Create a list of form field instances from the passed in 'attrs', plus any - similar fields on the base classes (in 'bases'). This is used by both the - Form and ModelForm metaclasses. - - If 'with_base_fields' is True, all fields from the bases are used. - Otherwise, only fields in the 'declared_fields' attribute on the bases are - used. The distinction is useful in ModelForm subclassing. - Also integrates any additional media definitions. - """ - fields = [(field_name, attrs.pop(field_name)) for field_name, obj in list(six.iteritems(attrs)) if isinstance(obj, Field)] - fields.sort(key=lambda x: x[1].creation_counter) - - # If this class is subclassing another Form, add that Form's fields. - # Note that we loop over the bases in *reverse*. This is necessary in - # order to preserve the correct order of fields. - if with_base_fields: - for base in bases[::-1]: - if hasattr(base, 'base_fields'): - fields = list(six.iteritems(base.base_fields)) + fields - else: - for base in bases[::-1]: - if hasattr(base, 'declared_fields'): - fields = list(six.iteritems(base.declared_fields)) + fields - - return SortedDict(fields) - -class DeclarativeFieldsMetaclass(type): - """ - Metaclass that converts Field attributes to a dictionary called - 'base_fields', taking into account parent class 'base_fields' as well. - """ - def __new__(cls, name, bases, attrs): - attrs['base_fields'] = get_declared_fields(bases, attrs) - new_class = super(DeclarativeFieldsMetaclass, - cls).__new__(cls, name, bases, attrs) - if 'media' not in attrs: - new_class.media = media_property(new_class) - return new_class - -@python_2_unicode_compatible -class BaseForm(object): - # This is the main implementation of all the Form logic. Note that this - # class is different than Form. See the comments by the Form class for more - # information. Any improvements to the form API should be made to *this* - # class, not to the Form class. - def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, - initial=None, error_class=ErrorList, label_suffix=None, - empty_permitted=False): - self.is_bound = data is not None or files is not None - self.data = data or {} - self.files = files or {} - self.auto_id = auto_id - self.prefix = prefix - self.initial = initial or {} - self.error_class = error_class - # Translators: This is the default suffix added to form field labels - self.label_suffix = label_suffix if label_suffix is not None else _(':') - self.empty_permitted = empty_permitted - self._errors = None # Stores the errors after clean() has been called. - self._changed_data = None - - # The base_fields class attribute is the *class-wide* definition of - # fields. Because a particular *instance* of the class might want to - # alter self.fields, we create self.fields here by copying base_fields. - # Instances should always modify self.fields; they should not modify - # self.base_fields. - self.fields = copy.deepcopy(self.base_fields) - - def __str__(self): - return self.as_table() - - def __iter__(self): - for name in self.fields: - yield self[name] - - def __getitem__(self, name): - "Returns a BoundField with the given name." - try: - field = self.fields[name] - except KeyError: - raise KeyError('Key %r not found in Form' % name) - return BoundField(self, field, name) - - @property - def errors(self): - "Returns an ErrorDict for the data provided for the form" - if self._errors is None: - self.full_clean() - return self._errors - - def is_valid(self): - """ - Returns True if the form has no errors. Otherwise, False. If errors are - being ignored, returns False. - """ - return self.is_bound and not bool(self.errors) - - def add_prefix(self, field_name): - """ - Returns the field name with a prefix appended, if this Form has a - prefix set. - - Subclasses may wish to override. - """ - return '%s-%s' % (self.prefix, field_name) if self.prefix else field_name - - def add_initial_prefix(self, field_name): - """ - Add a 'initial' prefix for checking dynamic initial values - """ - return 'initial-%s' % self.add_prefix(field_name) - - def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): - "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." - top_errors = self.non_field_errors() # Errors that should be displayed above all fields. - output, hidden_fields = [], [] - - for name, field in self.fields.items(): - html_class_attr = '' - bf = self[name] - # Escape and cache in local variable. - bf_errors = self.error_class([conditional_escape(error) for error in bf.errors]) - if bf.is_hidden: - if bf_errors: - top_errors.extend( - [_('(Hidden field %(name)s) %(error)s') % {'name': name, 'error': force_text(e)} - for e in bf_errors]) - hidden_fields.append(six.text_type(bf)) - else: - # Create a 'class="..."' atribute if the row should have any - # CSS classes applied. - css_classes = bf.css_classes() - if css_classes: - html_class_attr = ' class="%s"' % css_classes - - if errors_on_separate_row and bf_errors: - output.append(error_row % force_text(bf_errors)) - - if bf.label: - label = conditional_escape(force_text(bf.label)) - label = bf.label_tag(label) or '' - else: - label = '' - - if field.help_text: - help_text = help_text_html % force_text(field.help_text) - else: - help_text = '' - - output.append(normal_row % { - 'errors': force_text(bf_errors), - 'label': force_text(label), - 'field': six.text_type(bf), - 'help_text': help_text, - 'html_class_attr': html_class_attr - }) - - if top_errors: - output.insert(0, error_row % force_text(top_errors)) - - if hidden_fields: # Insert any hidden fields in the last row. - str_hidden = ''.join(hidden_fields) - if output: - last_row = output[-1] - # Chop off the trailing row_ender (e.g. '</td></tr>') and - # insert the hidden fields. - if not last_row.endswith(row_ender): - # This can happen in the as_p() case (and possibly others - # that users write): if there are only top errors, we may - # not be able to conscript the last row for our purposes, - # so insert a new, empty row. - last_row = (normal_row % {'errors': '', 'label': '', - 'field': '', 'help_text':'', - 'html_class_attr': html_class_attr}) - output.append(last_row) - output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender - else: - # If there aren't any rows in the output, just append the - # hidden fields. - output.append(str_hidden) - return mark_safe('\n'.join(output)) - - def as_table(self): - "Returns this form rendered as HTML <tr>s -- excluding the <table></table>." - return self._html_output( - normal_row = '<tr%(html_class_attr)s><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>', - error_row = '<tr><td colspan="2">%s</td></tr>', - row_ender = '</td></tr>', - help_text_html = '<br /><span class="helptext">%s</span>', - errors_on_separate_row = False) - - def as_ul(self): - "Returns this form rendered as HTML <li>s -- excluding the <ul></ul>." - return self._html_output( - normal_row = '<li%(html_class_attr)s>%(errors)s%(label)s %(field)s%(help_text)s</li>', - error_row = '<li>%s</li>', - row_ender = '</li>', - help_text_html = ' <span class="helptext">%s</span>', - errors_on_separate_row = False) - - def as_p(self): - "Returns this form rendered as HTML <p>s." - return self._html_output( - normal_row = '<p%(html_class_attr)s>%(label)s %(field)s%(help_text)s</p>', - error_row = '%s', - row_ender = '</p>', - help_text_html = ' <span class="helptext">%s</span>', - errors_on_separate_row = True) - - def non_field_errors(self): - """ - Returns an ErrorList of errors that aren't associated with a particular - field -- i.e., from Form.clean(). Returns an empty ErrorList if there - are none. - """ - return self.errors.get(NON_FIELD_ERRORS, self.error_class()) - - def _raw_value(self, fieldname): - """ - Returns the raw_value for a particular field name. This is just a - convenient wrapper around widget.value_from_datadict. - """ - field = self.fields[fieldname] - prefix = self.add_prefix(fieldname) - return field.widget.value_from_datadict(self.data, self.files, prefix) - - def full_clean(self): - """ - Cleans all of self.data and populates self._errors and - self.cleaned_data. - """ - self._errors = ErrorDict() - if not self.is_bound: # Stop further processing. - return - self.cleaned_data = {} - # If the form is permitted to be empty, and none of the form data has - # changed from the initial data, short circuit any validation. - if self.empty_permitted and not self.has_changed(): - return - self._clean_fields() - self._clean_form() - self._post_clean() - - def _clean_fields(self): - for name, field in self.fields.items(): - # value_from_datadict() gets the data from the data dictionaries. - # Each widget type knows how to retrieve its own data, because some - # widgets split data over several HTML fields. - value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) - try: - if isinstance(field, FileField): - initial = self.initial.get(name, field.initial) - value = field.clean(value, initial) - else: - value = field.clean(value) - self.cleaned_data[name] = value - if hasattr(self, 'clean_%s' % name): - value = getattr(self, 'clean_%s' % name)() - self.cleaned_data[name] = value - except ValidationError as e: - self._errors[name] = self.error_class(e.messages) - if name in self.cleaned_data: - del self.cleaned_data[name] - - def _clean_form(self): - try: - self.cleaned_data = self.clean() - except ValidationError as e: - self._errors[NON_FIELD_ERRORS] = self.error_class(e.messages) - - def _post_clean(self): - """ - An internal hook for performing additional cleaning after form cleaning - is complete. Used for model validation in model forms. - """ - pass - - def clean(self): - """ - Hook for doing any extra form-wide cleaning after Field.clean() been - called on every field. Any ValidationError raised by this method will - not be associated with a particular field; it will have a special-case - association with the field named '__all__'. - """ - return self.cleaned_data - - def has_changed(self): - """ - Returns True if data differs from initial. - """ - return bool(self.changed_data) - - @property - def changed_data(self): - if self._changed_data is None: - self._changed_data = [] - # XXX: For now we're asking the individual widgets whether or not the - # data has changed. It would probably be more efficient to hash the - # initial data, store it in a hidden field, and compare a hash of the - # submitted data, but we'd need a way to easily get the string value - # for a given field. Right now, that logic is embedded in the render - # method of each widget. - for name, field in self.fields.items(): - prefixed_name = self.add_prefix(name) - data_value = field.widget.value_from_datadict(self.data, self.files, prefixed_name) - if not field.show_hidden_initial: - initial_value = self.initial.get(name, field.initial) - if callable(initial_value): - initial_value = initial_value() - else: - initial_prefixed_name = self.add_initial_prefix(name) - hidden_widget = field.hidden_widget() - try: - initial_value = field.to_python(hidden_widget.value_from_datadict( - self.data, self.files, initial_prefixed_name)) - except ValidationError: - # Always assume data has changed if validation fails. - self._changed_data.append(name) - continue - if hasattr(field.widget, '_has_changed'): - warnings.warn("The _has_changed method on widgets is deprecated," - " define it at field level instead.", - PendingDeprecationWarning, stacklevel=2) - if field.widget._has_changed(initial_value, data_value): - self._changed_data.append(name) - elif field._has_changed(initial_value, data_value): - self._changed_data.append(name) - return self._changed_data - - @property - def media(self): - """ - Provide a description of all media required to render the widgets on this form - """ - media = Media() - for field in self.fields.values(): - media = media + field.widget.media - return media - - def is_multipart(self): - """ - Returns True if the form needs to be multipart-encoded, i.e. it has - FileInput. Otherwise, False. - """ - for field in self.fields.values(): - if field.widget.needs_multipart_form: - return True - return False - - def hidden_fields(self): - """ - Returns a list of all the BoundField objects that are hidden fields. - Useful for manual form layout in templates. - """ - return [field for field in self if field.is_hidden] - - def visible_fields(self): - """ - Returns a list of BoundField objects that aren't hidden fields. - The opposite of the hidden_fields() method. - """ - return [field for field in self if not field.is_hidden] - -class Form(six.with_metaclass(DeclarativeFieldsMetaclass, BaseForm)): - "A collection of Fields, plus their associated data." - # This is a separate class from BaseForm in order to abstract the way - # self.fields is specified. This class (Form) is the one that does the - # fancy metaclass stuff purely for the semantic sugar -- it allows one - # to define a form using declarative syntax. - # BaseForm itself has no way of designating self.fields. - -@python_2_unicode_compatible -class BoundField(object): - "A Field plus data" - def __init__(self, form, field, name): - self.form = form - self.field = field - self.name = name - self.html_name = form.add_prefix(name) - self.html_initial_name = form.add_initial_prefix(name) - self.html_initial_id = form.add_initial_prefix(self.auto_id) - if self.field.label is None: - self.label = pretty_name(name) - else: - self.label = self.field.label - self.help_text = field.help_text or '' - - def __str__(self): - """Renders this field as an HTML widget.""" - if self.field.show_hidden_initial: - return self.as_widget() + self.as_hidden(only_initial=True) - return self.as_widget() - - def __iter__(self): - """ - Yields rendered strings that comprise all widgets in this BoundField. - - This really is only useful for RadioSelect widgets, so that you can - iterate over individual radio buttons in a template. - """ - for subwidget in self.field.widget.subwidgets(self.html_name, self.value()): - yield subwidget - - def __len__(self): - return len(list(self.__iter__())) - - def __getitem__(self, idx): - return list(self.__iter__())[idx] - - @property - def errors(self): - """ - Returns an ErrorList for this field. Returns an empty ErrorList - if there are none. - """ - return self.form.errors.get(self.name, self.form.error_class()) - - def as_widget(self, widget=None, attrs=None, only_initial=False): - """ - Renders the field by rendering the passed widget, adding any HTML - attributes passed as attrs. If no widget is specified, then the - field's default widget will be used. - """ - if not widget: - widget = self.field.widget - - if self.field.localize: - widget.is_localized = True - - attrs = attrs or {} - auto_id = self.auto_id - if auto_id and 'id' not in attrs and 'id' not in widget.attrs: - if not only_initial: - attrs['id'] = auto_id - else: - attrs['id'] = self.html_initial_id - - if not only_initial: - name = self.html_name - else: - name = self.html_initial_name - return widget.render(name, self.value(), attrs=attrs) - - def as_text(self, attrs=None, **kwargs): - """ - Returns a string of HTML for representing this as an <input type="text">. - """ - return self.as_widget(TextInput(), attrs, **kwargs) - - def as_textarea(self, attrs=None, **kwargs): - "Returns a string of HTML for representing this as a <textarea>." - return self.as_widget(Textarea(), attrs, **kwargs) - - def as_hidden(self, attrs=None, **kwargs): - """ - Returns a string of HTML for representing this as an <input type="hidden">. - """ - return self.as_widget(self.field.hidden_widget(), attrs, **kwargs) - - @property - def data(self): - """ - Returns the data for this BoundField, or None if it wasn't given. - """ - return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name) - - def value(self): - """ - Returns the value for this BoundField, using the initial value if - the form is not bound or the data otherwise. - """ - if not self.form.is_bound: - data = self.form.initial.get(self.name, self.field.initial) - if callable(data): - data = data() - else: - data = self.field.bound_data( - self.data, self.form.initial.get(self.name, self.field.initial) - ) - return self.field.prepare_value(data) - - def label_tag(self, contents=None, attrs=None, label_suffix=None): - """ - Wraps the given contents in a <label>, if the field has an ID attribute. - contents should be 'mark_safe'd to avoid HTML escaping. If contents - aren't given, uses the field's HTML-escaped label. - - If attrs are given, they're used as HTML attributes on the <label> tag. - - label_suffix allows overriding the form's label_suffix. - """ - contents = contents or self.label - # Only add the suffix if the label does not end in punctuation. - label_suffix = label_suffix if label_suffix is not None else self.form.label_suffix - # Translators: If found as last label character, these punctuation - # characters will prevent the default label_suffix to be appended to the label - if label_suffix and contents and contents[-1] not in _(':?.!'): - contents = format_html('{0}{1}', contents, label_suffix) - widget = self.field.widget - id_ = widget.attrs.get('id') or self.auto_id - if id_: - id_for_label = widget.id_for_label(id_) - if id_for_label: - attrs = dict(attrs or {}, **{'for': id_for_label}) - attrs = flatatt(attrs) if attrs else '' - contents = format_html('<label{0}>{1}</label>', attrs, contents) - else: - contents = conditional_escape(contents) - return mark_safe(contents) - - def css_classes(self, extra_classes=None): - """ - Returns a string of space-separated CSS classes for this field. - """ - if hasattr(extra_classes, 'split'): - extra_classes = extra_classes.split() - extra_classes = set(extra_classes or []) - if self.errors and hasattr(self.form, 'error_css_class'): - extra_classes.add(self.form.error_css_class) - if self.field.required and hasattr(self.form, 'required_css_class'): - extra_classes.add(self.form.required_css_class) - return ' '.join(extra_classes) - - @property - def is_hidden(self): - "Returns True if this BoundField's widget is hidden." - return self.field.widget.is_hidden - - @property - def auto_id(self): - """ - Calculates and returns the ID attribute for this BoundField, if the - associated Form has specified auto_id. Returns an empty string otherwise. - """ - auto_id = self.form.auto_id - if auto_id and '%s' in smart_text(auto_id): - return smart_text(auto_id) % self.html_name - elif auto_id: - return self.html_name - return '' - - @property - def id_for_label(self): - """ - Wrapper around the field widget's `id_for_label` method. - Useful, for example, for focusing on this field regardless of whether - it has a single widget or a MultiWidget. - """ - widget = self.field.widget - id_ = widget.attrs.get('id') or self.auto_id - return widget.id_for_label(id_) |