Commits

Anonymous committed 040a190

Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.

Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702

Comments (0)

Files changed (193)

     Simon Greenhill <dev@simon.net.nz>
     Owen Griffiths
     Espen Grindhaug <http://grindhaug.org/>
+    Thomas GĂźttler <hv@tbz-pariv.de>
     Brian Harring <ferringb@gmail.com>
     Brant Harris
     Hawkeye
     Bruce Kroeze <http://coderseye.com/>
     Joseph Kocherhans
     konrad@gwu.edu
+    kurtiss@meetro.com
     lakin.wecker@gmail.com
     Nick Lane <nick.lane.au@gmail.com>
     Stuart Langridge <http://www.kryogenix.org/>

django/bin/make-messages.py

                         open(os.path.join(dirpath, '%s.py' % file), "wb").write(templatize(src))
                         thefile = '%s.py' % file
                     if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
-                    cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
+                    cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
                         os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
                     (stdin, stdout, stderr) = os.popen3(cmd, 'b')
                     msgs = stdout.read()

django/conf/global_settings.py

 DEFAULT_CONTENT_TYPE = 'text/html'
 DEFAULT_CHARSET = 'utf-8'
 
+# Encoding of files read from disk (template and initial SQL files).
+FILE_CHARSET = 'utf-8'
+
 # E-mail address that error messages come from.
 SERVER_EMAIL = 'root@localhost'
 

django/contrib/admin/filterspecs.py

 """
 
 from django.db import models
+from django.utils.encoding import smart_unicode, iri_to_uri
+from django.utils.translation import ugettext as _
 import datetime
 
 class FilterSpec(object):
     def output(self, cl):
         t = []
         if self.has_output():
-            t.append(_('<h3>By %s:</h3>\n<ul>\n') % self.title())
+            t.append(_(u'<h3>By %s:</h3>\n<ul>\n') % self.title())
 
             for choice in self.choices(cl):
-                t.append('<li%s><a href="%s">%s</a></li>\n' % \
+                t.append(u'<li%s><a href="%s">%s</a></li>\n' % \
                     ((choice['selected'] and ' class="selected"' or ''),
-                     choice['query_string'] ,
+                     iri_to_uri(choice['query_string']),
                      choice['display']))
             t.append('</ul>\n\n')
         return "".join(t)
                'display': _('All')}
         for val in self.lookup_choices:
             pk_val = getattr(val, self.field.rel.to._meta.pk.attname)
-            yield {'selected': self.lookup_val == str(pk_val),
+            yield {'selected': self.lookup_val == smart_unicode(pk_val),
                    'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}),
                    'display': val}
 
                'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
                'display': _('All')}
         for k, v in self.field.choices:
-            yield {'selected': str(k) == self.lookup_val,
+            yield {'selected': smart_unicode(k) == self.lookup_val,
                     'query_string': cl.get_query_string({self.lookup_kwarg: k}),
                     'display': v}
 
                'query_string': cl.get_query_string({}, [self.field.name]),
                'display': _('All')}
         for val in self.lookup_choices:
-            val = str(val[self.field.name])
+            val = smart_unicode(val[self.field.name])
             yield {'selected': self.lookup_val == val,
                    'query_string': cl.get_query_string({self.field.name: val}),
                    'display': val}

django/contrib/admin/media/js/urlify.js

+var LATIN_MAP =
+{
+    'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Ă
+    'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
+    'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
+    'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ý': 'Y', 'Þ': 'TH',
+    'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ':
+    'ae', 'ç': 'c', 'è': 'e', 'Ê': 'e', 'ê': 'e', 'Í': 'e', 'Ï': 'i', 'í': 'i',
+    'Î': 'i', 'ï': 'i', 'ð': 'o', 'ù': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'þ':
+    'o', 'Ü': 'o', 'ø': 'o', 'Ú': 'u', 'ú': 'u', 'Ý': 'u', 'ß': 'u', 'ý': 'y',
+    'Ăž': 'th', 'Ăż': 'y',
+}
+var LATIN_SYMBOLS_MAP =
+{
+    'Š':'(c)',
+}
+var GREEK_MAP =
+{
+    'ι':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ξ':'e', 'Μ':'z', 'Ρ':'h', 'θ':'8',
+    'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p',
+    'ρ':'r', 'σ':'s', 'τ':'t', 'Ď
+    'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s',
+    'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i',
+    'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8',
+    'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P',
+    'Υ':'R', 'Σ':'S', 'Τ':'T', 'μ':'Y', 'Ό':'F', 'Χ':'X', 'Ψ':'PS', 'Ί':'W',
+    'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I',
+    'ÎŤ':'Y'
+}
+var TURKISH_MAP = {
+    'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U',
+    'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G',
+}
+// var RUSSIAN_MAP =
+// {
+// }
+
+var ALL_DOWNCODE_MAPS=new Array()
+ALL_DOWNCODE_MAPS[0]=LATIN_MAP
+ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
+ALL_DOWNCODE_MAPS[2]=GREEK_MAP
+ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
+//ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
+
+var Downcoder = new Object();
+Downcoder.Initialize = function()
+{
+    if (Downcoder.map) // already made
+        return ;
+    Downcoder.map ={}
+    Downcoder.chars = '' ;
+    for(var i in ALL_DOWNCODE_MAPS)
+    {
+        var lookup = ALL_DOWNCODE_MAPS[i]
+        for (var c in lookup)
+        {
+            Downcoder.map[c] = lookup[c] ;
+            Downcoder.chars += c ;
+        }
+     }
+    Downcoder.regex = new RegExp('[' + Downcoder.chars + ']|[^' + Downcoder.chars + ']+','g') ;
+}
+
+downcode= function( slug )
+{
+    Downcoder.Initialize() ;
+    var downcoded =""
+    var pieces = slug.match(Downcoder.regex);
+    if(pieces)
+    {
+        for (var i = 0 ; i < pieces.length ; i++)
+        {
+            if (pieces[i].length == 1)
+            {
+                var mapped = Downcoder.map[pieces[i]] ;
+                if (mapped != null)
+                {
+                    downcoded+=mapped;
+                    continue ;
+                }
+            }
+            downcoded+=pieces[i];
+        }
+    }
+    else
+    {
+        downcoded = slug;
+    }
+    return downcoded;
+}
+
+
 function URLify(s, num_chars) {
     // changes, e.g., "Petty theft" to "petty_theft"
     // remove all these words from the string before urlifying
+    s = downcode(s);
     removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from",
                   "is", "in", "into", "like", "of", "off", "on", "onto", "per",
                   "since", "than", "the", "this", "that", "to", "up", "via",
                   "with"];
     r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
     s = s.replace(r, '');
+    // if downcode doesn't hit, the char will be stripped here
     s = s.replace(/[^-\w\s]/g, '');  // remove unneeded chars
     s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
     s = s.replace(/[-\s]+/g, '-');   // convert spaces to hyphens
     s = s.toLowerCase();             // convert to lowercase
     return s.substring(0, num_chars);// trim to first num_chars chars
 }
+

django/contrib/admin/models.py

 from django.db import models
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.auth.models import User
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ugettext_lazy as _
+from django.utils.encoding import smart_unicode
 
 ADDITION = 1
 CHANGE = 2
 
 class LogEntryManager(models.Manager):
     def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''):
-        e = self.model(None, None, user_id, content_type_id, str(object_id), object_repr[:200], action_flag, change_message)
+        e = self.model(None, None, user_id, content_type_id, smart_unicode(object_id), object_repr[:200], action_flag, change_message)
         e.save()
 
 class LogEntry(models.Model):
         ordering = ('-action_time',)
 
     def __repr__(self):
-        return str(self.action_time)
+        return smart_unicode(self.action_time)
 
     def is_addition(self):
         return self.action_flag == ADDITION
         Returns the admin URL to edit the object represented by this log entry.
         This is relative to the Django admin index page.
         """
-        return "%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, self.object_id)
+        return u"%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, self.object_id)

django/contrib/admin/templates/admin/filter.html

 <ul>
 {% for choice in choices %}
     <li{% if choice.selected %} class="selected"{% endif %}>
-    <a href="{{ choice.query_string }}">{{ choice.display|escape }}</a></li>
+    <a href="{{ choice.query_string|iriencode }}">{{ choice.display|escape }}</a></li>
 {% endfor %}
 </ul>

django/contrib/admin/templatetags/admin_list.py

 from django.utils import dateformat
 from django.utils.html import escape
 from django.utils.text import capfirst
-from django.utils.translation import get_date_formats, get_partial_date_formats
+from django.utils.translation import get_date_formats, get_partial_date_formats, ugettext as _
+from django.utils.encoding import smart_unicode, smart_str, force_unicode
 from django.template import Library
 import datetime
 
 
 def paginator_number(cl,i):
     if i == DOT:
-        return '... '
+        return u'... '
     elif i == cl.page_num:
-        return '<span class="this-page">%d</span> ' % (i+1)
+        return u'<span class="this-page">%d</span> ' % (i+1)
     else:
-        return '<a href="%s"%s>%d</a> ' % (cl.get_query_string({PAGE_VAR: i}), (i == cl.paginator.pages-1 and ' class="end"' or ''), i+1)
+        return u'<a href="%s"%s>%d</a> ' % (cl.get_query_string({PAGE_VAR: i}), (i == cl.paginator.pages-1 and ' class="end"' or ''), i+1)
 paginator_number = register.simple_tag(paginator_number)
 
 def pagination(cl):
             admin_order_field = None
         except models.FieldDoesNotExist:
             # For non-field list_display values, check for the function
-            # attribute "short_description". If that doesn't exist, fall
-            # back to the method name. And __str__ is a special-case.
-            if field_name == '__str__':
-                header = lookup_opts.verbose_name
+            # attribute "short_description". If that doesn't exist, fall back
+            # to the method name. And __str__ and __unicode__ are special-cases.
+            if field_name == '__unicode__':
+                header = force_unicode(lookup_opts.verbose_name)
+            elif field_name == '__str__':
+                header = smart_str(lookup_opts.verbose_name)
             else:
                 attr = getattr(cl.model, field_name) # Let AttributeErrors propagate.
                 try:
 
 def _boolean_icon(field_val):
     BOOLEAN_MAPPING = {True: 'yes', False: 'no', None: 'unknown'}
-    return '<img src="%simg/admin/icon-%s.gif" alt="%s" />' % (settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val)
+    return u'<img src="%simg/admin/icon-%s.gif" alt="%s" />' % (settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val)
 
 def items_for_result(cl, result):
     first = True
                     allow_tags = True
                     result_repr = _boolean_icon(attr)
                 else:
-                    result_repr = str(attr)
+                    result_repr = smart_unicode(attr)
             except (AttributeError, ObjectDoesNotExist):
                 result_repr = EMPTY_CHANGELIST_VALUE
             else:
             elif f.choices:
                 result_repr = dict(f.choices).get(field_val, EMPTY_CHANGELIST_VALUE)
             else:
-                result_repr = escape(str(field_val))
-        if result_repr == '':
+                result_repr = escape(field_val)
+        if force_unicode(result_repr) == '':
             result_repr = '&nbsp;'
         # If list_display_links not defined, add the link tag to the first field
-        if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links: 
+        if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links:
             table_tag = {True:'th', False:'td'}[first]
             first = False
             url = cl.url_for_result(result)
-            result_id = str(getattr(result, pk)) # str() is needed in case of 23L (long ints)
-            yield ('<%s%s><a href="%s"%s>%s</a></%s>' % \
+            result_id = smart_unicode(getattr(result, pk)) # conversion to string is needed in case of 23L (long ints)
+            yield (u'<%s%s><a href="%s"%s>%s</a></%s>' % \
                 (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %r); return false;"' % result_id or ''), result_repr, table_tag))
         else:
-            yield ('<td%s>%s</td>' % (row_class, result_repr))
+            yield (u'<td%s>%s</td>' % (row_class, result_repr))
 
 def results(cl):
     for res in cl.result_list:

django/contrib/admin/templatetags/admin_modify.py

 from django.contrib.admin.views.main import AdminBoundField
 from django.template import loader
 from django.utils.text import capfirst
+from django.utils.encoding import force_unicode
 from django.db import models
 from django.db.models.fields import Field
 from django.db.models.related import BoundRelatedObject
 absolute_url_re = re.compile(r'^(?:http(?:s)?:/)?/', re.IGNORECASE)
 
 def class_name_to_underscored(name):
-    return '_'.join([s.lower() for s in word_re.findall(name)[:-1]])
+    return u'_'.join([s.lower() for s in word_re.findall(name)[:-1]])
 
 def include_admin_script(script_path):
     """
     """
     if not absolute_url_re.match(script_path):
         script_path = '%s%s' % (settings.ADMIN_MEDIA_PREFIX, script_path)
-    return '<script type="text/javascript" src="%s"></script>' % script_path
+    return u'<script type="text/javascript" src="%s"></script>' % script_path
 include_admin_script = register.simple_tag(include_admin_script)
 
 def submit_row(context):
         if not bound_field.first:
             class_names.append('inline')
         colon = ":"
-    class_str = class_names and ' class="%s"' % ' '.join(class_names) or ''
-    return '<label for="%s"%s>%s%s</label> ' % (bound_field.element_id, class_str, \
-        capfirst(bound_field.field.verbose_name), colon)
+    class_str = class_names and u' class="%s"' % u' '.join(class_names) or u''
+    return u'<label for="%s"%s>%s%s</label> ' % (bound_field.element_id, class_str, \
+        force_unicode(capfirst(bound_field.field.verbose_name)), colon)
 field_label = register.simple_tag(field_label)
 
 class FieldWidgetNode(template.Node):
         if klass not in cls.nodelists:
             try:
                 field_class_name = klass.__name__
-                template_name = "widget/%s.html" % class_name_to_underscored(field_class_name)
+                template_name = u"widget/%s.html" % class_name_to_underscored(field_class_name)
                 nodelist = loader.get_template(template_name).nodelist
             except template.TemplateDoesNotExist:
                 super_klass = bool(klass.__bases__) and klass.__bases__[0] or None
         return output
 
 def output_all(form_fields):
-    return ''.join([str(f) for f in form_fields])
+    return u''.join([force_unicode(f) for f in form_fields])
 output_all = register.simple_tag(output_all)
 
 def auto_populated_field_script(auto_pop_fields, change = False):
     t = []
     for field in auto_pop_fields:
         if change:
-            t.append('document.getElementById("id_%s")._changed = true;' % field.name)
+            t.append(u'document.getElementById("id_%s")._changed = true;' % field.name)
         else:
-            t.append('document.getElementById("id_%s").onchange = function() { this._changed = true; };' % field.name)
+            t.append(u'document.getElementById("id_%s").onchange = function() { this._changed = true; };' % field.name)
 
-        add_values = ' + " " + '.join(['document.getElementById("id_%s").value' % g for g in field.prepopulate_from])
+        add_values = u' + " " + '.join([u'document.getElementById("id_%s").value' % g for g in field.prepopulate_from])
         for f in field.prepopulate_from:
-            t.append('document.getElementById("id_%s").onkeyup = function() {' \
+            t.append(u'document.getElementById("id_%s").onkeyup = function() {' \
                      ' var e = document.getElementById("id_%s");' \
                      ' if(!e._changed) { e.value = URLify(%s, %s);} }; ' % (
                      f, field.name, add_values, field.maxlength))
-    return ''.join(t)
+    return u''.join(t)
 auto_populated_field_script = register.simple_tag(auto_populated_field_script)
 
 def filter_interface_script_maybe(bound_field):
     f = bound_field.field
     if f.rel and isinstance(f.rel, models.ManyToManyRel) and f.rel.filter_interface:
-        return '<script type="text/javascript">addEvent(window, "load", function(e) {' \
+        return u'<script type="text/javascript">addEvent(window, "load", function(e) {' \
               ' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % (
               f.name, f.verbose_name.replace('"', '\\"'), f.rel.filter_interface-1, settings.ADMIN_MEDIA_PREFIX)
     else:

django/contrib/admin/templatetags/adminapplist.py

 from django import template
 from django.db.models import get_models
+from django.utils.encoding import force_unicode
 
 register = template.Library()
 
                         # If so, add the module to the model_list.
                         if True in perms.values():
                             model_list.append({
-                                'name': capfirst(m._meta.verbose_name_plural),
-                                'admin_url': '%s/%s/' % (app_label, m.__name__.lower()),
+                                'name': force_unicode(capfirst(m._meta.verbose_name_plural)),
+                                'admin_url': u'%s/%s/' % (force_unicode(app_label), m.__name__.lower()),
                                 'perms': perms,
                             })
 

django/contrib/admin/views/auth.py

 from django.shortcuts import render_to_response, get_object_or_404
 from django.http import HttpResponseRedirect
 from django.utils.html import escape
+from django.utils.translation import ugettext as _
 
 def user_add_stage(request):
     if not request.user.has_perm('auth.change_user'):

django/contrib/admin/views/decorators.py

 from django.contrib.auth.models import User
 from django.contrib.auth import authenticate, login
 from django.shortcuts import render_to_response
-from django.utils.translation import gettext_lazy
+from django.utils.translation import ugettext_lazy, ugettext as _
 import base64, datetime, md5
 import cPickle as pickle
 
-ERROR_MESSAGE = gettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
+ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
 LOGIN_FORM_KEY = 'this_is_the_login_form'
 
 def _display_login_form(request, error_message=''):

django/contrib/admin/views/doc.py

 from django.core import urlresolvers
 from django.contrib.admin import utils
 from django.contrib.sites.models import Site
+from django.utils.translation import ugettext as _
 import inspect, os, re
 
 # Exclude methods starting with these strings from documentation

django/contrib/admin/views/main.py

 from django.http import Http404, HttpResponse, HttpResponseRedirect
 from django.utils.html import escape
 from django.utils.text import capfirst, get_text_list
+from django.utils.encoding import force_unicode, smart_str
+from django.utils.translation import ugettext as _
 import operator
 
 try:
         if max([bool(f.errors()) for f in self.form_fields]):
             classes.append('error')
         if classes:
-            self.cell_class_attribute = ' class="%s" ' % ' '.join(classes)
+            self.cell_class_attribute = u' class="%s" ' % ' '.join(classes)
         self._repr_filled = False
 
         if field.rel:
-            self.related_url = '../../../%s/%s/' % (field.rel.to._meta.app_label, field.rel.to._meta.object_name.lower())
+            self.related_url = u'../../../%s/%s/' % (field.rel.to._meta.app_label, field.rel.to._meta.object_name.lower())
 
     def original_value(self):
         if self.original:
             return self._display
         except AttributeError:
             if isinstance(self.field.rel, models.ManyToOneRel):
-                self._display = getattr(self.original, self.field.name)
+                self._display = force_unicode(getattr(self.original, self.field.name), strings_only=True)
             elif isinstance(self.field.rel, models.ManyToManyRel):
-                self._display = ", ".join([str(obj) for obj in getattr(self.original, self.field.name).all()])
+                self._display = u", ".join([force_unicode(obj) for obj in getattr(self.original, self.field.name).all()])
             return self._display
 
     def __repr__(self):
         if not errors:
             new_object = manipulator.save(new_data)
             pk_value = new_object._get_pk_val()
-            LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), ADDITION)
-            msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
+            LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, force_unicode(new_object), ADDITION)
+            msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object}
             # Here, we distinguish between different save types by checking for
             # the presence of keys in request.POST.
             if "_continue" in request.POST:
                 if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable.
                     pk_value = '"%s"' % pk_value.replace('"', '\\"')
                 return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
-                    (pk_value, str(new_object).replace('"', '\\"')))
+                    (pk_value, force_unicode(new_object).replace('"', '\\"')))
             elif "_addanother" in request.POST:
-                request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
+                request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
                 return HttpResponseRedirect(request.path)
             else:
                 request.user.message_set.create(message=msg)
     form = oldforms.FormWrapper(manipulator, new_data, errors)
 
     c = template.RequestContext(request, {
-        'title': _('Add %s') % opts.verbose_name,
+        'title': _('Add %s') % force_unicode(opts.verbose_name),
         'form': form,
         'is_popup': '_popup' in request.REQUEST,
         'show_delete': show_delete,
             change_message = ' '.join(change_message)
             if not change_message:
                 change_message = _('No fields changed.')
-            LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), CHANGE, change_message)
+            LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, force_unicode(new_object), CHANGE, change_message)
 
-            msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
+            msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object}
             if "_continue" in request.POST:
                 request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
                 if '_popup' in request.REQUEST:
                 else:
                     return HttpResponseRedirect(request.path)
             elif "_saveasnew" in request.POST:
-                request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
+                request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object})
                 return HttpResponseRedirect("../%s/" % pk_value)
             elif "_addanother" in request.POST:
-                request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
+                request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
                 return HttpResponseRedirect("../add/")
             else:
                 request.user.message_set.create(message=msg)
             form.order_objects.extend(orig_list)
 
     c = template.RequestContext(request, {
-        'title': _('Change %s') % opts.verbose_name,
+        'title': _('Change %s') % force_unicode(opts.verbose_name),
         'form': form,
         'object_id': object_id,
         'original': manipulator.original_object,
                 if related.field.rel.edit_inline or not related.opts.admin:
                     # Don't display link to edit, because it either has no
                     # admin or is edited inline.
-                    nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), sub_obj), []])
+                    nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
                 else:
                     # Display a link to the admin page.
-                    nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
-                        (capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(),
+                    nh(deleted_objects, current_depth, [u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
+                        (force_unicode(capfirst(related.opts.verbose_name)), related.opts.app_label, related.opts.object_name.lower(),
                         sub_obj._get_pk_val(), sub_obj), []])
                 _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)
         else:
                 if related.field.rel.edit_inline or not related.opts.admin:
                     # Don't display link to edit, because it either has no
                     # admin or is edited inline.
-                    nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), escape(str(sub_obj))), []])
+                    nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), escape(sub_obj)), []])
                 else:
                     # Display a link to the admin page.
-                    nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
-                        (capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(str(sub_obj))), []])
+                    nh(deleted_objects, current_depth, [u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
+                        (force_unicode(capfirst(related.opts.verbose_name)), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(sub_obj)), []])
                 _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)
             # If there were related objects, and the user doesn't have
             # permission to delete them, add the missing perm to perms_needed.
         opts_seen.append(related.opts)
         rel_opts_name = related.get_accessor_name()
         has_related_objs = False
-       
+
         # related.get_accessor_name() could return None for symmetrical relationships
         if rel_opts_name:
             rel_objs = getattr(obj, rel_opts_name, None)
                     # Don't display link to edit, because it either has no
                     # admin or is edited inline.
                     nh(deleted_objects, current_depth, [_('One or more %(fieldname)s in %(name)s: %(obj)s') % \
-                        {'fieldname': related.field.verbose_name, 'name': related.opts.verbose_name, 'obj': escape(str(sub_obj))}, []])
+                        {'fieldname': force_unicode(related.field.verbose_name), 'name': force_unicode(related.opts.verbose_name), 'obj': escape(sub_obj)}, []])
                 else:
                     # Display a link to the admin page.
                     nh(deleted_objects, current_depth, [
-                        (_('One or more %(fieldname)s in %(name)s:') % {'fieldname': related.field.verbose_name, 'name':related.opts.verbose_name}) + \
-                        (' <a href="../../../../%s/%s/%s/">%s</a>' % \
-                            (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(str(sub_obj)))), []])
+                        (_('One or more %(fieldname)s in %(name)s:') % {'fieldname': force_unicode(related.field.verbose_name), 'name': force_unicode(related.opts.verbose_name)}) + \
+                        (u' <a href="../../../../%s/%s/%s/">%s</a>' % \
+                            (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(sub_obj))), []])
         # If there were related objects, and the user doesn't have
         # permission to change them, add the missing perm to perms_needed.
         if related.opts.admin and has_related_objs:
-            p = '%s.%s' % (related.opts.app_label, related.opts.get_change_permission())
+            p = u'%s.%s' % (related.opts.app_label, related.opts.get_change_permission())
             if not user.has_perm(p):
                 perms_needed.add(related.opts.verbose_name)
 
 
     # Populate deleted_objects, a data structure of all related objects that
     # will also be deleted.
-    deleted_objects = ['%s: <a href="../../%s/">%s</a>' % (capfirst(opts.verbose_name), object_id, escape(str(obj))), []]
+    deleted_objects = [u'%s: <a href="../../%s/">%s</a>' % (force_unicode(capfirst(opts.verbose_name)), force_unicode(object_id), escape(obj)), []]
     perms_needed = set()
     _get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1)
 
     if request.POST: # The user has already confirmed the deletion.
         if perms_needed:
             raise PermissionDenied
-        obj_display = str(obj)
+        obj_display = force_unicode(obj)
         obj.delete()
         LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, object_id, obj_display, DELETION)
-        request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': opts.verbose_name, 'obj': obj_display})
+        request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': obj_display})
         return HttpResponseRedirect("../../")
     extra_context = {
         "title": _("Are you sure?"),
-        "object_name": opts.verbose_name,
+        "object_name": force_unicode(opts.verbose_name),
         "object": obj,
         "deleted_objects": deleted_objects,
         "perms_lacking": perms_needed,
     extra_context = {
         'title': _('Change history: %s') % obj,
         'action_list': action_list,
-        'module_name': capfirst(model._meta.verbose_name_plural),
+        'module_name': force_unicode(capfirst(model._meta.verbose_name_plural)),
         'object': obj,
     }
     return render_to_response(["admin/%s/%s/object_history.html" % (app_label, model._meta.object_name.lower()),
         self.query = request.GET.get(SEARCH_VAR, '')
         self.query_set = self.get_query_set()
         self.get_results(request)
-        self.title = (self.is_popup and _('Select %s') % self.opts.verbose_name or _('Select %s to change') % self.opts.verbose_name)
+        self.title = (self.is_popup and _('Select %s') % force_unicode(self.opts.verbose_name) or _('Select %s to change') % force_unicode(self.opts.verbose_name))
         self.filter_specs, self.has_filters = self.get_filters(request)
         self.pk_attname = self.lookup_opts.pk.attname
 
                 del p[k]
             elif v is not None:
                 p[k] = v
-        return '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20')
+        return '?' + '&amp;'.join([u'%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20')
 
     def get_results(self, request):
         paginator = ObjectPaginator(self.query_set, self.lookup_opts.admin.list_per_page)
         for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR):
             if i in lookup_params:
                 del lookup_params[i]
+        for key, value in lookup_params.items():
+            if not isinstance(key, str):
+                # 'key' will be used as a keyword argument later, so Python
+                # requires it to be a string.
+                del lookup_params[key]
+                lookup_params[smart_str(key)] = value
 
         # Apply lookup parameters from the query string.
         qs = qs.filter(**lookup_params)

django/contrib/auth/forms.py

 from django.template import Context, loader
 from django.core import validators
 from django import oldforms
-from django.utils.translation import gettext as _
+from django.utils.translation import ugettext as _
 
 class UserCreationForm(oldforms.Manipulator):
     "A form that creates a user, with no privileges, from the given username and password."

django/contrib/auth/management.py

 from django.contrib.auth import models as auth_app
 
 def _get_permission_codename(action, opts):
-    return '%s_%s' % (action, opts.object_name.lower())
+    return u'%s_%s' % (action, opts.object_name.lower())
 
 def _get_all_permissions(opts):
     "Returns (codename, name) for all permissions in the given opts."
     perms = []
     for action in ('add', 'change', 'delete'):
-        perms.append((_get_permission_codename(action, opts), 'Can %s %s' % (action, opts.verbose_name)))
+        perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
     return perms + list(opts.permissions)
 
 def create_permissions(app, created_models, verbosity):

django/contrib/auth/models.py

 from django.core.exceptions import ImproperlyConfigured
 from django.db import backend, connection, models
 from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext_lazy as _
+from django.utils.encoding import smart_str
+from django.utils.translation import ugettext_lazy as _
 import datetime
+import urllib
 
 try:
     set
     algo, salt, hsh = enc_password.split('$')
     if algo == 'md5':
         import md5
-        return hsh == md5.new(salt+raw_password).hexdigest()
+        return hsh == md5.new(smart_str(salt + raw_password)).hexdigest()
     elif algo == 'sha1':
         import sha
-        return hsh == sha.new(salt+raw_password).hexdigest()
+        return hsh == sha.new(smart_str(salt + raw_password)).hexdigest()
     elif algo == 'crypt':
         try:
             import crypt
         except ImportError:
             raise ValueError, "Crypt password algorithm not supported in this environment."
-        return hsh == crypt.crypt(raw_password, salt)
+        return hsh == crypt.crypt(smart_str(raw_password), smart_str(salt))
     raise ValueError, "Got unknown password algorithm type in password."
 
 class SiteProfileNotAvailable(Exception):
         unique_together = (('content_type', 'codename'),)
         ordering = ('content_type', 'codename')
 
-    def __str__(self):
-        return "%s | %s | %s" % (self.content_type.app_label, self.content_type, self.name)
+    def __unicode__(self):
+        return u"%s | %s | %s" % (self.content_type.app_label, self.content_type, self.name)
 
 class Group(models.Model):
     """Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
     class Admin:
         search_fields = ('name',)
 
-    def __str__(self):
+    def __unicode__(self):
         return self.name
 
 class UserManager(models.Manager):
         list_filter = ('is_staff', 'is_superuser')
         search_fields = ('username', 'first_name', 'last_name', 'email')
 
-    def __str__(self):
+    def __unicode__(self):
         return self.username
 
     def get_absolute_url(self):
-        return "/users/%s/" % self.username
+        return "/users/%s/" % urllib.quote(smart_str(self.username))
 
     def is_anonymous(self):
         "Always returns False. This is a way of comparing User objects to anonymous users."
 
     def get_full_name(self):
         "Returns the first_name plus the last_name, with a space in between."
-        full_name = '%s %s' % (self.first_name, self.last_name)
+        full_name = u'%s %s' % (self.first_name, self.last_name)
         return full_name.strip()
 
     def set_password(self, raw_password):
         import sha, random
         algo = 'sha1'
         salt = sha.new(str(random.random())).hexdigest()[:5]
-        hsh = sha.new(salt+raw_password).hexdigest()
+        hsh = sha.new(salt + smart_str(raw_password)).hexdigest()
         self.password = '%s$%s$%s' % (algo, salt, hsh)
 
     def check_password(self, raw_password):
         # algorithm or salt.
         if '$' not in self.password:
             import md5
-            is_correct = (self.password == md5.new(raw_password).hexdigest())
+            is_correct = (self.password == md5.new(smart_str(raw_password)).hexdigest())
             if is_correct:
                 # Convert the password to the new, more secure format.
                 self.set_password(raw_password)
 
     def get_all_permissions(self):
         if not hasattr(self, '_perm_cache'):
-            self._perm_cache = set(["%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()])
+            self._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()])
             self._perm_cache.update(self.get_group_permissions())
         return self._perm_cache
 
     user = models.ForeignKey(User)
     message = models.TextField(_('message'))
 
-    def __str__(self):
+    def __unicode__(self):
         return self.message
 
 class AnonymousUser(object):
     def __init__(self):
         pass
 
+    def __unicode__(self):
+        return 'AnonymousUser'
+
     def __str__(self):
-        return 'AnonymousUser'
+        return unicode(self).encode('utf-8')
 
     def __eq__(self, other):
         return isinstance(other, self.__class__)

django/contrib/auth/views.py

 from django.http import HttpResponseRedirect
 from django.contrib.auth.decorators import login_required
 from django.contrib.auth import REDIRECT_FIELD_NAME
+from django.utils.translation import ugettext as _
 
 def login(request, template_name='registration/login.html'):
     "Displays the login form and handles the login action."

django/contrib/comments/feeds.py

     def title(self):
         if not hasattr(self, '_site'):
             self._site = Site.objects.get_current()
-        return "%s comments" % self._site.name
+        return u"%s comments" % self._site.name
 
     def link(self):
         if not hasattr(self, '_site'):
     def description(self):
         if not hasattr(self, '_site'):
             self._site = Site.objects.get_current()
-        return "Latest comments on %s" % self._site.name
+        return u"Latest comments on %s" % self._site.name
 
     def get_query_set(self):
         return self.comments_class.objects.filter(site__pk=settings.SITE_ID, is_public=True)

django/contrib/comments/models.py

 from django.contrib.contenttypes.models import ContentType
 from django.contrib.sites.models import Site
 from django.contrib.auth.models import User
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ugettext_lazy as _
 from django.conf import settings
 import datetime
 

django/contrib/comments/views/comments.py

 from django.http import HttpResponseRedirect
 from django.utils.text import normalize_newlines
 from django.conf import settings
-from django.utils.translation import ngettext
+from django.utils.translation import ungettext, ugettext as _
+from django.utils.encoding import smart_unicode
 import base64, datetime
 
 COMMENTS_PER_PAGE = 20
         # If the commentor has posted fewer than COMMENTS_FIRST_FEW comments,
         # send the comment to the managers.
         if self.user_cache.comment_set.count() <= settings.COMMENTS_FIRST_FEW:
-            message = ngettext('This comment was posted by a user who has posted fewer than %(count)s comment:\n\n%(text)s',
+            message = ungettext('This comment was posted by a user who has posted fewer than %(count)s comment:\n\n%(text)s',
                 'This comment was posted by a user who has posted fewer than %(count)s comments:\n\n%(text)s', settings.COMMENTS_FIRST_FEW) % \
                 {'count': settings.COMMENTS_FIRST_FEW, 'text': c.get_as_text()}
             mail_managers("Comment posted by rookie user", message)
         # If the IP is banned, mail the admins, do NOT save the comment, and
         # serve up the "Thanks for posting" page as if the comment WAS posted.
         if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
-            mail_admins("Banned IP attempted to post comment", str(request.POST) + "\n\n" + str(request.META))
+            mail_admins("Banned IP attempted to post comment", smart_unicode(request.POST) + "\n\n" + str(request.META))
         else:
             manipulator.do_html2python(new_data)
             comment = manipulator.save(new_data)
         # serve up the "Thanks for posting" page as if the comment WAS posted.
         if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
             from django.core.mail import mail_admins
-            mail_admins("Practical joker", str(request.POST) + "\n\n" + str(request.META))
+            mail_admins("Practical joker", smart_unicode(request.POST) + "\n\n" + str(request.META))
         else:
             manipulator.do_html2python(new_data)
             comment = manipulator.save(new_data)

django/contrib/comments/views/karma.py

 from django.shortcuts import render_to_response
 from django.template import RequestContext
 from django.contrib.comments.models import Comment, KarmaScore
+from django.utils.translation import ugettext as _
 
 def vote(request, comment_id, vote):
     """

django/contrib/contenttypes/generic.py

         
     def __get__(self, instance, instance_type=None):
         if instance is None:
-            raise AttributeError, "%s must be accessed via instance" % self.name
+            raise AttributeError, u"%s must be accessed via instance" % self.name
 
         try:
             return getattr(instance, self.cache_attr)
 
     def __set__(self, instance, value):
         if instance is None:
-            raise AttributeError, "%s must be accessed via instance" % self.related.opts.object_name
+            raise AttributeError, u"%s must be accessed via instance" % self.related.opts.object_name
 
         ct = None
         fk = None

django/contrib/contenttypes/management.py

 
 from django.dispatch import dispatcher
 from django.db.models import get_apps, get_models, signals
+from django.utils.encoding import smart_unicode
 
 def create_contenttypes(app, created_models, verbosity=2):
     from django.contrib.contenttypes.models import ContentType
             ContentType.objects.get(app_label=opts.app_label,
                 model=opts.object_name.lower())
         except ContentType.DoesNotExist:
-            ct = ContentType(name=str(opts.verbose_name),
+            ct = ContentType(name=smart_unicode(opts.verbose_name_raw),
                 app_label=opts.app_label, model=opts.object_name.lower())
             ct.save()
             if verbosity >= 2:

django/contrib/contenttypes/models.py

 from django.db import models
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ugettext_lazy as _
+from django.utils.encoding import smart_unicode
 
 CONTENT_TYPE_CACHE = {}
 class ContentTypeManager(models.Manager):
         try:
             ct = CONTENT_TYPE_CACHE[key]
         except KeyError:
-            # The str() is needed around opts.verbose_name because it's a
-            # django.utils.functional.__proxy__ object.
+            # The smart_unicode() is needed around opts.verbose_name_raw because it might
+            # be a django.utils.functional.__proxy__ object.
             ct, created = self.model._default_manager.get_or_create(app_label=key[0],
-                model=key[1], defaults={'name': str(opts.verbose_name)})
+                model=key[1], defaults={'name': smart_unicode(opts.verbose_name_raw)})
             CONTENT_TYPE_CACHE[key] = ct
         return ct
-        
+
     def clear_cache(self):
         """
         Clear out the content-type cache. This needs to happen during database
         ordering = ('name',)
         unique_together = (('app_label', 'model'),)
 
-    def __str__(self):
+    def __unicode__(self):
         return self.name
 
     def model_class(self):

django/contrib/databrowse/datastructures.py

 from django.utils import dateformat
 from django.utils.text import capfirst
 from django.utils.translation import get_date_formats
+from django.utils.encoding import smart_unicode, smart_str, iri_to_uri
 
 EMPTY_VALUE = '(None)'
 
         self.verbose_name_plural = model._meta.verbose_name_plural
 
     def __repr__(self):
-        return '<EasyModel for %s>' % self.model._meta.object_name
+        return '<EasyModel for %s>' % smart_str(self.model._meta.object_name)
 
     def model_databrowse(self):
         "Returns the ModelDatabrowse class for this model."
         self.model, self.field = easy_model, field
 
     def __repr__(self):
-        return '<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
+        return smart_str(u'<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
 
     def choices(self):
         for value, label in self.field.choices:
         self.value, self.label = value, label
 
     def __repr__(self):
-        return '<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
+        return smart_str(u'<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
 
     def url(self):
-        return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, self.value)
+        return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value))
 
 class EasyInstance(object):
     def __init__(self, easy_model, instance):
         self.model, self.instance = easy_model, instance
 
     def __repr__(self):
-        return '<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val())
+        return smart_str(u'<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val()))
+
+    def __unicode__(self):
+        val = smart_unicode(self.instance)
+        if len(val) > 30:
+            return val[:30] + u'...'
+        return val
 
     def __str__(self):
-        val = str(self.instance)
-        if len(val) > 30:
-            return val[:30] + '...'
-        return val
+        return self.__unicode__().encode('utf-8')
 
     def pk(self):
         return self.instance._get_pk_val()
 
     def url(self):
-        return '%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.pk())
+        return '%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, iri_to_uri(self.pk()))
 
     def fields(self):
         """
         self.raw_value = getattr(instance.instance, field.name)
 
     def __repr__(self):
-        return '<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
+        return smart_str(u'<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
 
     def values(self):
         """
             if self.field.rel.to in self.model.model_list:
                 lst = []
                 for value in self.values():
-                    url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, value._get_pk_val())
-                    lst.append((str(value), url))
+                    url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val()))
+                    lst.append((smart_unicode(value), url))
             else:
                 lst = [(value, None) for value in self.values()]
         elif self.field.choices:
             lst = []
             for value in self.values():
-                url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, self.raw_value)
+                url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value))
                 lst.append((value, url))
         elif isinstance(self.field, models.URLField):
             val = self.values()[0]
-            lst = [(val, val)]
+            lst = [(val, iri_to_uri(val))]
         else:
             lst = [(self.values()[0], None)]
         return lst

django/contrib/databrowse/plugins/calendars.py

 from django.utils.text import capfirst
 from django.utils.translation import get_date_formats
 from django.views.generic import date_based
+from django.utils.encoding import force_unicode
 import datetime
 import time
 
     def model_index_html(self, request, model, site):
         fields = self.field_dict(model)
         if not fields:
-            return ''
-        return '<p class="filter"><strong>View calendar by:</strong> %s</p>' % \
-            ', '.join(['<a href="calendars/%s/">%s</a>' % (f.name, capfirst(f.verbose_name)) for f in fields.values()])
+            return u''
+        return u'<p class="filter"><strong>View calendar by:</strong> %s</p>' % \
+            u', '.join(['<a href="calendars/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()])
 
     def urls(self, plugin_name, easy_instance_field):
         if isinstance(easy_instance_field.field, models.DateField):
-            return ['%s%s/%s/%s/%s/%s/' % (easy_instance_field.model.url(),
+            return [u'%s%s/%s/%s/%s/%s/' % (easy_instance_field.model.url(),
                 plugin_name, easy_instance_field.field.name,
                 easy_instance_field.raw_value.year,
                 easy_instance_field.raw_value.strftime('%b').lower(),

django/contrib/databrowse/plugins/fieldchoices.py

 from django.contrib.databrowse.sites import DatabrowsePlugin
 from django.shortcuts import render_to_response
 from django.utils.text import capfirst
+from django.utils.encoding import smart_str, force_unicode
 from django.views.generic import date_based
 import datetime
 import time
+import urllib
 
 class FieldChoicePlugin(DatabrowsePlugin):
     def __init__(self, field_filter=None):
     def model_index_html(self, request, model, site):
         fields = self.field_dict(model)
         if not fields:
-            return ''
-        return '<p class="filter"><strong>View by:</strong> %s</p>' % \
-            ', '.join(['<a href="fields/%s/">%s</a>' % (f.name, capfirst(f.verbose_name)) for f in fields.values()])
+            return u''
+        return u'<p class="filter"><strong>View by:</strong> %s</p>' % \
+            u', '.join(['<a href="fields/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()])
 
     def urls(self, plugin_name, easy_instance_field):
         if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values():
-            return ['%s%s/%s/%s/' % (easy_instance_field.model.url(),
+            return [u'%s%s/%s/%s/' % (easy_instance_field.model.url(),
                 plugin_name, easy_instance_field.field.name,
-                easy_instance_field.raw_value)]
+                urllib.quote(smart_str(easy_instance_field.raw_value)))]
 
     def model_view(self, request, model_databrowse, url):
         self.model, self.site = model_databrowse.model, model_databrowse.site

django/contrib/databrowse/sites.py

 
     def main_view(self, request):
         easy_model = EasyModel(self.site, self.model)
-        html_snippets = '\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()])
+        html_snippets = u'\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()])
         return render_to_response('databrowse/model_detail.html', {
             'model': easy_model,
             'root_url': self.site.root_url,

django/contrib/databrowse/templates/databrowse/fieldchoice_list.html

 
 <ul class="objectlist">
 {% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object }}/">{{ object|escape }}</a></li>
+<li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
 {% endfor %}
 </ul>
 

django/contrib/flatpages/models.py

 from django.core import validators
 from django.db import models
 from django.contrib.sites.models import Site
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ugettext_lazy as _
 
 class FlatPage(models.Model):
     url = models.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL], db_index=True,
         list_filter = ('sites',)
         search_fields = ('url', 'title')
 
-    def __str__(self):
-        return "%s -- %s" % (self.url, self.title)
+    def __unicode__(self):
+        return u"%s -- %s" % (self.url, self.title)
 
     def get_absolute_url(self):
         return self.url

django/contrib/humanize/templatetags/humanize.py

-from django.utils.translation import ngettext
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ungettext, ugettext as _
+from django.utils.encoding import force_unicode
 from django import template
 import re
 
         return value
     t = (_('th'), _('st'), _('nd'), _('rd'), _('th'), _('th'), _('th'), _('th'), _('th'), _('th'))
     if value % 100 in (11, 12, 13): # special case
-        return "%d%s" % (value, t[0])
-    return '%d%s' % (value, t[value % 10])
+        return u"%d%s" % (value, t[0])
+    return u'%d%s' % (value, t[value % 10])
 register.filter(ordinal)
 
 def intcomma(value):
     Converts an integer to a string containing commas every three digits.
     For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
     """
-    orig = str(value)
-    new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', str(value))
+    orig = force_unicode(value)
+    new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', orig)
     if orig == new:
         return new
     else:
         return value
     if value < 1000000000:
         new_value = value / 1000000.0
-        return ngettext('%(value).1f million', '%(value).1f million', new_value) % {'value': new_value}
+        return ungettext('%(value).1f million', '%(value).1f million', new_value) % {'value': new_value}
     if value < 1000000000000:
         new_value = value / 1000000000.0
-        return ngettext('%(value).1f billion', '%(value).1f billion', new_value) % {'value': new_value}
+        return ungettext('%(value).1f billion', '%(value).1f billion', new_value) % {'value': new_value}
     if value < 1000000000000000:
         new_value = value / 1000000000000.0
-        return ngettext('%(value).1f trillion', '%(value).1f trillion', new_value) % {'value': new_value}
+        return ungettext('%(value).1f trillion', '%(value).1f trillion', new_value) % {'value': new_value}
     return value
 register.filter(intword)
 

django/contrib/localflavor/au/forms.py

 from django.newforms import ValidationError
 from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
 from django.newforms.util import smart_unicode
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
 import re
 
 PHONE_DIGITS_RE = re.compile(r'^(\d{10})$')
     def __init__(self, *args, **kwargs):
         super(AUPostCodeField, self).__init__(r'^\d{4}$',
             max_length=None, min_length=None,
-            error_message=gettext(u'Enter a 4 digit post code.'),
-            *args, **kwargs)
+            error_message=ugettext('Enter a 4 digit post code.'),
+                    *args, **kwargs)
 
 class AUPhoneNumberField(Field):
     """Australian phone number field."""
     def clean(self, value):
-        """Validate a phone number. Strips parentheses, whitespace and
-        hyphens.
+        """
+        Validate a phone number. Strips parentheses, whitespace and hyphens.
         """
         super(AUPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
     choices.
     """
     def __init__(self, attrs=None):
-        from au_states import STATE_CHOICES # relative import
+        from au_states import STATE_CHOICES
         super(AUStateSelect, self).__init__(attrs, choices=STATE_CHOICES)

django/contrib/localflavor/br/forms.py

 from django.newforms import ValidationError
 from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES
 from django.utils.encoding import smart_unicode
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
 import re
 
 phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
     def __init__(self, *args, **kwargs):
         super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
             max_length=None, min_length=None,
-            error_message=gettext('Enter a zip code in the format XXXXX-XXX.'),
-            *args, **kwargs)
+            error_message=ugettext('Enter a zip code in the format XXXXX-XXX.'),
+                    *args, **kwargs)
 
 class BRPhoneNumberField(Field):
     def clean(self, value):
         m = phone_digits_re.search(value)
         if m:
             return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
-        raise ValidationError(gettext(u'Phone numbers must be in XX-XXXX-XXXX format.'))
+        raise ValidationError(ugettext('Phone numbers must be in XX-XXXX-XXXX format.'))
 
 class BRStateSelect(Select):
     """
     as its choices.
     """
     def __init__(self, attrs=None):
-        from br_states import STATE_CHOICES # relative import
+        from br_states import STATE_CHOICES
         super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
 
 
         try:
             int(value)
         except ValueError:
-            raise ValidationError(gettext("This field requires only numbers."))
+            raise ValidationError(ugettext("This field requires only numbers."))
         if len(value) != 11:
-            raise ValidationError(gettext("This field requires at most 11 digits or 14 characters."))
+            raise ValidationError(ugettext("This field requires at most 11 digits or 14 characters."))
         orig_dv = value[-2:]
 
         new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
         new_2dv = DV_maker(new_2dv % 11)
         value = value[:-1] + str(new_2dv)
         if value[-2:] != orig_dv:
-            raise ValidationError(gettext("Invalid CPF number."))
+            raise ValidationError(ugettext("Invalid CPF number."))
 
         return orig_value
 
             raise ValidationError("This field requires only numbers.")
         if len(value) != 14:
             raise ValidationError(
-                gettext("This field requires at least 14 digits"))
+                ugettext("This field requires at least 14 digits"))
         orig_dv = value[-2:]
 
         new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
         new_2dv = DV_maker(new_2dv % 11)
         value = value[:-1] + str(new_2dv)
         if value[-2:] != orig_dv:
-            raise ValidationError(gettext("Invalid CNPJ number."))
+            raise ValidationError(ugettext("Invalid CNPJ number."))
 
         return orig_value
 

django/contrib/localflavor/ch/ch_states.py

 # -*- coding: utf-8 -*
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ugettext_lazy as _
 
 STATE_CHOICES = (
     ('AG', _('Aargau')),

django/contrib/localflavor/ch/forms.py

 from django.newforms import ValidationError
 from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
 from django.utils.encoding import smart_unicode
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
 import re
 
 id_re = re.compile(r"^(?P<idnumber>\w{8})(?P<pos9>(\d{1}|<))(?P<checksum>\d{1})$")
     def __init__(self, *args, **kwargs):
         super(CHZipCodeField, self).__init__(r'^\d{4}$',
         max_length=None, min_length=None,
-        error_message=gettext('Enter a zip code in the format XXXX.'),
+        error_message=ugettext('Enter a zip code in the format XXXX.'),
         *args, **kwargs)
 
 class CHPhoneNumberField(Field):
 
     def clean(self, value):
         super(CHIdentityCardNumberField, self).clean(value)
-        error_msg = gettext('Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.')
+        error_msg = ugettext('Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.')
         if value in EMPTY_VALUES:
             return u''
 

django/contrib/localflavor/cl/forms.py

 
 from django.newforms import ValidationError
 from django.newforms.fields import RegexField, EMPTY_VALUES
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
+from django.utils.encoding import smart_unicode
 
 class CLRutField(RegexField):
     """
         if 'strict' in kwargs:
             del kwargs['strict']
             super(CLRutField, self).__init__(r'^(\d{1,2}\.)?\d{3}\.\d{3}-[\dkK]$',
-                error_message=gettext('Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.'),
-                *args, **kwargs)
+                error_message=ugettext('Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.'),
+                        *args, **kwargs)
         else:
             # In non-strict mode, accept RUTs that validate but do not exist in
             # the real world.
-            super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', error_message=gettext(u'Enter valid a Chilean RUT'), *args, **kwargs)
+            super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', error_message=ugettext('Enter valid a Chilean RUT'), *args, **kwargs)
 
     def clean(self, value):
         """
             multi += 1
             if multi == 8:
                 multi = 2
-        return '0123456789K0'[11 - suma % 11]
+        return u'0123456789K0'[11 - suma % 11]
 
     def _canonify(self, rut):
         """
         Turns the RUT into one normalized format. Returns a (rut, verifier)
         tuple.
         """
-        rut = str(rut).replace(' ', '').replace('.', '').replace('-', '')
+        rut = smart_unicode(rut).replace(' ', '').replace('.', '').replace('-', '')
         return rut[:-1], rut[-1]
 
     def _format(self, code, verifier=None):
             else:
                 new_dot = pos - 3
             code = code[:new_dot] + '.' + code[new_dot:]
-        return '%s-%s' % (code, verifier)
+        return u'%s-%s' % (code, verifier)
 

django/contrib/localflavor/de/de_states.py

 # -*- coding: utf-8 -*
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ugettext_lazy as _
 
 STATE_CHOICES = (
     ('BW', _('Baden-Wuerttemberg')),

django/contrib/localflavor/de/forms.py

 
 from django.newforms import ValidationError
 from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
 import re
 
 id_re = re.compile(r"^(?P<residence>\d{10})(?P<origin>\w{1,3})[-\ ]?(?P<birthday>\d{7})[-\ ]?(?P<validity>\d{7})[-\ ]?(?P<checksum>\d{1})$")
     def __init__(self, *args, **kwargs):
         super(DEZipCodeField, self).__init__(r'^\d{5}$',
             max_length=None, min_length=None,
-            error_message=gettext(u'Enter a zip code in the format XXXXX.'),
-            *args, **kwargs)
+            error_message=ugettext('Enter a zip code in the format XXXXX.'),
+                    *args, **kwargs)
 
 class DEStateSelect(Select):
     """
     A Select widget that uses a list of DE states as its choices.
     """
     def __init__(self, attrs=None):
-        from de_states import STATE_CHOICES # relative import
+        from de_states import STATE_CHOICES
         super(DEStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
 
 class DEIdentityCardNumberField(Field):
 
     def clean(self, value):
         super(DEIdentityCardNumberField, self).clean(value)
-        error_msg = gettext(u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.')
+        error_msg = ugettext('Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.')
         if value in EMPTY_VALUES:
             return u''
         match = re.match(id_re, value)
         if residence == '0000000000' or birthday == '0000000' or validity == '0000000':
             raise ValidationError(error_msg)
 
-        all_digits = "%s%s%s%s" % (residence, birthday, validity, checksum)
+        all_digits = u"%s%s%s%s" % (residence, birthday, validity, checksum)
         if not self.has_valid_checksum(residence) or not self.has_valid_checksum(birthday) or \
             not self.has_valid_checksum(validity) or not self.has_valid_checksum(all_digits):
                 raise ValidationError(error_msg)

django/contrib/localflavor/fi/forms.py

 import re
 from django.newforms import ValidationError
 from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
 
 class FIZipCodeField(RegexField):
     def __init__(self, *args, **kwargs):
         super(FIZipCodeField, self).__init__(r'^\d{5}$',
             max_length=None, min_length=None,
-            error_message=gettext(u'Enter a zip code in the format XXXXX.'),
-            *args, **kwargs)
+            error_message=ugettext('Enter a zip code in the format XXXXX.'),
+                    *args, **kwargs)
 
 class FIMunicipalitySelect(Select):
     """
     A Select widget that uses a list of Finnish municipalities as its choices.
     """
     def __init__(self, attrs=None):
-        from fi_municipalities import MUNICIPALITY_CHOICES # relative import
+        from fi_municipalities import MUNICIPALITY_CHOICES
         super(FIMunicipalitySelect, self).__init__(attrs, choices=MUNICIPALITY_CHOICES)
 
 class FISocialSecurityNumber(Field):
             (?P<serial>(\d{3}))
             (?P<checksum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE)
         if not result:
-            raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))
+            raise ValidationError(ugettext('Enter a valid Finnish social security number.'))
         gd = result.groupdict()
         checksum = int(gd['date'] + gd['serial'])
         if checkmarks[checksum % len(checkmarks)] == gd['checksum'].upper():
             return u'%s' % value.upper()
-        raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))
+        raise ValidationError(ugettext('Enter a valid Finnish social security number.'))

django/contrib/localflavor/fr/forms.py

 from django.newforms import ValidationError
 from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
 from django.utils.encoding import smart_unicode
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
 import re
 
 phone_digits_re = re.compile(r'^0\d(\s|\.)?(\d{2}(\s|\.)?){3}\d{2}$')
     def __init__(self, *args, **kwargs):
         super(FRZipCodeField, self).__init__(r'^\d{5}$',
             max_length=None, min_length=None,
-            error_message=gettext(u'Enter a zip code in the format XXXXX.'),
-            *args, **kwargs)
+            error_message=ugettext('Enter a zip code in the format XXXXX.'),
+                    *args, **kwargs)
 
 class FRPhoneNumberField(Field):
     """
     A Select widget that uses a list of FR departments as its choices.
     """
     def __init__(self, attrs=None):
-        from fr_department import DEPARTMENT_ASCII_CHOICES # relative import
+        from fr_department import DEPARTMENT_ASCII_CHOICES
         super(FRDepartmentSelect, self).__init__(attrs, choices=DEPARTMENT_ASCII_CHOICES)
 

django/contrib/localflavor/is_/forms.py

 from django.newforms import ValidationError
 from django.newforms.fields import RegexField, EMPTY_VALUES
 from django.newforms.widgets import Select
-from django.utils.translation import gettext
+from django.utils.translation import ugettext
+from django.utils.encoding import smart_unicode
 
 class ISIdNumberField(RegexField):
     """
     of Iceland has.
     """
     def __init__(self, *args, **kwargs):
-        error_msg = gettext(u'Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.')
+        error_msg = ugettext('Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.')
         kwargs['min_length'],kwargs['max_length'] = 10,11
         super(ISIdNumberField, self).__init__(r'^\d{6}(-| )?\d{4}$', error_message=error_msg, *args, **kwargs)
 
         if self._validate(value):
             return self._format(value)
         else:
-            raise ValidationError(gettext(u'The Icelandic identification number is not valid.'))
+            raise ValidationError(ugettext(u'The Icelandic identification number is not valid.'))
 
     def _canonify(self, value):
         """
         Takes in the value in canonical form and returns it in the common
         display format.
         """
-        return value[:6]+'-'+value[6:]
+        return smart_unicode(value[:6]+'-'+value[6:])
 
 class ISPhoneNumberField(RegexField):
     """

django/contrib/localflavor/it/forms.py

 
 from django.newforms import ValidationError