Django

Code

Changeset 4189

Show
Ignore:
Timestamp:
12/10/06 09:43:51 (2 years ago)
Author:
jpellerin
Message:

[multi-db] Merged trunk to [4188]. Some tests still failing.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/multiple-db-support/django/contrib/admin/templates/admin/search_form.html

    r3097 r4189  
    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/multiple-db-support/django/contrib/admin/views/main.py

    r4155 r4189  
    227227    model = models.get_model(app_label, model_name) 
    228228    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)
    230230    opts = model._meta 
    231231 
     
    303303    object_id = unquote(object_id) 
    304304    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)
    306306    opts = model._meta 
    307307 
     
    314314    try: 
    315315        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))) 
    318318 
    319319    if request.POST: 
     
    491491    object_id = unquote(object_id) 
    492492    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)
    494494    opts = model._meta 
    495495    if not request.user.has_perm(app_label + '.' + opts.get_delete_permission()): 
     
    528528    object_id = unquote(object_id) 
    529529    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)
    531531    action_list = LogEntry.objects.filter(object_id=object_id, 
    532532        content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time') 
     
    744744    model = models.get_model(app_label, model_name) 
    745745    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)
    747747    if not request.user.has_perm(app_label + '.' + model._meta.get_change_permission()): 
    748748        raise PermissionDenied 
  • django/branches/multiple-db-support/django/contrib/contenttypes/management.py

    r3665 r4189  
    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/multiple-db-support/django/contrib/sitemaps/__init__.py

    r3739 r4189  
    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/multiple-db-support/django/core/servers/fastcgi.py

    r4157 r4189  
    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/multiple-db-support/django/newforms/fields.py

    r4159 r4189  
    33""" 
    44 
    5 from util import ValidationError, DEFAULT_ENCODING, smart_unicode 
    6 from widgets import TextInput, CheckboxInput, Select, SelectMultiple 
     5from django.utils.translation import gettext 
     6from util import ValidationError, smart_unicode 
     7from widgets import TextInput, PasswordInput, CheckboxInput, Select, SelectMultiple 
    78import datetime 
    89import re 
     
    3233    creation_counter = 0 
    3334 
    34     def __init__(self, required=True, widget=None): 
    35         self.required = required 
     35    def __init__(self, required=True, widget=None, label=None): 
     36        self.required, self.label = required, label 
    3637        widget = widget or self.widget 
    3738        if isinstance(widget, type): 
    3839            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 
    3946        self.widget = widget 
    4047 
     
    5158        """ 
    5259        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 {} 
    5570 
    5671class 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): 
    5973        self.max_length, self.min_length = max_length, min_length 
     74        Field.__init__(self, required, widget, label) 
    6075 
    6176    def clean(self, value): 
     
    6580        value = smart_unicode(value) 
    6681        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) 
    6883        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)} 
    7190 
    7291class IntegerField(Field): 
     
    82101            return int(value) 
    83102        except (ValueError, TypeError): 
    84             raise ValidationError(u'Enter a whole number.'
     103            raise ValidationError(gettext(u'Enter a whole number.')
    85104 
    86105DEFAULT_DATE_INPUT_FORMATS = ( 
     
    93112 
    94113class 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
    97116        self.input_formats = input_formats or DEFAULT_DATE_INPUT_FORMATS 
    98117 
     
    114133            except ValueError: 
    115134                continue 
    116         raise ValidationError(u'Enter a valid date.'
     135        raise ValidationError(gettext(u'Enter a valid date.')
    117136 
    118137DEFAULT_DATETIME_INPUT_FORMATS = ( 
     
    129148 
    130149class 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
    133152        self.input_formats = input_formats or DEFAULT_DATETIME_INPUT_FORMATS 
    134153 
     
    150169            except ValueError: 
    151170                continue 
    152         raise ValidationError(u'Enter a valid date/time.'
     171        raise ValidationError(gettext(u'Enter a valid date/time.')
    153172 
    154173class 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): 
    156175        """ 
    157176        regex can be either a string or a compiled regular expression object. 
     
    159178        'Enter a valid value' is too generic for you. 
    160179        """ 
    161         Field.__init__(self, required, widget
     180        Field.__init__(self, required, widget, label
    162181        if isinstance(regex, basestring): 
    163182            regex = re.compile(regex) 
    164183        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.') 
    166185 
    167186    def clean(self, value): 
     
    185204 
    186205class 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
    189208 
    190209url_re = re.compile( 
     
    202221 
    203222class 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, 
    205224            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
    207226        self.verify_exists = verify_exists 
    208227        self.user_agent = validator_user_agent 
     
    224243                u = urllib2.urlopen(req) 
    225244            except ValueError: 
    226                 raise ValidationError(u'Enter a valid URL.'
     245                raise ValidationError(gettext(u'Enter a valid URL.')
    227246            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.')
    229248        return value 
    230249 
     
    238257 
    239258class ChoiceField(Field): 
    240     def __init__(self, choices=(), required=True, widget=Select): 
     259    def __init__(self, choices=(), required=True, widget=Select, label=None): 
    241260        if isinstance(widget, type): 
    242261            widget = widget(choices=choices) 
    243         Field.__init__(self, required, widget
     262        Field.__init__(self, required, widget, label
    244263        self.choices = choices 
    245264 
     
    255274        valid_values = set([str(k) for k, v in self.choices]) 
    256275        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) 
    258277        return value 
    259278 
    260279class 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
    263282 
    264283    def clean(self, value): 
     
    267286        """ 
    268287        if self.required and not value: 
    269             raise ValidationError(u'This field is required.'
     288            raise ValidationError(gettext(u'This field is required.')
    270289        elif not self.required and not value: 
    271290            return [] 
    272291        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.')
    274293        new_value = [] 
    275294        for val in value: 
     
    277296            new_value.append(val) 
    278297        # Validate that each value in the value list is in self.choices. 
    279         valid_values = set([k for k, v in self.choices]) 
     298        valid_values = set([smart_unicode(k) for k, v in self.choices]) 
    280299        for val in new_value: 
    281300            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) 
    283302        return new_value 
    284303 
    285304class 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
    288307        # Set 'required' to False on the individual fields, because the 
    289308        # required validation will be handled by ComboField, not by those 
  • django/branches/multiple-db-support/django/newforms/forms.py

    r4159 r4189  
    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.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 
    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        self.label = self.field.label or pretty_name(name) 
     168 
     169    def __unicode__(self): 
    166170        "Renders this field as an HTML widget." 
    167171        # Use the 'widget' attribute on the field to determine which type 
    168172        # of HTML widget to use. 
    169         value = self.as_widget(self._field.widget) 
     173        value = self.as_widget(self.field.widget) 
    170174        if not isinstance(value, basestring): 
    171175            # Some Widget render() methods -- notably RadioSelect -- return a 
     
    180184        if there are none. 
    181185        """ 
    182         try: 
    183             return self._form.errors[self._name] 
    184         except KeyError: 
    185             return ErrorList() 
     186        return self.form.errors.get(self.name, ErrorList()) 
    186187    errors = property(_errors) 
    187188 
     
    191192        if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'): 
    192193            attrs['id'] = auto_id 
    193         return widget.render(self._name, self.data, attrs=attrs) 
     194        return widget.render(self.name, self.data, attrs=attrs) 
    194195 
    195196    def as_text(self, attrs=None): 
     
    211212    def _data(self): 
    212213        "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) 
    214215    data = property(_data) 
    215  
    216     def _verbose_name(self): 
    217         return pretty_name(self._name) 
    218     verbose_name = property(_verbose_name) 
    219216 
    220217    def label_tag(self, contents=None): 
     
    222219        Wraps the given contents in a <label>, if the field has an ID attribute. 
    223220        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.widget 
     221        field's HTML-escaped label
     222        """ 
     223        contents = contents or escape(self.label
     224        widget = self.field.widget 
    228225        id_ = widget.attrs.get('id') or self.auto_id 
    229226        if id_: 
     
    233230    def _is_hidden(self): 
    234231        "Returns True if this BoundField's widget is hidden." 
    235         return self._field.widget.is_hidden 
     232        return self.field.widget.is_hidden 
    236233    is_hidden = property(_is_hidden) 
    237234 
     
    241238        associated Form has specified auto_id. Returns an empty string otherwise. 
    242239        """ 
    243         auto_id = self._form.auto_id 
     240        auto_id = self.form.auto_id 
    244241        if auto_id and '%s' in str(auto_id): 
    245             return str(auto_id) % self._name 
     242            return str(auto_id) % self.name 
    246243        elif auto_id: 
    247             return self._name 
     244            return self.name 
    248245        return '' 
    249246    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. 
     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/multiple-db-support/django/newforms/widgets.py

    r4159 r4189  
    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/multiple-db-support/django/template/__init__.py

    r4157 r4189  
    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/multiple-db-support/docs/add_ons.txt

    r3712 r4189  
    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/multiple-db-support/docs/settings.txt

    r4157 r4189  
    838838exist (see the ``verify_exists`` option on URLField_). 
    839839 
    840 .. URLField: ../model_api/#urlfield 
     840.. _URLField: ../model_api/#urlfield 
    841841 
    842842USE_ETAGS 
  • django/branches/multiple-db-support/tests/regressiontests/forms/tests.py

    r4159 r4189  
    637637              Widget that it'll use if you don't specify this. In most cases, 
    638638              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. 
    639642 
    640643Other than that, the Field subclasses have class-specific options for 
     
    13361339<input type="text" name="birthday" value="1940-10-9" /> 
    13371340>>> for boundfield in p: 
    1338 ...     print boundfield.verbose_name, boundfield.data 
     1341...     print boundfield.label, boundfield.data 
    13391342First name John 
    13401343Last name Lennon 
     
    13691372<li><ul class="errorlist"><li>This field is required.</li></ul>Last name: <input type="text" name="last_name" /></li> 
    13701373<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> 
    13711381 
    13721382If you don't pass any values to the Form's __init__(), or if you pass None, 
     
    13901400<li>Last name: <input type="text" name="last_name" /></li> 
    13911401<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> 
    13921406 
    13931407Unicode values are handled properly. 
     
    13971411>>> p.as_ul() 
    13981412u'<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() 
     1414u'<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>' 
    13991415 
    14001416>>> p = Person({'last_name': u'Lennon'}) 
     
    14331449the human-readable labels for a field. 
    14341450>>> 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> 
    14351455>>> print p.as_ul() 
    14361456<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 
    14371457<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> 
    14381458<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
    14431463 
    14441464If auto_id is any True value whose str() does not contain '%s', the "id" 
     
    15971617<li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 
    15981618</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> 
    15991625 
    16001626MultipleChoiceField is a special case, as its data is required to be a list: 
     
    17141740>>> print f.as_table() 
    17151741<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> 
    17171743<tr><td colspan="2"><ul class="errorlist"><li>This field is required.</li></ul></td></tr> 
    17181744<tr><td>Password1:</td><td><input type="password" name="password1" /></td></tr> 
     
    17261752>>> print f.as_table() 
    17271753<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> 
    17291755<tr><td>Password1:</td><td><input type="password" name="password1" value="foo" /></td></tr> 
    17301756<tr><td>Password2:</td><td><input type="password" name="password2" value="bar" /></td></tr> 
    17311757>>> print f.as_ul() 
    17321758<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> 
    17341760<li>Password1: <input type="password" name="password1" value="foo" /></li> 
    17351761<li>Password2: <input type="password" name="password2" value="bar" /></li> 
     
    17551781<tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr> 
    17561782 
    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. 
     1783HiddenInput widgets are displayed differently in the as_table(), as_ul() 
     1784and as_p() output of a Form -- their verbose names are not displayed, and a 
     1785separate row is not displayed. They're displayed in the last row of the 
     1786form, directly after that row's form element. 
    17601787>>> class Person(Form): 
    17611788...     first_name = CharField() 
     
    17671794<tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr> 
    17681795<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> 
    17711797>>> print p.as_ul() 
    17721798<li>First name: <input type="text" name="first_name" /></li> 
    17731799<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> 
    17761805 
    17771806With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label. 
     
    17801809<tr><td><label for="id_first_name">First name:</label></td><td><input type="text" name="first_name" id="id_first_name" /></td></tr> 
    17811810<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> 
    17841812>>> print p.as_ul() 
    17851813<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> 
    17861814<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> 
     1815<li><label for="id_birthday"&g