Changeset 4184
- Timestamp:
- 12/07/06 17:15:08 (2 years ago)
- Files:
-
- django/branches/generic-auth/django/contrib/admin/templates/admin/search_form.html (modified) (1 diff)
- django/branches/generic-auth/django/contrib/admin/views/main.py (modified) (6 diffs)
- django/branches/generic-auth/django/contrib/contenttypes/management.py (modified) (2 diffs)
- django/branches/generic-auth/django/contrib/formtools (copied) (copied from django/trunk/django/contrib/formtools)
- django/branches/generic-auth/django/contrib/formtools/__init__.py (copied) (copied from django/trunk/django/contrib/formtools/__init__.py)
- django/branches/generic-auth/django/contrib/formtools/preview.py (copied) (copied from django/trunk/django/contrib/formtools/preview.py)
- django/branches/generic-auth/django/contrib/formtools/templates (copied) (copied from django/trunk/django/contrib/formtools/templates)
- django/branches/generic-auth/django/contrib/formtools/templates/formtools (copied) (copied from django/trunk/django/contrib/formtools/templates/formtools)
- django/branches/generic-auth/django/contrib/formtools/templates/formtools/form.html (copied) (copied from django/trunk/django/contrib/formtools/templates/formtools/form.html)
- django/branches/generic-auth/django/contrib/formtools/templates/formtools/preview.html (copied) (copied from django/trunk/django/contrib/formtools/templates/formtools/preview.html)
- django/branches/generic-auth/django/contrib/sitemaps/__init__.py (modified) (1 diff)
- django/branches/generic-auth/django/core/servers/fastcgi.py (modified) (1 diff)
- django/branches/generic-auth/django/newforms/fields.py (modified) (13 diffs)
- django/branches/generic-auth/django/newforms/forms.py (modified) (11 diffs)
- django/branches/generic-auth/django/newforms/util.py (modified) (2 diffs)
- django/branches/generic-auth/django/newforms/widgets.py (modified) (5 diffs)
- django/branches/generic-auth/django/template/__init__.py (modified) (1 diff)
- django/branches/generic-auth/docs/add_ons.txt (modified) (1 diff)
- django/branches/generic-auth/docs/newforms.txt (copied) (copied from django/trunk/docs/newforms.txt)
- django/branches/generic-auth/docs/settings.txt (modified) (1 diff)
- django/branches/generic-auth/docs/testing.txt (modified) (1 diff)
- django/branches/generic-auth/tests/regressiontests/forms/tests.py (modified) (8 diffs)
- django/branches/generic-auth/tests/regressiontests/templates/tests.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/generic-auth/django/contrib/admin/templates/admin/search_form.html
r3097 r4184 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/generic-auth/django/contrib/admin/views/main.py
r4026 r4184 228 228 model = models.get_model(app_label, model_name) 229 229 if model is None: 230 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)230 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 231 231 opts = model._meta 232 232 … … 308 308 object_id = unquote(object_id) 309 309 if model is None: 310 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)310 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 311 311 opts = model._meta 312 312 … … 316 316 try: 317 317 manipulator = model.ChangeManipulator(object_id) 318 except ObjectDoesNotExist:319 raise Http404 318 except model.DoesNotExist: 319 raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id))) 320 320 321 321 if not has_permission(request.user, opts.get_change_permission(), manipulator.original_object): … … 493 493 object_id = unquote(object_id) 494 494 if model is None: 495 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)495 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 496 496 opts = model._meta 497 497 obj = get_object_or_404(model, pk=object_id) … … 530 530 object_id = unquote(object_id) 531 531 if model is None: 532 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)532 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 533 533 action_list = LogEntry.objects.filter(object_id=object_id, 534 534 content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time') … … 746 746 model = models.get_model(app_label, model_name) 747 747 if model is None: 748 raise Http404 , "App %r, model %r, not found" % (app_label, model_name)748 raise Http404("App %r, model %r, not found" % (app_label, model_name)) 749 749 # There isn't a specific object to check here, so don't pass one to 750 750 # has_permission. There should be a has_permission implementation django/branches/generic-auth/django/contrib/contenttypes/management.py
r4026 r4184 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/generic-auth/django/contrib/sitemaps/__init__.py
r4026 r4184 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/generic-auth/django/core/servers/fastcgi.py
r4063 r4184 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/generic-auth/django/newforms/fields.py
r4149 r4184 3 3 """ 4 4 5 from util import ValidationError, DEFAULT_ENCODING, smart_unicode 5 from django.utils.translation import gettext 6 from util import ValidationError, smart_unicode 6 7 from widgets import TextInput, CheckboxInput, Select, SelectMultiple 7 8 import datetime … … 51 52 """ 52 53 if self.required and value in EMPTY_VALUES: 53 raise ValidationError( u'This field is required.')54 raise ValidationError(gettext(u'This field is required.')) 54 55 return value 55 56 … … 65 66 value = smart_unicode(value) 66 67 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)68 raise ValidationError(gettext(u'Ensure this value has at most %d characters.') % self.max_length) 68 69 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 raise ValidationError(gettext(u'Ensure this value has at least %d characters.') % self.min_length) 70 71 return value 71 72 … … 82 83 return int(value) 83 84 except (ValueError, TypeError): 84 raise ValidationError( u'Enter a whole number.')85 raise ValidationError(gettext(u'Enter a whole number.')) 85 86 86 87 DEFAULT_DATE_INPUT_FORMATS = ( … … 114 115 except ValueError: 115 116 continue 116 raise ValidationError( u'Enter a valid date.')117 raise ValidationError(gettext(u'Enter a valid date.')) 117 118 118 119 DEFAULT_DATETIME_INPUT_FORMATS = ( … … 150 151 except ValueError: 151 152 continue 152 raise ValidationError( u'Enter a valid date/time.')153 raise ValidationError(gettext(u'Enter a valid date/time.')) 153 154 154 155 class RegexField(Field): … … 163 164 regex = re.compile(regex) 164 165 self.regex = regex 165 self.error_message = error_message or u'Enter a valid value.'166 self.error_message = error_message or gettext(u'Enter a valid value.') 166 167 167 168 def clean(self, value): … … 186 187 class EmailField(RegexField): 187 188 def __init__(self, required=True, widget=None): 188 RegexField.__init__(self, email_re, u'Enter a valid e-mail address.', required, widget)189 RegexField.__init__(self, email_re, gettext(u'Enter a valid e-mail address.'), required, widget) 189 190 190 191 url_re = re.compile( … … 204 205 def __init__(self, required=True, verify_exists=False, widget=None, 205 206 validator_user_agent=URL_VALIDATOR_USER_AGENT): 206 RegexField.__init__(self, url_re, u'Enter a valid URL.', required, widget)207 RegexField.__init__(self, url_re, gettext(u'Enter a valid URL.'), required, widget) 207 208 self.verify_exists = verify_exists 208 209 self.user_agent = validator_user_agent … … 224 225 u = urllib2.urlopen(req) 225 226 except ValueError: 226 raise ValidationError( u'Enter a valid URL.')227 raise ValidationError(gettext(u'Enter a valid URL.')) 227 228 except: # urllib2.URLError, httplib.InvalidURL, etc. 228 raise ValidationError( u'This URL appears to be a broken link.')229 raise ValidationError(gettext(u'This URL appears to be a broken link.')) 229 230 return value 230 231 … … 255 256 valid_values = set([str(k) for k, v in self.choices]) 256 257 if value not in valid_values: 257 raise ValidationError( u'Select a valid choice. %s is not one of the available choices.'% value)258 raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % value) 258 259 return value 259 260 … … 267 268 """ 268 269 if self.required and not value: 269 raise ValidationError( u'This field is required.')270 raise ValidationError(gettext(u'This field is required.')) 270 271 elif not self.required and not value: 271 272 return [] 272 273 if not isinstance(value, (list, tuple)): 273 raise ValidationError( u'Enter a list of values.')274 raise ValidationError(gettext(u'Enter a list of values.')) 274 275 new_value = [] 275 276 for val in value: … … 280 281 for val in new_value: 281 282 if val not in valid_values: 282 raise ValidationError( u'Select a valid choice. %s is not one of the available choices.'% val)283 raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % val) 283 284 return new_value 284 285 django/branches/generic-auth/django/newforms/forms.py
r4149 r4184 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.verbose_name+':')), '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 = form162 self. _field = field163 self. _name = name164 165 def __ str__(self):164 self.form = form 165 self.field = field 166 self.name = name 167 168 def __unicode__(self): 166 169 "Renders this field as an HTML widget." 167 170 # Use the 'widget' attribute on the field to determine which type 168 171 # of HTML widget to use. 169 value = self.as_widget(self. _field.widget)172 value = self.as_widget(self.field.widget) 170 173 if not isinstance(value, basestring): 171 174 # Some Widget render() methods -- notably RadioSelect -- return a … … 180 183 if there are none. 181 184 """ 182 try: 183 return self._form.errors[self._name] 184 except KeyError: 185 return ErrorList() 185 return self.form.errors.get(self.name, ErrorList()) 186 186 errors = property(_errors) 187 187 … … 191 191 if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'): 192 192 attrs['id'] = auto_id 193 return widget.render(self. _name, self.data, attrs=attrs)193 return widget.render(self.name, self.data, attrs=attrs) 194 194 195 195 def as_text(self, attrs=None): … … 211 211 def _data(self): 212 212 "Returns the data for this BoundField, or None if it wasn't given." 213 return self. _form.data.get(self._name, None)213 return self.form.data.get(self.name, None) 214 214 data = property(_data) 215 215 216 216 def _verbose_name(self): 217 return pretty_name(self. _name)217 return pretty_name(self.name) 218 218 verbose_name = property(_verbose_name) 219 219 … … 225 225 """ 226 226 contents = contents or escape(self.verbose_name) 227 widget = self. _field.widget227 widget = self.field.widget 228 228 id_ = widget.attrs.get('id') or self.auto_id 229 229 if id_: … … 233 233 def _is_hidden(self): 234 234 "Returns True if this BoundField's widget is hidden." 235 return self. _field.widget.is_hidden235 return self.field.widget.is_hidden 236 236 is_hidden = property(_is_hidden) 237 237 … … 241 241 associated Form has specified auto_id. Returns an empty string otherwise. 242 242 """ 243 auto_id = self. _form.auto_id243 auto_id = self.form.auto_id 244 244 if auto_id and '%s' in str(auto_id): 245 return str(auto_id) % self. _name245 return str(auto_id) % self.name 246 246 elif auto_id: 247 return self. _name247 return self.name 248 248 return '' 249 249 auto_id = property(_auto_id) django/branches/generic-auth/django/newforms/util.py
r4104 r4184 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/generic-auth/django/newforms/widgets.py
r4149 r4184 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/generic-auth/django/template/__init__.py
r4063 r4184 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/generic-auth/docs/add_ons.txt
r4026 r4184 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/generic-auth/docs/settings.txt
r4063 r4184 831 831 exist (see the ``verify_exists`` option on URLField_). 832 832 833 .. URLField: ../model_api/#urlfield833 .. _URLField: ../model_api/#urlfield 834 834 835 835 USE_ETAGS django/branches/generic-auth/docs/testing.txt
r4063 r4184 134 134 135 135 For developers new to testing, however, this choice can seem 136 confusing, so here are a few key differences to help you decide w eather136 confusing, so here are a few key differences to help you decide whether 137 137 doctests or unit tests are right for you. 138 138 django/branches/generic-auth/tests/regressiontests/forms/tests.py
r4149 r4184 1369 1369 <li><ul class="errorlist"><li>This field is required.</li></ul>Last name: <input type="text" name="last_name" /></li> 1370 1370 <li><ul class="errorlist"><li>This field is required.</li></ul>Birthday: <input type="text" name="birthday" /></li> 1371 >>> print p.as_p() 1372 <p><ul class="errorlist"><li>This field is required.</li></ul></p> 1373 <p>First name: <input type="text" name="first_name" /></p> 1374 <p><ul class="errorlist"><li>This field is required.</li></ul></p> 1375 <p>Last name: <input type="text" name="last_name" /></p> 1376 <p><ul class="errorlist"><li>This field is required.</li></ul></p> 1377 <p>Birthday: <input type="text" name="birthday" /></p> 1371 1378 1372 1379 If you don't pass any values to the Form's __init__(), or if you pass None, … … 1390 1397 <li>Last name: <input type="text" name="last_name" /></li> 1391 1398 <li>Birthday: <input type="text" name="birthday" /></li> 1399 >>> print p.as_p() 1400 <p>First name: <input type="text" name="first_name" /></p> 1401 <p>Last name: <input type="text" name="last_name" /></p> 1402 <p>Birthday: <input type="text" name="birthday" /></p> 1392 1403 1393 1404 Unicode values are handled properly. … … 1397 1408 >>> p.as_ul() 1398 1409 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>' 1410 >>> p.as_p() 1411 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 1412 1400 1413 >>> p = Person({'last_name': u'Lennon'}) … … 1433 1446 the human-readable labels for a field. 1434 1447 >>> p = Person(auto_id='id_%s') 1448 >>> print p.as_table() 1449 <tr><td><label for="id_first_name">First name:</label></td><td><input type="text" name="first_name" id="id_first_name" /></td></tr> 1450 <tr><td><label for="id_last_name">Last name:</label></td><td><input type="text" name="last_name" id="id_last_name" /></td></tr> 1451 <tr><td><label for="id_birthday">Birthday:</label></td><td><input type="text" name="birthday" id="id_birthday" /></td></tr> 1435 1452 >>> print p.as_ul() 1436 1453 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 1437 1454 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> 1438 1455 <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>1456 >>> print p.as_p() 1457 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> 1458 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> 1459 <p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p> 1443 1460 1444 1461 If auto_id is any True value whose str() does not contain '%s', the "id" … … 1597 1614 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 1598 1615 </ul></li> 1616 >>> print f.as_p() 1617 <p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p> 1618 <p><label for="id_language_0">Language:</label> <ul> 1619 <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> 1620 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 1621 </ul></p> 1599 1622 1600 1623 MultipleChoiceField is a special case, as its data is required to be a list: … … 1755 1778 <tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr> 1756 1779 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. 1780 HiddenInput widgets are displayed differently in the as_table(), as_ul() 1781 and as_p() output of a Form -- their verbose names are not displayed, and a 1782 separate row is not displayed. They're displayed in the last row of the 1783 form, directly after that row's form element. 1760 1784 >>> class Person(Form): 1761 1785 ... first_name = CharField() … … 1767 1791 <tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr> 1768 1792 <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> 1793 <tr><td>Birthday:</td><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr> 1771 1794 >>> print p.as_ul() 1772 1795 <li>First name: <input type="text" name="first_name" /></li> 1773 1796 <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> 1797 <li>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></li> 1798 >>> print p.as_p() 1799 <p>First name: <input type="text" name="first_name" /></p> 1800 <p>Last name: <input type="text" name="last_name" /></p> 1801 <p>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></p> 1776 1802 1777 1803 With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label. … … 1780 1806 <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 1807 <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> 1808 <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 1809 >>> print p.as_ul() 1785 1810 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 1786 1811 <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 <li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li> 1812 <li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></li> 1813 >>> print p.as_p() 1814 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> 1815 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> 1816 <p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></p> 1789 1817 1790 1818 If a field with a HiddenInput has errors, the as_table() and as_ul() output 1791 1819 will include the error message(s) with the text "(Hidden field [fieldname]) " 1792 prepended. 1820 prepended. This message is displayed at the top of the output, regardless of 1821 its field's order in the form. 1793 1822 >>> p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}) 1794 1823 >>> print p 1824 <tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr> 1795 1825 <tr><td>First name:</td><td><input type="text" name="first_name" value="John" /></td></tr> 1796 1826 <tr><td>Last name:</td><td><input type="text" name="last_name" value="Lennon" /></td></tr> 1797 <tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr> 1798 <input type="hidden" name="hidden_text" /> 1799 <tr><td>Birthday:</td><td><input type="text" name="birthday" value="1940-10-9" /></td></tr> 1827 <tr><td>Birthday:</td><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr> 1800 1828 >>> print p.as_ul() 1829 <li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li> 1801 1830 <li>First name: <input type="text" name="first_name" value="John" /></li> 1802 1831 <li>Last name: <input type="text" name="last_name" value="Lennon" /></li> 1803 <li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li> 1804 <input type="hidden" name="hidden_text" /> 1805 <li>Birthday: <input type="text" name="birthday" value="1940-10-9" /></li> 1832 <li>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></li> 1833 >>> print p.as_p() 1834 <p><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></p> 1835 <p>First name: <input type="text" name="first_name" value="John" /></p> 1836 <p>Last name: <input type="text" name="last_name" value="Lennon" /></p> 1837 <p>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></p> 1838 1839 A corner case: It's possible for a form to have only HiddenInputs. 1840 >>> class TestForm(Form): 1841 ... foo = CharField(widget=HiddenInput) 1842 ... bar = CharField(widget=HiddenInput) 1843 >>> p = TestForm() 1844 >>> print p.as_table() 1845 <input type="hidden" name="foo" /><input type="hidden" name="bar" /> 1846 >>> print p.as_ul() 1847 <input type="hidden" name="foo" /><input type="hidden" name="bar" /> 1848 >>> print p.as_p() 1849 <input type="hidden" name="foo" /><input type="hidden" name="bar" /> 1806 1850 1807 1851 A Form's fields are displayed in the same order in which they were defined. django/branches/generic-auth/tests/regressiontests/templates/tests.py
r4063 r4184 1 # -*- coding: utf-8 -*- 1 2 from django.conf import settings 2 3 … … 63 64 return "OtherClass.method" 64 65 66 class UnicodeInStrClass: 67 "Class whose __str__ returns a Unicode object." 68 def __str__(self): 69 return u'ŠĐĆŽćžšđ' 70 65 71 class Templates(unittest.TestCase): 66 72 def test_templates(self): … … 173 179 # Empty strings can be passed as arguments to filters 174 180 'basic-syntax36': (r'{{ var|join:"" }}', {'var': ['a', 'b', 'c']}, 'abc'), 181 182 # If a variable has a __str__() that returns a Unicode object, the value 183 # will be converted to a bytestring. 184 'basic-syntax37': (r'{{ var }}', {'var': UnicodeInStrClass()}, '\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91'), 175 185 176 186 ### COMMENT SYNTAX ######################################################## … … 329 339 'ifchanged06': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (2, 2, 2)}, '1222'), 330 340 'ifchanged07': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% for y in numy %}{% ifchanged %}{{ y }}{% endifchanged %}{% endfor %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (2, 2, 2), 'numy': (3, 3, 3)}, '1233323332333'), 331 341 332 342 # Test one parameter given to ifchanged. 333 343 'ifchanged-param01': ('{% for n in num %}{% ifchanged n %}..{% endifchanged %}{{ n }}{% endfor %}', { 'num': (1,2,3) }, '..1..2..3'), 334 344 'ifchanged-param02': ('{% for n in num %}{% for x in numx %}{% ifchanged n %}..{% endifchanged %}{{ x }}{% endfor %}{% endfor %}', { 'num': (1,2,3), 'numx': (5,6,7) }, '..567..567..567'), 335 345 336 346 # Test multiple parameters to ifchanged. 337 347 'ifchanged-param03': ('{% for n in num %}{{ n }}{% for x in numx %}{% ifchanged x n %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1,1,2), 'numx': (5,6,6) }, '156156256'), 338 348 339 349 # Test a date+hour like construct, where the hour of the last day 340 350 # is the same but the date had changed, so print the hour anyway. 341 351 'ifchanged-param04': ('{% for d in days %}{% ifchanged %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'), 342 352 343 353 # Logically the same as above, just written with explicit 344 354 # ifchanged for the day.
