Author: mtredinnick
Date: 2007-05-12 05:34:34 -0500 (Sat, 12 May 2007)
New Revision: 5200
Modified:
django/branches/unicode/django/contrib/admin/filterspecs.py
django/branches/unicode/django/contrib/admin/models.py
django/branches/unicode/django/contrib/admin/templatetags/admin_list.py
django/branches/unicode/django/contrib/admin/templatetags/admin_modify.py
django/branches/unicode/django/contrib/admin/views/main.py
Log:
unicode: Adjusted the admin interface to handle unicode strings. May still need
some tweaking, but the bulk of it should be correct. Fixed #4266.
Modified: django/branches/unicode/django/contrib/admin/filterspecs.py
===================================================================
--- django/branches/unicode/django/contrib/admin/filterspecs.py 2007-05-12
06:54:41 UTC (rev 5199)
+++ django/branches/unicode/django/contrib/admin/filterspecs.py 2007-05-12
10:34:34 UTC (rev 5200)
@@ -7,6 +7,7 @@
"""
from django.db import models
+from django.utils.encoding import smart_unicode
import datetime
class FilterSpec(object):
@@ -37,10 +38,10 @@
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'] ,
choice['display']))
@@ -70,7 +71,7 @@
'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}
@@ -87,7 +88,7 @@
'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}
@@ -168,7 +169,7 @@
'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}
Modified: django/branches/unicode/django/contrib/admin/models.py
===================================================================
--- django/branches/unicode/django/contrib/admin/models.py 2007-05-12
06:54:41 UTC (rev 5199)
+++ django/branches/unicode/django/contrib/admin/models.py 2007-05-12
10:34:34 UTC (rev 5200)
@@ -28,7 +28,7 @@
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
@@ -48,4 +48,4 @@
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)
Modified:
django/branches/unicode/django/contrib/admin/templatetags/admin_list.py
===================================================================
--- django/branches/unicode/django/contrib/admin/templatetags/admin_list.py
2007-05-12 06:54:41 UTC (rev 5199)
+++ django/branches/unicode/django/contrib/admin/templatetags/admin_list.py
2007-05-12 10:34:34 UTC (rev 5200)
@@ -7,6 +7,7 @@
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.encoding import smart_unicode, smart_str
from django.template import Library
import datetime
@@ -16,11 +17,11 @@
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):
@@ -74,10 +75,12 @@
f = lookup_opts.get_field(field_name)
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 = smart_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:
@@ -112,7 +115,7 @@
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
@@ -134,7 +137,7 @@
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:
@@ -177,19 +180,19 @@
elif f.choices:
result_repr = dict(f.choices).get(field_val,
EMPTY_CHANGELIST_VALUE)
else:
- result_repr = escape(str(field_val))
+ result_repr = escape(field_val)
if result_repr == '':
result_repr = ' '
# 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:
Modified:
django/branches/unicode/django/contrib/admin/templatetags/admin_modify.py
===================================================================
--- django/branches/unicode/django/contrib/admin/templatetags/admin_modify.py
2007-05-12 06:54:41 UTC (rev 5199)
+++ django/branches/unicode/django/contrib/admin/templatetags/admin_modify.py
2007-05-12 10:34:34 UTC (rev 5200)
@@ -2,6 +2,7 @@
from django.contrib.admin.views.main import AdminBoundField
from django.template import loader
from django.utils.text import capfirst
+from django.utils.encoding import smart_unicode
from django.db import models
from django.db.models.fields import Field
from django.db.models.related import BoundRelatedObject
@@ -14,7 +15,7 @@
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):
"""
@@ -31,7 +32,7 @@
"""
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):
@@ -61,8 +62,8 @@
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, \
+ 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, \
capfirst(bound_field.field.verbose_name), colon)
field_label = register.simple_tag(field_label)
@@ -77,7 +78,7 @@
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
@@ -175,30 +176,30 @@
return output
def output_all(form_fields):
- return ''.join([str(f) for f in form_fields])
+ return u''.join([smart_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:
Modified: django/branches/unicode/django/contrib/admin/views/main.py
===================================================================
--- django/branches/unicode/django/contrib/admin/views/main.py 2007-05-12
06:54:41 UTC (rev 5199)
+++ django/branches/unicode/django/contrib/admin/views/main.py 2007-05-12
10:34:34 UTC (rev 5200)
@@ -12,6 +12,7 @@
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 smart_unicode
import operator
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION
@@ -142,7 +143,7 @@
if isinstance(self.field.rel, models.ManyToOneRel):
self._display = getattr(self.original, self.field.name)
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([smart_unicode(obj) for obj in
getattr(self.original, self.field.name).all()])
return self._display
def __repr__(self):
@@ -253,7 +254,7 @@
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)
+ LogEntry.objects.log_action(request.user.id,
ContentType.objects.get_for_model(model).id, pk_value,
smart_unicode(new_object), ADDITION)
msg = _('The %(name)s "%(obj)s" was added successfully.') %
{'name': opts.verbose_name, 'obj': new_object}
# Here, we distinguish between different save types by checking for
# the presence of keys in request.POST.
@@ -266,7 +267,7 @@
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, smart_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))
return HttpResponseRedirect(request.path)
@@ -340,7 +341,7 @@
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,
smart_unicode(new_object), CHANGE, change_message)
msg = _('The %(name)s "%(obj)s" was changed successfully.') %
{'name': opts.verbose_name, 'obj': new_object}
if "_continue" in request.POST:
@@ -443,11 +444,11 @@
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, ['%s: %s' %
(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))), []])
+ (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.
@@ -461,7 +462,7 @@
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)
@@ -474,13 +475,13 @@
# 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': related.field.verbose_name, 'name':
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)))), []])
+ (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:
@@ -501,14 +502,14 @@
# 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 = ['%s: <a href="../../%s/">%s</a>' %
(capfirst(opts.verbose_name), object_id, escape(obj)), []]
perms_needed = sets.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 = smart_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})
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---