Ticket #6631: 01-forms-options.diff
File 01-forms-options.diff, 8.6 KB (added by , 16 years ago) |
---|
-
django/forms/forms.py
=== modified file 'django/forms/forms.py'
3 3 """ 4 4 5 5 from copy import deepcopy 6 import re 6 7 7 8 from django.utils.html import conditional_escape 8 9 from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode 9 10 from django.utils.safestring import mark_safe 11 from django.utils.text import capfirst 10 12 11 13 from fields import FileField 12 14 from widgets import Media, TextInput, Textarea … … 24 26 25 27 class FormOptions(object): 26 28 def __init__(self, options=None): 29 # main options 27 30 self.fieldsets = getattr(options, 'fieldsets', None) 28 31 self.fields = getattr(options, 'fields', None) 29 32 self.exclude = getattr(options, 'exclude', None) 33 # other options 34 self.error_class = getattr(options, 'error_class', ErrorList) 35 self.error_row_class = getattr(options, 'error_row_class', 'error') 36 # self.error_row_class = getattr(options, 'error_row_class', None) # backward-compatible 37 self.hidden_row_class = getattr(options, 'hidden_row_class', 'hidden') 38 self.label_capfirst = getattr(options, 'label_capfirst', True) 39 # self.label_capfirst = getattr(options, 'label_capfirst', False) # backward-compatible 40 self.label_suffix = getattr(options, 'label_suffix', ':') 41 self.required_row_class = getattr(options, 'required_row_class', 'required') 42 # self.required_row_class = getattr(options, 'required_row_class', None) # backward-compatible 43 self.use_field_row_class = getattr(options, 'use_field_row_class', True) 44 # self.use_field_row_class = getattr(options, 'use_field_row_class', False) # backward-compatible 30 45 31 46 class FormMetaclass(type): 32 47 def __new__(cls, name, bases, attrs): … … 44 59 # information. Any improvements to the form API should be made to *this* 45 60 # class, not to the Form class. 46 61 def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 47 initial=None, error_class= ErrorList, label_suffix=':',62 initial=None, error_class=None, label_suffix=None, 48 63 empty_permitted=False): 49 64 self.is_bound = data is not None or files is not None 50 65 self.data = data or {} … … 52 67 self.auto_id = auto_id 53 68 self.prefix = prefix 54 69 self.initial = initial or {} 55 self.error_class = error_class 56 self.label_suffix = label_suffix 70 if not hasattr(self, '_meta'): 71 self._options = FormOptions 72 metaclassing.create_meta(self, {}) 73 if error_class is not None: 74 self.error_class = error_class 75 if label_suffix is not None: 76 self.label_suffix = label_suffix 57 77 self.empty_permitted = empty_permitted 58 78 self._errors = None # Stores the errors after clean() has been called. 59 79 self._changed_data = None … … 152 172 'help_text': self._help_text_html_output(bf, help_text_html), 153 173 'attrs': bf.row_attrs, 154 174 } 175 176 _field_row_class_re = re.compile(r'([a-z])([A-Z])') 177 def _field_row_class(self, field): 178 return (self._field_row_class_re.sub(r'\1-\2', field.__class__.__name__).lower() + 179 ' ' + self._field_row_class_re.sub(r'\1-\2', field.widget.__class__.__name__).lower()) 155 180 156 181 def _top_errors_html_output(self, top_errors, top_errors_html): 157 182 "Helper function for outputting HTML from a top errors. Used by _html_output." … … 182 207 183 208 def _hidden_fields_html_output(self, hidden_fields, hidden_fields_html): 184 209 "Helper function for outputting HTML from a hidden fields. Used by _html_output." 210 if self.hidden_row_class: 211 attrs = u' class="%s"' % self.hidden_row_class 212 else: 213 attrs = u'' 185 214 return hidden_fields_html % { 215 'attrs': attrs, 186 216 'hidden_fields': u''.join(hidden_fields), 187 217 } 188 218 … … 226 256 'fieldset_start_html': u'<fieldset%(attrs)s>\n%(legend_tag)s<table>', 227 257 'fieldset_end_html': u'</table>\n</fieldset>', 228 258 'legend_tag_html': u'<legend>%(legend)s</legend>\n', 229 'hidden_fields_html': u'<tr class="hidden"><td colspan="2">%(hidden_fields)s</td></tr>',259 'hidden_fields_html': u'<tr%(attrs)s><td colspan="2">%(hidden_fields)s</td></tr>', 230 260 } 231 261 return self._html_output(**kwargs) 232 262 … … 240 270 'fieldset_start_html': u'<fieldset%(attrs)s>\n%(legend_tag)s<ul>', 241 271 'fieldset_end_html': u'</ul>\n</fieldset>', 242 272 'legend_tag_html': u'<legend>%(legend)s</legend>\n', 243 'hidden_fields_html': u'<li class="hidden">%(hidden_fields)s</li>',273 'hidden_fields_html': u'<li%(attrs)s>%(hidden_fields)s</li>', 244 274 } 245 275 return self._html_output(**kwargs) 246 276 … … 254 284 'fieldset_start_html': u'<fieldset%(attrs)s>\n%(legend_tag)s', 255 285 'fieldset_end_html': u'</fieldset>', 256 286 'legend_tag_html': u'<legend>%(legend)s</legend>\n', 257 'hidden_fields_html': u'<p class="hidden">%(hidden_fields)s</p>',287 'hidden_fields_html': u'<p%(attrs)s>%(hidden_fields)s</p>', 258 288 } 259 289 return self._html_output(**kwargs) 260 290 … … 439 469 if self.field.label is None: 440 470 return pretty_name(self.name) 441 471 else: 442 return conditional_escape(force_unicode(self.field.label)) 472 label = conditional_escape(force_unicode(self.field.label)) 473 if self.form.label_capfirst: 474 label = capfirst(label) 475 return label 443 476 label = property(_label) 444 477 445 478 def _label_id(self): … … 459 492 460 493 def _row_attrs(self): 461 494 "Returns row attributes for this field as safe HTML." 462 return flatatt(self.widget.row_attrs) 495 attrs = self.widget.row_attrs.copy() 496 class_list = attrs.pop('class', '').split() 497 if self.form.error_row_class and self.errors: 498 class_list.append(self.form.error_row_class) 499 if self.form.required_row_class and self.required: 500 class_list.append(self.form.required_row_class) 501 if self.form.use_field_row_class: 502 class_list.append(self.form._field_row_class(self.field)) 503 if class_list: 504 attrs['class'] = u' '.join(class_list) 505 return flatatt(attrs) 463 506 row_attrs = property(_row_attrs) 464 507 465 508 def label_tag(self, contents=None, attrs=None): -
django/forms/metaclassing.py
=== modified file 'django/forms/metaclassing.py'
10 10 11 11 def create_meta(cls, attrs): 12 12 cls._meta = cls._options(getattr(cls, 'Meta', None)) 13 for name, attr in cls._meta.__dict__.items(): 14 if name not in ('fieldsets', 'fields', 'exclude'): 15 setattr(cls, name, attr) 13 16 14 17 def create_declared_fields(cls, attrs): 15 18 fields = [] … … 23 26 def create_model_fields(cls, attrs): 24 27 formfield_callback = attrs.pop('formfield_callback', lambda f: f.formfield()) 25 28 fields = [] 26 if cls. _meta.model:27 for dbfield in cls. _meta.model._meta.fields + cls._meta.model._meta.many_to_many:29 if cls.model: 30 for dbfield in cls.model._meta.fields + cls.model._meta.many_to_many: 28 31 if dbfield.editable: 29 32 formfield = formfield_callback(dbfield) 30 33 if formfield: … … 45 48 for base in cls.__mro__[::-1]: 46 49 try: 47 50 declared_fields += base.declared_fields.items() 48 if base. _meta.model:51 if base.model: 49 52 model_fields = base.model_fields.items() 50 53 except AttributeError: 51 54 pass -
django/forms/models.py
=== modified file 'django/forms/models.py'
9 9 from django.utils.encoding import smart_unicode 10 10 from django.utils.datastructures import SortedDict 11 11 12 from util import ValidationError , ErrorList12 from util import ValidationError 13 13 from forms import FormOptions, FormMetaclass, BaseForm 14 14 from fields import Field, ChoiceField, IntegerField, EMPTY_VALUES 15 15 from widgets import Select, SelectMultiple, HiddenInput, MultipleHiddenInput … … 224 224 225 225 class BaseModelForm(BaseForm): 226 226 def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 227 initial=None, error_class= ErrorList, label_suffix=':',227 initial=None, error_class=None, label_suffix=None, 228 228 empty_permitted=False, instance=None): 229 229 opts = self._meta 230 230 if instance is None: