Django

Code

Changeset 4184

Show
Ignore:
Timestamp:
12/07/06 17:15:08 (2 years ago)
Author:
jkocherhans
Message:

generic-auth: Merged to trunk [4183].

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/generic-auth/django/contrib/admin/templates/admin/search_form.html

    r3097 r4184  
    88<input type="submit" value="{% trans 'Go' %}" /> 
    99{% 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> 
    1111{% endif %} 
    1212{% for pair in cl.params.items %} 
  • django/branches/generic-auth/django/contrib/admin/views/main.py

    r4026 r4184  
    228228    model = models.get_model(app_label, model_name) 
    229229    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)
    231231    opts = model._meta 
    232232 
     
    308308    object_id = unquote(object_id) 
    309309    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)
    311311    opts = model._meta 
    312312 
     
    316316    try: 
    317317        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))) 
    320320 
    321321    if not has_permission(request.user, opts.get_change_permission(), manipulator.original_object): 
     
    493493    object_id = unquote(object_id) 
    494494    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)
    496496    opts = model._meta 
    497497    obj = get_object_or_404(model, pk=object_id) 
     
    530530    object_id = unquote(object_id) 
    531531    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)
    533533    action_list = LogEntry.objects.filter(object_id=object_id, 
    534534        content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time') 
     
    746746    model = models.get_model(app_label, model_name) 
    747747    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)
    749749    # There isn't a specific object to check here, so don't pass one to  
    750750    # has_permission. There should be a has_permission implementation  
  • django/branches/generic-auth/django/contrib/contenttypes/management.py

    r4026 r4184  
    44 
    55from django.dispatch import dispatcher 
    6 from django.db.models import get_models, signals 
     6from django.db.models import get_apps, get_models, signals 
    77 
    8 def create_contenttypes(app, created_models, verbosity): 
     8def create_contenttypes(app, created_models, verbosity=2): 
    99    from django.contrib.contenttypes.models import ContentType 
    1010    app_models = get_models(app) 
     
    2323                print "Adding content type '%s | %s'" % (ct.app_label, ct.model) 
    2424 
     25def create_all_contenttypes(verbosity=2): 
     26    for app in get_apps(): 
     27        create_contenttypes(app, None, verbosity) 
     28 
    2529dispatcher.connect(create_contenttypes, signal=signals.post_syncdb) 
     30 
     31if __name__ == "__main__": 
     32    create_all_contenttypes() 
  • django/branches/generic-auth/django/contrib/sitemaps/__init__.py

    r4026 r4184  
    3030    from django.contrib.sites.models import Site 
    3131    current_site = Site.objects.get_current() 
    32     url = "%s%s" % (current_site.domain, sitemap
     32    url = "%s%s" % (current_site.domain, sitemap_url
    3333    params = urllib.urlencode({'sitemap':url}) 
    3434    urllib.urlopen("%s?%s" % (ping_url, params)) 
  • django/branches/generic-auth/django/core/servers/fastcgi.py

    r4063 r4184  
    119119        return fastcgi_help("ERROR: Implementation must be one of prefork or thread.") 
    120120 
     121    wsgi_opts['debug'] = False # Turn off flup tracebacks 
     122 
    121123    # Prep up and go 
    122124    from django.core.handlers.wsgi import WSGIHandler 
  • django/branches/generic-auth/django/newforms/fields.py

    r4149 r4184  
    33""" 
    44 
    5 from util import ValidationError, DEFAULT_ENCODING, smart_unicode 
     5from django.utils.translation import gettext 
     6from util import ValidationError, smart_unicode 
    67from widgets import TextInput, CheckboxInput, Select, SelectMultiple 
    78import datetime 
     
    5152        """ 
    5253        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.')
    5455        return value 
    5556 
     
    6566        value = smart_unicode(value) 
    6667        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) 
    6869        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) 
    7071        return value 
    7172 
     
    8283            return int(value) 
    8384        except (ValueError, TypeError): 
    84             raise ValidationError(u'Enter a whole number.'
     85            raise ValidationError(gettext(u'Enter a whole number.')
    8586 
    8687DEFAULT_DATE_INPUT_FORMATS = ( 
     
    114115            except ValueError: 
    115116                continue 
    116         raise ValidationError(u'Enter a valid date.'
     117        raise ValidationError(gettext(u'Enter a valid date.')
    117118 
    118119DEFAULT_DATETIME_INPUT_FORMATS = ( 
     
    150151            except ValueError: 
    151152                continue 
    152         raise ValidationError(u'Enter a valid date/time.'
     153        raise ValidationError(gettext(u'Enter a valid date/time.')
    153154 
    154155class RegexField(Field): 
     
    163164            regex = re.compile(regex) 
    164165        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.') 
    166167 
    167168    def clean(self, value): 
     
    186187class EmailField(RegexField): 
    187188    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) 
    189190 
    190191url_re = re.compile( 
     
    204205    def __init__(self, required=True, verify_exists=False, widget=None, 
    205206            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) 
    207208        self.verify_exists = verify_exists 
    208209        self.user_agent = validator_user_agent 
     
    224225                u = urllib2.urlopen(req) 
    225226            except ValueError: 
    226                 raise ValidationError(u'Enter a valid URL.'
     227                raise ValidationError(gettext(u'Enter a valid URL.')
    227228            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.')
    229230        return value 
    230231 
     
    255256        valid_values = set([str(k) for k, v in self.choices]) 
    256257        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) 
    258259        return value 
    259260 
     
    267268        """ 
    268269        if self.required and not value: 
    269             raise ValidationError(u'This field is required.'
     270            raise ValidationError(gettext(u'This field is required.')
    270271        elif not self.required and not value: 
    271272            return [] 
    272273        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.')
    274275        new_value = [] 
    275276        for val in value: 
     
    280281        for val in new_value: 
    281282            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) 
    283284        return new_value 
    284285 
  • django/branches/generic-auth/django/newforms/forms.py

    r4149 r4184  
    77from fields import Field 
    88from widgets import TextInput, Textarea, HiddenInput 
    9 from util import ErrorDict, ErrorList, ValidationError 
     9from util import StrAndUnicode, ErrorDict, ErrorList, ValidationError 
    1010 
    1111NON_FIELD_ERRORS = '__all__' 
     
    3333        return type.__new__(cls, name, bases, attrs) 
    3434 
    35 class Form(object): 
     35class Form(StrAndUnicode): 
    3636    "A collection of Fields, plus their associated data." 
    3737    __metaclass__ = DeclarativeFieldsMetaclass 
     
    4444        self.__errors = None # Stores the errors after clean() has been called. 
    4545 
    46     def __str__(self): 
     46    def __unicode__(self): 
    4747        return self.as_table() 
    4848 
     
    7373        return not self.ignore_errors and not bool(self.errors) 
    7474 
     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 
    75102    def as_table(self): 
    76103        "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) 
    93105 
    94106    def as_ul(self): 
    95107        "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) 
    110113 
    111114    def non_field_errors(self): 
     
    156159        return self.clean_data 
    157160 
    158 class BoundField(object): 
     161class BoundField(StrAndUnicode): 
    159162    "A Field plus data" 
    160163    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 
     168    def __unicode__(self): 
    166169        "Renders this field as an HTML widget." 
    167170        # Use the 'widget' attribute on the field to determine which type 
    168171        # of HTML widget to use. 
    169         value = self.as_widget(self._field.widget) 
     172        value = self.as_widget(self.field.widget) 
    170173        if not isinstance(value, basestring): 
    171174            # Some Widget render() methods -- notably RadioSelect -- return a 
     
    180183        if there are none. 
    181184        """ 
    182         try: 
    183             return self._form.errors[self._name] 
    184         except KeyError: 
    185             return ErrorList() 
     185        return self.form.errors.get(self.name, ErrorList()) 
    186186    errors = property(_errors) 
    187187 
     
    191191        if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'): 
    192192            attrs['id'] = auto_id 
    193         return widget.render(self._name, self.data, attrs=attrs) 
     193        return widget.render(self.name, self.data, attrs=attrs) 
    194194 
    195195    def as_text(self, attrs=None): 
     
    211211    def _data(self): 
    212212        "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) 
    214214    data = property(_data) 
    215215 
    216216    def _verbose_name(self): 
    217         return pretty_name(self._name) 
     217        return pretty_name(self.name) 
    218218    verbose_name = property(_verbose_name) 
    219219 
     
    225225        """ 
    226226        contents = contents or escape(self.verbose_name) 
    227         widget = self._field.widget 
     227        widget = self.field.widget 
    228228        id_ = widget.attrs.get('id') or self.auto_id 
    229229        if id_: 
     
    233233    def _is_hidden(self): 
    234234        "Returns True if this BoundField's widget is hidden." 
    235         return self._field.widget.is_hidden 
     235        return self.field.widget.is_hidden 
    236236    is_hidden = property(_is_hidden) 
    237237 
     
    241241        associated Form has specified auto_id. Returns an empty string otherwise. 
    242242        """ 
    243         auto_id = self._form.auto_id 
     243        auto_id = self.form.auto_id 
    244244        if auto_id and '%s' in str(auto_id): 
    245             return str(auto_id) % self._name 
     245            return str(auto_id) % self.name 
    246246        elif auto_id: 
    247             return self._name 
     247            return self.name 
    248248        return '' 
    249249    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. 
     1from django.conf import settings 
    32 
    43def smart_unicode(s): 
     
    65        s = unicode(str(s)) 
    76    elif not isinstance(s, unicode): 
    8         s = unicode(s, DEFAULT_ENCODING
     7        s = unicode(s, settings.DEFAULT_CHARSET
    98    return s 
     9 
     10class 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) 
    1019 
    1120class ErrorDict(dict): 
  • django/branches/generic-auth/django/newforms/widgets.py

    r4149 r4184  
    99) 
    1010 
    11 from util import smart_unicode 
     11from util import StrAndUnicode, smart_unicode 
    1212from django.utils.html import escape 
    1313from itertools import chain 
     
    147147        return u'\n'.join(output) 
    148148 
    149 class RadioInput(object): 
     149class RadioInput(StrAndUnicode): 
    150150    "An object used by RadioFieldRenderer that represents a single <input type='radio'>." 
    151151    def __init__(self, name, value, attrs, choice, index): 
     
    155155        self.index = index 
    156156 
    157     def __str__(self): 
     157    def __unicode__(self): 
    158158        return u'<label>%s %s</label>' % (self.tag(), self.choice_label) 
    159159 
     
    169169        return u'<input%s />' % flatatt(final_attrs) 
    170170 
    171 class RadioFieldRenderer(object): 
     171class RadioFieldRenderer(StrAndUnicode): 
    172172    "An object used by RadioSelect to enable customization of radio widgets." 
    173173    def __init__(self, name, value, attrs, choices): 
     
    179179            yield RadioInput(self.name, self.value, self.attrs.copy(), choice, i) 
    180180 
    181     def __str__(self): 
     181    def __unicode__(self): 
    182182        "Outputs a <ul> for this set of radio fields." 
    183183        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  
    743743        # Check type so that we don't run str() on a Unicode object 
    744744        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) 
    746750        elif isinstance(output, unicode): 
    747751            return output.encode(settings.DEFAULT_CHARSET) 
  • django/branches/generic-auth/docs/add_ons.txt

    r4026 r4184  
    4848 
    4949.. _csrf documentation: http://www.djangoproject.com/documentation/csrf/ 
     50 
     51formtools 
     52========= 
     53 
     54**New in Django development version** 
     55 
     56A set of high-level abstractions for Django forms (django.newforms). 
     57 
     58django.contrib.formtools.preview 
     59-------------------------------- 
     60 
     61An abstraction of the following workflow: 
     62 
     63"Display an HTML form, force a preview, then do something with the submission." 
     64 
     65Full documentation for this feature does not yet exist, but you can read the 
     66code and docstrings in ``django/contrib/formtools/preview.py`` for a start. 
    5067 
    5168humanize 
  • django/branches/generic-auth/docs/settings.txt

    r4063 r4184  
    831831exist (see the ``verify_exists`` option on URLField_). 
    832832 
    833 .. URLField: ../model_api/#urlfield 
     833.. _URLField: ../model_api/#urlfield 
    834834 
    835835USE_ETAGS 
  • django/branches/generic-auth/docs/testing.txt

    r4063 r4184  
    134134 
    135135For developers new to testing, however, this choice can seem 
    136 confusing, so here are a few key differences to help you decide weather 
     136confusing, so here are a few key differences to help you decide whether 
    137137doctests or unit tests are right for you. 
    138138 
  • django/branches/generic-auth/tests/regressiontests/forms/tests.py

    r4149 r4184  
    13691369<li><ul class="errorlist"><li>This field is required.</li></ul>Last name: <input type="text" name="last_name" /></li> 
    13701370<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> 
    13711378 
    13721379If you don't pass any values to the Form's __init__(), or if you pass None, 
     
    13901397<li>Last name: <input type="text" name="last_name" /></li> 
    13911398<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> 
    13921403 
    13931404Unicode values are handled properly. 
     
    13971408>>> p.as_ul() 
    13981409u'<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() 
     1411u'<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>' 
    13991412 
    14001413>>> p = Person({'last_name': u'Lennon'}) 
     
    14331446the human-readable labels for a field. 
    14341447>>> 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> 
    14351452>>> print p.as_ul() 
    14361453<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 
    14371454<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> 
    14381455<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
    14431460 
    14441461If auto_id is any True value whose str() does not contain '%s', the "id" 
     
    15971614<li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 
    15981615</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> 
    15991622 
    16001623MultipleChoiceField is a special case, as its data is required to be a list: 
     
    17551778<tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr> 
    17561779 
    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. 
     1780HiddenInput widgets are displayed differently in the as_table(), as_ul() 
     1781and as_p() output of a Form -- their verbose names are not displayed, and a 
     1782separate row is not displayed. They're displayed in the last row of the 
     1783form, directly after that row's form element. 
    17601784>>> class Person(Form): 
    17611785...     first_name = CharField() 
     
    17671791<tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr> 
    17681792<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> 
    17711794>>> print p.as_ul() 
    17721795<li>First name: <input type="text" name="first_name" /></li> 
    17731796<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> 
    17761802 
    17771803With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label. 
     
    17801806<tr><td><label for="id_first_name">First name:</label></td><td><input type="text" name="first_name" id="id_first_name" /></td></tr> 
    17811807<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> 
    17841809>>> print p.as_ul() 
    17851810<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 
    17861811<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> 
    17891817 
    17901818If a field with a HiddenInput has errors, the as_table() and as_ul() output 
    17911819will include the error message(s) with the text "(Hidden field [fieldname]) " 
    1792 prepended. 
     1820prepended. This message is displayed at the top of the output, regardless of 
     1821its field's order in the form. 
    17931822>>> p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}) 
    17941823>>> print p 
     1824<tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr> 
    17951825<tr><td>First name:</td><td><input type="text" name="first_name" value="John" /></td></tr> 
    17961826<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> 
    18001828>>> print p.as_ul() 
     1829<li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li> 
    18011830<li>First name: <input type="text" name="first_name" value="John" /></li> 
    18021831<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 
     1839A 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" /> 
    18061850 
    18071851A 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 -*- 
    12from django.conf import settings 
    23 
     
    6364        return "OtherClass.method" 
    6465 
     66class UnicodeInStrClass: 
     67    "Class whose __str__ returns a Unicode object." 
     68    def __str__(self): 
     69        return u'ŠĐĆŽćžšđ' 
     70 
    6571class Templates(unittest.TestCase): 
    6672    def test_templates(self): 
     
    173179            # Empty strings can be passed as arguments to filters 
    174180            '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'), 
    175185 
    176186            ### COMMENT SYNTAX ######################################################## 
     
    329339            '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'), 
    330340            '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 
    332342            # Test one parameter given to ifchanged. 
    333343            'ifchanged-param01': ('{% for n in num %}{% ifchanged n %}..{% endifchanged %}{{ n }}{% endfor %}', { 'num': (1,2,3) }, '..1..2..3'), 
    334344            '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 
    336346            # Test multiple parameters to ifchanged. 
    337347            '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 
    339349            # Test a date+hour like construct, where the hour of the last day 
    340350            # is the same but the date had changed, so print the hour anyway. 
    341351            '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 
    343353            # Logically the same as above, just written with explicit 
    344354            # ifchanged for the day.