Changeset 4189 for django/branches/multiple-db-support
- Timestamp:
- 12/10/06 09:43:51 (2 years ago)
- Files:
-
- django/branches/multiple-db-support/django/contrib/admin/templates/admin/search_form.html (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/admin/views/main.py (modified) (6 diffs)
- django/branches/multiple-db-support/django/contrib/contenttypes/management.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/contrib/formtools (copied) (copied from django/trunk/django/contrib/formtools)
- django/branches/multiple-db-support/django/contrib/formtools/__init__.py (copied) (copied from django/trunk/django/contrib/formtools/__init__.py)
- django/branches/multiple-db-support/django/contrib/formtools/preview.py (copied) (copied from django/trunk/django/contrib/formtools/preview.py)
- django/branches/multiple-db-support/django/contrib/formtools/templates (copied) (copied from django/trunk/django/contrib/formtools/templates)
- django/branches/multiple-db-support/django/contrib/formtools/templates/formtools (copied) (copied from django/trunk/django/contrib/formtools/templates/formtools)
- django/branches/multiple-db-support/django/contrib/formtools/templates/formtools/form.html (copied) (copied from django/trunk/django/contrib/formtools/templates/formtools/form.html)
- django/branches/multiple-db-support/django/contrib/formtools/templates/formtools/preview.html (copied) (copied from django/trunk/django/contrib/formtools/templates/formtools/preview.html)
- django/branches/multiple-db-support/django/contrib/sitemaps/__init__.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/servers/fastcgi.py (modified) (1 diff)
- django/branches/multiple-db-support/django/newforms/fields.py (modified) (17 diffs)
- django/branches/multiple-db-support/django/newforms/forms.py (modified) (11 diffs)
- django/branches/multiple-db-support/django/newforms/util.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/newforms/widgets.py (modified) (5 diffs)
- django/branches/multiple-db-support/django/template/__init__.py (modified) (1 diff)
- django/branches/multiple-db-support/docs/add_ons.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/newforms.txt (copied) (copied from django/trunk/docs/newforms.txt)
- django/branches/multiple-db-support/docs/settings.txt (modified) (1 diff)
- django/branches/multiple-db-support/tests/regressiontests/forms/tests.py (modified) (23 diffs)
- django/branches/multiple-db-support/tests/regressiontests/templates/tests.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/multiple-db-support/django/contrib/admin/templates/admin/search_form.html
r3097 r4189 8 8 <input type="submit" value="{% trans 'Go' %}" /> 9 9 {% if show_result_count %} 10 <span class="small quiet">{% blocktrans count cl.result_count as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="? ">{% blocktrans with cl.full_result_count as full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span>10 <span class="small quiet">{% blocktrans count cl.result_count as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}pop=1{% endif %}">{% blocktrans with cl.full_result_count as full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span> 11 11 {% endif %} 12 12 {% for pair in cl.params.items %} django/branches/multiple-db-support/django/contrib/admin/views/main.py
r4155 r4189 227 227 model = models.get_model(app_label, model_name) 228 228 if model is None: 229 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)229 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 230 230 opts = model._meta 231 231 … … 303 303 object_id = unquote(object_id) 304 304 if model is None: 305 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)305 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 306 306 opts = model._meta 307 307 … … 314 314 try: 315 315 manipulator = model.ChangeManipulator(object_id) 316 except ObjectDoesNotExist:317 raise Http404 316 except model.DoesNotExist: 317 raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id))) 318 318 319 319 if request.POST: … … 491 491 object_id = unquote(object_id) 492 492 if model is None: 493 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)493 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 494 494 opts = model._meta 495 495 if not request.user.has_perm(app_label + '.' + opts.get_delete_permission()): … … 528 528 object_id = unquote(object_id) 529 529 if model is None: 530 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)530 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 531 531 action_list = LogEntry.objects.filter(object_id=object_id, 532 532 content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time') … … 744 744 model = models.get_model(app_label, model_name) 745 745 if model is None: 746 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)746 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 747 747 if not request.user.has_perm(app_label + '.' + model._meta.get_change_permission()): 748 748 raise PermissionDenied django/branches/multiple-db-support/django/contrib/contenttypes/management.py
r3665 r4189 4 4 5 5 from django.dispatch import dispatcher 6 from django.db.models import get_ models, signals6 from django.db.models import get_apps, get_models, signals 7 7 8 def create_contenttypes(app, created_models, verbosity ):8 def create_contenttypes(app, created_models, verbosity=2): 9 9 from django.contrib.contenttypes.models import ContentType 10 10 app_models = get_models(app) … … 23 23 print "Adding content type '%s | %s'" % (ct.app_label, ct.model) 24 24 25 def create_all_contenttypes(verbosity=2): 26 for app in get_apps(): 27 create_contenttypes(app, None, verbosity) 28 25 29 dispatcher.connect(create_contenttypes, signal=signals.post_syncdb) 30 31 if __name__ == "__main__": 32 create_all_contenttypes() django/branches/multiple-db-support/django/contrib/sitemaps/__init__.py
r3739 r4189 30 30 from django.contrib.sites.models import Site 31 31 current_site = Site.objects.get_current() 32 url = "%s%s" % (current_site.domain, sitemap )32 url = "%s%s" % (current_site.domain, sitemap_url) 33 33 params = urllib.urlencode({'sitemap':url}) 34 34 urllib.urlopen("%s?%s" % (ping_url, params)) django/branches/multiple-db-support/django/core/servers/fastcgi.py
r4157 r4189 119 119 return fastcgi_help("ERROR: Implementation must be one of prefork or thread.") 120 120 121 wsgi_opts['debug'] = False # Turn off flup tracebacks 122 121 123 # Prep up and go 122 124 from django.core.handlers.wsgi import WSGIHandler django/branches/multiple-db-support/django/newforms/fields.py
r4159 r4189 3 3 """ 4 4 5 from util import ValidationError, DEFAULT_ENCODING, smart_unicode 6 from widgets import TextInput, CheckboxInput, Select, SelectMultiple 5 from django.utils.translation import gettext 6 from util import ValidationError, smart_unicode 7 from widgets import TextInput, PasswordInput, CheckboxInput, Select, SelectMultiple 7 8 import datetime 8 9 import re … … 32 33 creation_counter = 0 33 34 34 def __init__(self, required=True, widget=None ):35 self.required = required35 def __init__(self, required=True, widget=None, label=None): 36 self.required, self.label = required, label 36 37 widget = widget or self.widget 37 38 if isinstance(widget, type): 38 39 widget = widget() 40 41 # Hook into self.widget_attrs() for any Field-specific HTML attributes. 42 extra_attrs = self.widget_attrs(widget) 43 if extra_attrs: 44 widget.attrs.update(extra_attrs) 45 39 46 self.widget = widget 40 47 … … 51 58 """ 52 59 if self.required and value in EMPTY_VALUES: 53 raise ValidationError(u'This field is required.') 54 return value 60 raise ValidationError(gettext(u'This field is required.')) 61 return value 62 63 def widget_attrs(self, widget): 64 """ 65 Given a Widget instance (*not* a Widget class), returns a dictionary of 66 any HTML attributes that should be added to the Widget, based on this 67 Field. 68 """ 69 return {} 55 70 56 71 class CharField(Field): 57 def __init__(self, max_length=None, min_length=None, required=True, widget=None): 58 Field.__init__(self, required, widget) 72 def __init__(self, max_length=None, min_length=None, required=True, widget=None, label=None): 59 73 self.max_length, self.min_length = max_length, min_length 74 Field.__init__(self, required, widget, label) 60 75 61 76 def clean(self, value): … … 65 80 value = smart_unicode(value) 66 81 if self.max_length is not None and len(value) > self.max_length: 67 raise ValidationError( u'Ensure this value has at most %d characters.'% self.max_length)82 raise ValidationError(gettext(u'Ensure this value has at most %d characters.') % self.max_length) 68 83 if self.min_length is not None and len(value) < self.min_length: 69 raise ValidationError(u'Ensure this value has at least %d characters.' % self.min_length) 70 return value 84 raise ValidationError(gettext(u'Ensure this value has at least %d characters.') % self.min_length) 85 return value 86 87 def widget_attrs(self, widget): 88 if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)): 89 return {'maxlength': str(self.max_length)} 71 90 72 91 class IntegerField(Field): … … 82 101 return int(value) 83 102 except (ValueError, TypeError): 84 raise ValidationError( u'Enter a whole number.')103 raise ValidationError(gettext(u'Enter a whole number.')) 85 104 86 105 DEFAULT_DATE_INPUT_FORMATS = ( … … 93 112 94 113 class DateField(Field): 95 def __init__(self, input_formats=None, required=True, widget=None ):96 Field.__init__(self, required, widget )114 def __init__(self, input_formats=None, required=True, widget=None, label=None): 115 Field.__init__(self, required, widget, label) 97 116 self.input_formats = input_formats or DEFAULT_DATE_INPUT_FORMATS 98 117 … … 114 133 except ValueError: 115 134 continue 116 raise ValidationError( u'Enter a valid date.')135 raise ValidationError(gettext(u'Enter a valid date.')) 117 136 118 137 DEFAULT_DATETIME_INPUT_FORMATS = ( … … 129 148 130 149 class DateTimeField(Field): 131 def __init__(self, input_formats=None, required=True, widget=None ):132 Field.__init__(self, required, widget )150 def __init__(self, input_formats=None, required=True, widget=None, label=None): 151 Field.__init__(self, required, widget, label) 133 152 self.input_formats = input_formats or DEFAULT_DATETIME_INPUT_FORMATS 134 153 … … 150 169 except ValueError: 151 170 continue 152 raise ValidationError( u'Enter a valid date/time.')171 raise ValidationError(gettext(u'Enter a valid date/time.')) 153 172 154 173 class RegexField(Field): 155 def __init__(self, regex, error_message=None, required=True, widget=None ):174 def __init__(self, regex, error_message=None, required=True, widget=None, label=None): 156 175 """ 157 176 regex can be either a string or a compiled regular expression object. … … 159 178 'Enter a valid value' is too generic for you. 160 179 """ 161 Field.__init__(self, required, widget )180 Field.__init__(self, required, widget, label) 162 181 if isinstance(regex, basestring): 163 182 regex = re.compile(regex) 164 183 self.regex = regex 165 self.error_message = error_message or u'Enter a valid value.'184 self.error_message = error_message or gettext(u'Enter a valid value.') 166 185 167 186 def clean(self, value): … … 185 204 186 205 class EmailField(RegexField): 187 def __init__(self, required=True, widget=None ):188 RegexField.__init__(self, email_re, u'Enter a valid e-mail address.', required, widget)206 def __init__(self, required=True, widget=None, label=None): 207 RegexField.__init__(self, email_re, gettext(u'Enter a valid e-mail address.'), required, widget, label) 189 208 190 209 url_re = re.compile( … … 202 221 203 222 class URLField(RegexField): 204 def __init__(self, required=True, verify_exists=False, widget=None, 223 def __init__(self, required=True, verify_exists=False, widget=None, label=None, 205 224 validator_user_agent=URL_VALIDATOR_USER_AGENT): 206 RegexField.__init__(self, url_re, u'Enter a valid URL.', required, widget)225 RegexField.__init__(self, url_re, gettext(u'Enter a valid URL.'), required, widget, label) 207 226 self.verify_exists = verify_exists 208 227 self.user_agent = validator_user_agent … … 224 243 u = urllib2.urlopen(req) 225 244 except ValueError: 226 raise ValidationError( u'Enter a valid URL.')245 raise ValidationError(gettext(u'Enter a valid URL.')) 227 246 except: # urllib2.URLError, httplib.InvalidURL, etc. 228 raise ValidationError( u'This URL appears to be a broken link.')247 raise ValidationError(gettext(u'This URL appears to be a broken link.')) 229 248 return value 230 249 … … 238 257 239 258 class ChoiceField(Field): 240 def __init__(self, choices=(), required=True, widget=Select ):259 def __init__(self, choices=(), required=True, widget=Select, label=None): 241 260 if isinstance(widget, type): 242 261 widget = widget(choices=choices) 243 Field.__init__(self, required, widget )262 Field.__init__(self, required, widget, label) 244 263 self.choices = choices 245 264 … … 255 274 valid_values = set([str(k) for k, v in self.choices]) 256 275 if value not in valid_values: 257 raise ValidationError( u'Select a valid choice. %s is not one of the available choices.'% value)276 raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % value) 258 277 return value 259 278 260 279 class MultipleChoiceField(ChoiceField): 261 def __init__(self, choices=(), required=True, widget=SelectMultiple ):262 ChoiceField.__init__(self, choices, required, widget )280 def __init__(self, choices=(), required=True, widget=SelectMultiple, label=None): 281 ChoiceField.__init__(self, choices, required, widget, label) 263 282 264 283 def clean(self, value): … … 267 286 """ 268 287 if self.required and not value: 269 raise ValidationError( u'This field is required.')288 raise ValidationError(gettext(u'This field is required.')) 270 289 elif not self.required and not value: 271 290 return [] 272 291 if not isinstance(value, (list, tuple)): 273 raise ValidationError( u'Enter a list of values.')292 raise ValidationError(gettext(u'Enter a list of values.')) 274 293 new_value = [] 275 294 for val in value: … … 277 296 new_value.append(val) 278 297 # Validate that each value in the value list is in self.choices. 279 valid_values = set([ kfor k, v in self.choices])298 valid_values = set([smart_unicode(k) for k, v in self.choices]) 280 299 for val in new_value: 281 300 if val not in valid_values: 282 raise ValidationError( u'Select a valid choice. %s is not one of the available choices.'% val)301 raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % val) 283 302 return new_value 284 303 285 304 class ComboField(Field): 286 def __init__(self, fields=(), required=True, widget=None ):287 Field.__init__(self, required, widget )305 def __init__(self, fields=(), required=True, widget=None, label=None): 306 Field.__init__(self, required, widget, label) 288 307 # Set 'required' to False on the individual fields, because the 289 308 # required validation will be handled by ComboField, not by those django/branches/multiple-db-support/django/newforms/forms.py
r4159 r4189 7 7 from fields import Field 8 8 from widgets import TextInput, Textarea, HiddenInput 9 from util import ErrorDict, ErrorList, ValidationError9 from util import StrAndUnicode, ErrorDict, ErrorList, ValidationError 10 10 11 11 NON_FIELD_ERRORS = '__all__' … … 33 33 return type.__new__(cls, name, bases, attrs) 34 34 35 class Form( object):35 class Form(StrAndUnicode): 36 36 "A collection of Fields, plus their associated data." 37 37 __metaclass__ = DeclarativeFieldsMetaclass … … 44 44 self.__errors = None # Stores the errors after clean() has been called. 45 45 46 def __ str__(self):46 def __unicode__(self): 47 47 return self.as_table() 48 48 … … 73 73 return not self.ignore_errors and not bool(self.errors) 74 74 75 def _html_output(self, normal_row, error_row, row_ender, errors_on_separate_row): 76 "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." 77 top_errors = self.non_field_errors() # Errors that should be displayed above all fields. 78 output, hidden_fields = [], [] 79 for name, field in self.fields.items(): 80 bf = BoundField(self, field, name) 81 bf_errors = bf.errors # Cache in local variable. 82 if bf.is_hidden: 83 if bf_errors: 84 top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors]) 85 hidden_fields.append(unicode(bf)) 86 else: 87 if errors_on_separate_row and bf_errors: 88 output.append(error_row % bf_errors) 89 output.append(normal_row % {'errors': bf_errors, 'label': bf.label_tag(escape(bf.label+':')), 'field': bf}) 90 if top_errors: 91 output.insert(0, error_row % top_errors) 92 if hidden_fields: # Insert any hidden fields in the last row. 93 str_hidden = u''.join(hidden_fields) 94 if output: 95 last_row = output[-1] 96 # Chop off the trailing row_ender (e.g. '</td></tr>') and insert the hidden fields. 97 output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender 98 else: # If there aren't any rows in the output, just append the hidden fields. 99 output.append(str_hidden) 100 return u'\n'.join(output) 101 75 102 def as_table(self): 76 103 "Returns this form rendered as HTML <tr>s -- excluding the <table></table>." 77 output = [] 78 if self.errors.get(NON_FIELD_ERRORS): 79 # Errors not corresponding to a particular field are displayed at the top. 80 output.append(u'<tr><td colspan="2">%s</td></tr>' % self.non_field_errors()) 81 for name, field in self.fields.items(): 82 bf = BoundField(self, field, name) 83 if bf.is_hidden: 84 if bf.errors: 85 new_errors = ErrorList(['(Hidden field %s) %s' % (name, e) for e in bf.errors]) 86 output.append(u'<tr><td colspan="2">%s</td></tr>' % new_errors) 87 output.append(str(bf)) 88 else: 89 if bf.errors: 90 output.append(u'<tr><td colspan="2">%s</td></tr>' % bf.errors) 91 output.append(u'<tr><td>%s</td><td>%s</td></tr>' % (bf.label_tag(escape(bf.verbose_name+':')), bf)) 92 return u'\n'.join(output) 104 return self._html_output(u'<tr><td>%(label)s</td><td>%(field)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', True) 93 105 94 106 def as_ul(self): 95 107 "Returns this form rendered as HTML <li>s -- excluding the <ul></ul>." 96 output = [] 97 if self.errors.get(NON_FIELD_ERRORS): 98 # Errors not corresponding to a particular field are displayed at the top. 99 output.append(u'<li>%s</li>' % self.non_field_errors()) 100 for name, field in self.fields.items(): 101 bf = BoundField(self, field, name) 102 if bf.is_hidden: 103 if bf.errors: 104 new_errors = ErrorList(['(Hidden field %s) %s' % (name, e) for e in bf.errors]) 105 output.append(u'<li>%s</li>' % new_errors) 106 output.append(str(bf)) 107 else: 108 output.append(u'<li>%s%s %s</li>' % (bf.errors, bf.label_tag(escape(bf.verbose_name+':')), bf)) 109 return u'\n'.join(output) 108 return self._html_output(u'<li>%(errors)s%(label)s %(field)s</li>', u'<li>%s</li>', '</li>', False) 109 110 def as_p(self): 111 "Returns this form rendered as HTML <p>s." 112 return self._html_output(u'<p>%(label)s %(field)s</p>', u'<p>%s</p>', '</p>', True) 110 113 111 114 def non_field_errors(self): … … 156 159 return self.clean_data 157 160 158 class BoundField( object):161 class BoundField(StrAndUnicode): 159 162 "A Field plus data" 160 163 def __init__(self, form, field, name): 161 self._form = form 162 self._field = field 163 self._name = name 164 165 def __str__(self): 164 self.form = form 165 self.field = field 166 self.name = name 167 self.label = self.field.label or pretty_name(name) 168 169 def __unicode__(self): 166 170 "Renders this field as an HTML widget." 167 171 # Use the 'widget' attribute on the field to determine which type 168 172 # of HTML widget to use. 169 value = self.as_widget(self. _field.widget)173 value = self.as_widget(self.field.widget) 170 174 if not isinstance(value, basestring): 171 175 # Some Widget render() methods -- notably RadioSelect -- return a … … 180 184 if there are none. 181 185 """ 182 try: 183 return self._form.errors[self._name] 184 except KeyError: 185 return ErrorList() 186 return self.form.errors.get(self.name, ErrorList()) 186 187 errors = property(_errors) 187 188 … … 191 192 if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'): 192 193 attrs['id'] = auto_id 193 return widget.render(self. _name, self.data, attrs=attrs)194 return widget.render(self.name, self.data, attrs=attrs) 194 195 195 196 def as_text(self, attrs=None): … … 211 212 def _data(self): 212 213 "Returns the data for this BoundField, or None if it wasn't given." 213 return self. _form.data.get(self._name, None)214 return self.form.data.get(self.name, None) 214 215 data = property(_data) 215 216 def _verbose_name(self):217 return pretty_name(self._name)218 verbose_name = property(_verbose_name)219 216 220 217 def label_tag(self, contents=None): … … 222 219 Wraps the given contents in a <label>, if the field has an ID attribute. 223 220 Does not HTML-escape the contents. If contents aren't given, uses the 224 field's HTML-escaped verbose_name.225 """ 226 contents = contents or escape(self. verbose_name)227 widget = self. _field.widget221 field's HTML-escaped label. 222 """ 223 contents = contents or escape(self.label) 224 widget = self.field.widget 228 225 id_ = widget.attrs.get('id') or self.auto_id 229 226 if id_: … … 233 230 def _is_hidden(self): 234 231 "Returns True if this BoundField's widget is hidden." 235 return self. _field.widget.is_hidden232 return self.field.widget.is_hidden 236 233 is_hidden = property(_is_hidden) 237 234 … … 241 238 associated Form has specified auto_id. Returns an empty string otherwise. 242 239 """ 243 auto_id = self. _form.auto_id240 auto_id = self.form.auto_id 244 241 if auto_id and '%s' in str(auto_id): 245 return str(auto_id) % self. _name242 return str(auto_id) % self.name 246 243 elif auto_id: 247 return self. _name244 return self.name 248 245 return '' 249 246 auto_id = property(_auto_id) django/branches/multiple-db-support/django/newforms/util.py
r4158 r4189 1 # Default encoding for input byte strings. 2 DEFAULT_ENCODING = 'utf-8' # TODO: First look at django.conf.settings, then fall back to this. 1 from django.conf import settings 3 2 4 3 def smart_unicode(s): … … 6 5 s = unicode(str(s)) 7 6 elif not isinstance(s, unicode): 8 s = unicode(s, DEFAULT_ENCODING)7 s = unicode(s, settings.DEFAULT_CHARSET) 9 8 return s 9 10 class StrAndUnicode(object): 11 """ 12 A class whose __str__ returns its __unicode__ as a bytestring 13 according to settings.DEFAULT_CHARSET. 14 15 Useful as a mix-in. 16 """ 17 def __str__(self): 18 return self.__unicode__().encode(settings.DEFAULT_CHARSET) 10 19 11 20 class ErrorDict(dict): django/branches/multiple-db-support/django/newforms/widgets.py
r4159 r4189 9 9 ) 10 10 11 from util import smart_unicode11 from util import StrAndUnicode, smart_unicode 12 12 from django.utils.html import escape 13 13 from itertools import chain … … 147 147 return u'\n'.join(output) 148 148 149 class RadioInput( object):149 class RadioInput(StrAndUnicode): 150 150 "An object used by RadioFieldRenderer that represents a single <input type='radio'>." 151 151 def __init__(self, name, value, attrs, choice, index): … … 155 155 self.index = index 156 156 157 def __ str__(self):157 def __unicode__(self): 158 158 return u'<label>%s %s</label>' % (self.tag(), self.choice_label) 159 159 … … 169 169 return u'<input%s />' % flatatt(final_attrs) 170 170 171 class RadioFieldRenderer( object):171 class RadioFieldRenderer(StrAndUnicode): 172 172 "An object used by RadioSelect to enable customization of radio widgets." 173 173 def __init__(self, name, value, attrs, choices): … … 179 179 yield RadioInput(self.name, self.value, self.attrs.copy(), choice, i) 180 180 181 def __ str__(self):181 def __unicode__(self): 182 182 "Outputs a <ul> for this set of radio fields." 183 183 return u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % w for w in self]) django/branches/multiple-db-support/django/template/__init__.py
r4157 r4189 743 743 # Check type so that we don't run str() on a Unicode object 744 744 if not isinstance(output, basestring): 745 return str(output) 745 try: 746 return str(output) 747 except UnicodeEncodeError: 748 # If __str__() returns a Unicode object, convert it to bytestring. 749 return unicode(output).encode(settings.DEFAULT_CHARSET) 746 750 elif isinstance(output, unicode): 747 751 return output.encode(settings.DEFAULT_CHARSET) django/branches/multiple-db-support/docs/add_ons.txt
r3712 r4189 48 48 49 49 .. _csrf documentation: http://www.djangoproject.com/documentation/csrf/ 50 51 formtools 52 ========= 53 54 **New in Django development version** 55 56 A set of high-level abstractions for Django forms (django.newforms). 57 58 django.contrib.formtools.preview 59 -------------------------------- 60 61 An abstraction of the following workflow: 62 63 "Display an HTML form, force a preview, then do something with the submission." 64 65 Full documentation for this feature does not yet exist, but you can read the 66 code and docstrings in ``django/contrib/formtools/preview.py`` for a start. 50 67 51 68 humanize django/branches/multiple-db-support/docs/settings.txt
r4157 r4189 838 838 exist (see the ``verify_exists`` option on URLField_). 839 839 840 .. URLField: ../model_api/#urlfield840 .. _URLField: ../model_api/#urlfield 841 841 842 842 USE_ETAGS django/branches/multiple-db-support/tests/regressiontests/forms/tests.py
r4159 r4189 637 637 Widget that it'll use if you don't specify this. In most cases, 638 638 the default widget is TextInput. 639 label -- A verbose name for this field, for use in displaying this field in 640 a form. By default, Django will use a "pretty" version of the form 641 field name, if the Field is part of a Form. 639 642 640 643 Other than that, the Field subclasses have class-specific options for … … 1336 1339 <input type="text" name="birthday" value="1940-10-9" /> 1337 1340 >>> for boundfield in p: 1338 ... print boundfield. verbose_name, boundfield.data1341 ... print boundfield.label, boundfield.data 1339 1342 First name John 1340 1343 Last name Lennon … … 1369 1372 <li><ul class="errorlist"><li>This field is required.</li></ul>Last name: <input type="text" name="last_name" /></li> 1370 1373 <li><ul class="errorlist"><li>This field is required.</li></ul>Birthday: <input type="text" name="birthday" /></li> 1374 >>> print p.as_p() 1375 <p><ul class="errorlist"><li>This field is required.</li></ul></p> 1376 <p>First name: <input type="text" name="first_name" /></p> 1377 <p><ul class="errorlist"><li>This field is required.</li></ul></p> 1378 <p>Last name: <input type="text" name="last_name" /></p> 1379 <p><ul class="errorlist"><li>This field is required.</li></ul></p> 1380 <p>Birthday: <input type="text" name="birthday" /></p> 1371 1381 1372 1382 If you don't pass any values to the Form's __init__(), or if you pass None, … … 1390 1400 <li>Last name: <input type="text" name="last_name" /></li> 1391 1401 <li>Birthday: <input type="text" name="birthday" /></li> 1402 >>> print p.as_p() 1403 <p>First name: <input type="text" name="first_name" /></p> 1404 <p>Last name: <input type="text" name="last_name" /></p> 1405 <p>Birthday: <input type="text" name="birthday" /></p> 1392 1406 1393 1407 Unicode values are handled properly. … … 1397 1411 >>> p.as_ul() 1398 1412 u'<li>First name: <input type="text" name="first_name" value="John" /></li>\n<li>Last name: <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /></li>\n<li>Birthday: <input type="text" name="birthday" value="1940-10-9" /></li>' 1413 >>> p.as_p() 1414 u'<p>First name: <input type="text" name="first_name" value="John" /></p>\n<p>Last name: <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /></p>\n<p>Birthday: <input type="text" name="birthday" value="1940-10-9" /></p>' 1399 1415 1400 1416 >>> p = Person({'last_name': u'Lennon'}) … … 1433 1449 the human-readable labels for a field. 1434 1450 >>> p = Person(auto_id='id_%s') 1451 >>> print p.as_table() 1452 <tr><td><label for="id_first_name">First name:</label></td><td><input type="text" name="first_name" id="id_first_name" /></td></tr> 1453 <tr><td><label for="id_last_name">Last name:</label></td><td><input type="text" name="last_name" id="id_last_name" /></td></tr> 1454 <tr><td><label for="id_birthday">Birthday:</label></td><td><input type="text" name="birthday" id="id_birthday" /></td></tr> 1435 1455 >>> print p.as_ul() 1436 1456 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 1437 1457 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> 1438 1458 <li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li> 1439 >>> print p.as_ table()1440 < tr><td><label for="id_first_name">First name:</label></td><td><input type="text" name="first_name" id="id_first_name" /></td></tr>1441 < tr><td><label for="id_last_name">Last name:</label></td><td><input type="text" name="last_name" id="id_last_name" /></td></tr>1442 < tr><td><label for="id_birthday">Birthday:</label></td><td><input type="text" name="birthday" id="id_birthday" /></td></tr>1459 >>> print p.as_p() 1460 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> 1461 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> 1462 <p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p> 1443 1463 1444 1464 If auto_id is any True value whose str() does not contain '%s', the "id" … … 1597 1617 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 1598 1618 </ul></li> 1619 >>> print f.as_p() 1620 <p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p> 1621 <p><label for="id_language_0">Language:</label> <ul> 1622 <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> 1623 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 1624 </ul></p> 1599 1625 1600 1626 MultipleChoiceField is a special case, as its data is required to be a list: … … 1714 1740 >>> print f.as_table() 1715 1741 <tr><td colspan="2"><ul class="errorlist"><li>This field is required.</li></ul></td></tr> 1716 <tr><td>Username:</td><td><input type="text" name="username" /></td></tr>1742 <tr><td>Username:</td><td><input type="text" name="username" maxlength="10" /></td></tr> 1717 1743 <tr><td colspan="2"><ul class="errorlist"><li>This field is required.</li></ul></td></tr> 1718 1744 <tr><td>Password1:</td><td><input type="password" name="password1" /></td></tr> … … 1726 1752 >>> print f.as_table() 1727 1753 <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr> 1728 <tr><td>Username:</td><td><input type="text" name="username" value="adrian" /></td></tr>1754 <tr><td>Username:</td><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr> 1729 1755 <tr><td>Password1:</td><td><input type="password" name="password1" value="foo" /></td></tr> 1730 1756 <tr><td>Password2:</td><td><input type="password" name="password2" value="bar" /></td></tr> 1731 1757 >>> print f.as_ul() 1732 1758 <li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li> 1733 <li>Username: <input type="text" name="username" value="adrian" /></li>1759 <li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li> 1734 1760 <li>Password1: <input type="password" name="password1" value="foo" /></li> 1735 1761 <li>Password2: <input type="password" name="password2" value="bar" /></li> … … 1755 1781 <tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr> 1756 1782 1757 HiddenInput widgets are displayed differently in the as_table() and as_ul() 1758 output of a Form -- their verbose names are not displayed, and a separate 1759 <tr>/<li> is not displayed. 1783 HiddenInput widgets are displayed differently in the as_table(), as_ul() 1784 and as_p() output of a Form -- their verbose names are not displayed, and a 1785 separate row is not displayed. They're displayed in the last row of the 1786 form, directly after that row's form element. 1760 1787 >>> class Person(Form): 1761 1788 ... first_name = CharField() … … 1767 1794 <tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr> 1768 1795 <tr><td>Last name:</td><td><input type="text" name="last_name" /></td></tr> 1769 <input type="hidden" name="hidden_text" /> 1770 <tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr> 1796 <tr><td>Birthday:</td><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr> 1771 1797 >>> print p.as_ul() 1772 1798 <li>First name: <input type="text" name="first_name" /></li> 1773 1799 <li>Last name: <input type="text" name="last_name" /></li> 1774 <input type="hidden" name="hidden_text" /> 1775 <li>Birthday: <input type="text" name="birthday" /></li> 1800 <li>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></li> 1801 >>> print p.as_p() 1802 <p>First name: <input type="text" name="first_name" /></p> 1803 <p>Last name: <input type="text" name="last_name" /></p> 1804 <p>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></p> 1776 1805 1777 1806 With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label. … … 1780 1809 <tr><td><label for="id_first_name">First name:</label></td><td><input type="text" name="first_name" id="id_first_name" /></td></tr> 1781 1810 <tr><td><label for="id_last_name">Last name:</label></td><td><input type="text" name="last_name" id="id_last_name" /></td></tr> 1782 <input type="hidden" name="hidden_text" id="id_hidden_text" /> 1783 <tr><td><label for="id_birthday">Birthday:</label></td><td><input type="text" name="birthday" id="id_birthday" /></td></tr> 1811 <tr><td><label for="id_birthday">Birthday:</label></td><td><input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></td></tr> 1784 1812 >>> print p.as_ul() 1785 1813 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 1786 1814 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> 1787 <input type="hidden" name="hidden_text" id="id_hidden_text" /> 1788
