Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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


git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 953badbea5a04159adbfa970f5805c0232b6a401 1 parent 4c958b1
@malcolmt malcolmt authored
Showing with 3,000 additions and 1,598 deletions.
  1. +2 −0  AUTHORS
  2. +1 −1  django/bin/make-messages.py
  3. +3 −0  django/conf/global_settings.py
  4. +8 −6 django/contrib/admin/filterspecs.py
  5. +95 −0 django/contrib/admin/media/js/urlify.js
  6. +5 −4 django/contrib/admin/models.py
  7. +1 −1  django/contrib/admin/templates/admin/filter.html
  8. +19 −16 django/contrib/admin/templatetags/admin_list.py
  9. +14 −13 django/contrib/admin/templatetags/admin_modify.py
  10. +3 −2 django/contrib/admin/templatetags/adminapplist.py
  11. +1 −0  django/contrib/admin/views/auth.py
  12. +2 −2 django/contrib/admin/views/decorators.py
  13. +1 −0  django/contrib/admin/views/doc.py
  14. +41 −33 django/contrib/admin/views/main.py
  15. +1 −1  django/contrib/auth/forms.py
  16. +2 −2 django/contrib/auth/management.py
  17. +20 −15 django/contrib/auth/models.py
  18. +1 −0  django/contrib/auth/views.py
  19. +2 −2 django/contrib/comments/feeds.py
  20. +1 −1  django/contrib/comments/models.py
  21. +5 −4 django/contrib/comments/views/comments.py
  22. +1 −0  django/contrib/comments/views/karma.py
  23. +2 −2 django/contrib/contenttypes/generic.py
  24. +2 −1  django/contrib/contenttypes/management.py
  25. +7 −6 django/contrib/contenttypes/models.py
  26. +18 −14 django/contrib/databrowse/datastructures.py
  27. +5 −4 django/contrib/databrowse/plugins/calendars.py
  28. +7 −5 django/contrib/databrowse/plugins/fieldchoices.py
  29. +1 −1  django/contrib/databrowse/sites.py
  30. +1 −1  django/contrib/databrowse/templates/databrowse/fieldchoice_list.html
  31. +3 −3 django/contrib/flatpages/models.py
  32. +9 −9 django/contrib/humanize/templatetags/humanize.py
  33. +6 −6 django/contrib/localflavor/au/forms.py
  34. +10 −10 django/contrib/localflavor/br/forms.py
  35. +1 −1  django/contrib/localflavor/ch/ch_states.py
  36. +3 −3 django/contrib/localflavor/ch/forms.py
  37. +8 −7 django/contrib/localflavor/cl/forms.py
  38. +1 −1  django/contrib/localflavor/de/de_states.py
  39. +6 −6 django/contrib/localflavor/de/forms.py
  40. +6 −6 django/contrib/localflavor/fi/forms.py
  41. +4 −4 django/contrib/localflavor/fr/forms.py
  42. +5 −4 django/contrib/localflavor/is_/forms.py
  43. +7 −7 django/contrib/localflavor/it/forms.py
  44. +1 −1  django/contrib/localflavor/it/it_province.py
  45. +15 −11 django/contrib/localflavor/it/util.py
  46. +3 −3 django/contrib/localflavor/jp/forms.py
  47. +48 −48 django/contrib/localflavor/jp/jp_prefectures.py
  48. +6 −6 django/contrib/localflavor/no/forms.py
  49. +5 −5 django/contrib/localflavor/no/no_municipalities.py
  50. +2 −2 django/contrib/localflavor/uk/forms.py
  51. +10 −10 django/contrib/localflavor/us/forms.py
  52. +8 −7 django/contrib/markup/templatetags/markup.py
  53. +3 −3 django/contrib/redirects/models.py
  54. +1 −1  django/contrib/sessions/models.py
  55. +2 −1  django/contrib/sitemaps/views.py
  56. +2 −2 django/contrib/sites/models.py
  57. +8 −5 django/contrib/syndication/feeds.py
  58. +39 −7 django/contrib/webdesign/lorem_ipsum.py
  59. +1 −1  django/contrib/webdesign/templatetags/webdesign.py
  60. +2 −2 django/contrib/webdesign/tests.py
  61. +3 −3 django/core/handlers/modpython.py
  62. +5 −5 django/core/handlers/wsgi.py
  63. +35 −6 django/core/mail.py
  64. +3 −3 django/core/management.py
  65. +8 −8 django/core/serializers/__init__.py
  66. +3 −2 django/core/serializers/base.py
  67. +22 −27 django/core/serializers/python.py
  68. +2 −2 django/core/serializers/pyyaml.py
  69. +42 −40 django/core/serializers/xml_serializer.py
  70. +17 −10 django/core/urlresolvers.py
  71. +61 −58 django/core/validators.py
  72. +1 −1  django/db/backends/mysql/base.py
  73. +2 −0  django/db/backends/mysql_old/base.py
  74. +49 −15 django/db/backends/oracle/base.py
  75. +5 −5 django/db/backends/oracle/creation.py
  76. +35 −15 django/db/backends/postgresql/base.py
  77. +4 −0 django/db/backends/postgresql_psycopg2/base.py
  78. +6 −13 django/db/backends/sqlite3/base.py
  79. +13 −6 django/db/backends/util.py
  80. +6 −3 django/db/models/base.py
  81. +27 −26 django/db/models/fields/__init__.py
  82. +6 −5 django/db/models/fields/related.py
  83. +4 −2 django/db/models/manipulators.py
  84. +19 −3 django/db/models/options.py
  85. +2 −1  django/db/models/query.py
  86. +82 −16 django/http/__init__.py
  87. +36 −36 django/newforms/fields.py
  88. +8 −8 django/newforms/forms.py
  89. +8 −6 django/newforms/models.py
  90. +9 −9 django/newforms/util.py
  91. +20 −20 django/newforms/widgets.py
  92. +91 −81 django/oldforms/__init__.py
  93. +21 −20 django/template/__init__.py
  94. +67 −72 django/template/defaultfilters.py
  95. +4 −3 django/template/defaulttags.py
  96. +1 −1  django/template/loaders/app_directories.py
  97. +1 −1  django/template/loaders/eggs.py
  98. +1 −1  django/template/loaders/filesystem.py
  99. +4 −4 django/templatetags/i18n.py
  100. +18 −15 django/test/client.py
  101. +6 −6 django/test/testcases.py
  102. +2 −2 django/test/utils.py
  103. +2 −1  django/utils/cache.py
  104. +28 −26 django/utils/dateformat.py
  105. +5 −1 django/utils/dates.py
  106. +68 −16 django/utils/encoding.py
  107. +29 −21 django/utils/feedgenerator.py
  108. +54 −1 django/utils/functional.py
  109. +25 −16 django/utils/html.py
  110. +35 −0 django/utils/http.py
  111. +1 −1  django/utils/stopwords.py
  112. +34 −20 django/utils/text.py
  113. +10 −10 django/utils/timesince.py
  114. +18 −5 django/utils/translation/__init__.py
  115. +9 −2 django/utils/translation/trans_null.py
  116. +63 −32 django/utils/translation/trans_real.py
  117. +10 −3 django/utils/tzinfo.py
  118. +13 −1 django/views/debug.py
  119. +4 −4 django/views/generic/create_update.py
  120. +1 −0  docs/contributing.txt
  121. +3 −3 docs/db-api.txt
  122. +1 −1  docs/forms.txt
  123. +128 −48 docs/i18n.txt
  124. +40 −10 docs/model-api.txt
  125. +1 −1  docs/newforms.txt
  126. +2 −2 docs/overview.txt
  127. +10 −0 docs/settings.txt
  128. +10 −0 docs/templates.txt
  129. +24 −7 docs/tutorial01.txt
  130. +363 −0 docs/unicode.txt
  131. +3 −2 tests/modeltests/basic/models.py
  132. +3 −3 tests/modeltests/choices/models.py
  133. +9 −9 tests/modeltests/custom_columns/models.py
  134. +4 −4 tests/modeltests/custom_managers/models.py
  135. +1 −1  tests/modeltests/custom_methods/models.py
  136. +5 −5 tests/modeltests/custom_pk/models.py
  137. +1 −1  tests/modeltests/field_defaults/models.py
  138. +10 −10 tests/modeltests/fixtures/models.py
  139. +8 −8 tests/modeltests/generic_relations/models.py
  140. +2 −2 tests/modeltests/get_latest/models.py
  141. +2 −2 tests/modeltests/get_object_or_404/models.py
  142. +2 −2 tests/modeltests/get_or_create/models.py
  143. +16 −16 tests/modeltests/lookup/models.py
  144. +2 −2 tests/modeltests/m2m_and_m2o/models.py
  145. +5 −5 tests/modeltests/m2m_intermediary/models.py
  146. +2 −2 tests/modeltests/m2m_multiple/models.py
  147. +1 −1  tests/modeltests/m2m_recursive/models.py
  148. +1 −1  tests/modeltests/m2o_recursive/models.py
  149. +1 −1  tests/modeltests/m2o_recursive2/models.py
  150. +8 −8 tests/modeltests/manipulators/models.py
  151. +2 −2 tests/modeltests/many_to_many/models.py
  152. +10 −5 tests/modeltests/many_to_one/models.py
  153. +2 −2 tests/modeltests/many_to_one_null/models.py
  154. +8 −8 tests/modeltests/model_forms/models.py
  155. +6 −6 tests/modeltests/model_inheritance/models.py
  156. +6 −6 tests/modeltests/one_to_one/models.py
  157. +2 −2 tests/modeltests/or_lookups/models.py
  158. +1 −1  tests/modeltests/ordering/models.py
  159. +1 −1  tests/modeltests/pagination/models.py
  160. +1 −1  tests/modeltests/reserved_names/models.py
  161. +3 −3 tests/modeltests/reverse_lookup/models.py
  162. +2 −2 tests/modeltests/save_delete_hooks/models.py
  163. +8 −8 tests/modeltests/select_related/models.py
  164. +5 −5 tests/modeltests/serializers/models.py
  165. +29 −7 tests/modeltests/str/models.py
  166. +7 −3 tests/modeltests/test_client/models.py
  167. +1 −1  tests/modeltests/test_client/views.py
  168. +3 −3 tests/modeltests/transactions/models.py
  169. +7 −7 tests/modeltests/validation/models.py
  170. +23 −23 tests/regressiontests/dateformat/tests.py
  171. +230 −216 tests/regressiontests/defaultfilters/tests.py
  172. +3 −3 tests/regressiontests/fixtures_regress/models.py
  173. +7 −7 tests/regressiontests/forms/localflavor.py
  174. +44 −5 tests/regressiontests/forms/regressions.py
  175. +1 −1  tests/regressiontests/forms/tests.py
  176. +43 −33 tests/regressiontests/httpwrappers/tests.py
  177. +5 −5 tests/regressiontests/humanize/tests.py
  178. 0  tests/regressiontests/i18n/__init__.py
  179. 0  tests/regressiontests/i18n/models.py
  180. +33 −0 tests/regressiontests/i18n/tests.py
  181. 0  tests/regressiontests/model_regress/__init__.py
  182. +34 −0 tests/regressiontests/model_regress/models.py
  183. +4 −4 tests/regressiontests/null_queries/models.py
  184. +6 −6 tests/regressiontests/one_to_one_regress/models.py
  185. +3 −0  tests/regressiontests/serializers_regress/tests.py
  186. +27 −11 tests/regressiontests/string_lookup/models.py
  187. +14 −7 tests/regressiontests/templates/tests.py
  188. +33 −0 tests/regressiontests/templates/unicode.py
  189. +2 −0  tests/regressiontests/templates/urls.py
  190. +11 −1 tests/regressiontests/test_client_regress/models.py
  191. +1 −1  tests/regressiontests/test_client_regress/urls.py
  192. +13 −1 tests/regressiontests/test_client_regress/views.py
  193. +26 −5 tests/regressiontests/text/tests.py
View
2  AUTHORS
@@ -113,6 +113,7 @@ answer newbie questions, and generally made Django that much better:
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
@@ -147,6 +148,7 @@ answer newbie questions, and generally made Django that much better:
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/>
View
2  django/bin/make-messages.py
@@ -103,7 +103,7 @@ def make_messages():
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()
View
3  django/conf/global_settings.py
@@ -97,6 +97,9 @@
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'
View
14 django/contrib/admin/filterspecs.py
@@ -7,6 +7,8 @@
"""
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):
@@ -37,12 +39,12 @@ def title(self):
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)
@@ -70,7 +72,7 @@ def choices(self, cl):
'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 +89,7 @@ def choices(self, cl):
'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 +170,7 @@ def choices(self, cl):
'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}
View
95 django/contrib/admin/media/js/urlify.js
@@ -1,15 +1,110 @@
+var LATIN_MAP =
+{
+ 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
+ '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', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w',
+ 'ά':'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
}
+
View
9 django/contrib/admin/models.py
@@ -1,7 +1,8 @@
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
@@ -9,7 +10,7 @@
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):
@@ -28,7 +29,7 @@ class Meta:
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 +49,4 @@ def get_admin_url(self):
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)
View
2  django/contrib/admin/templates/admin/filter.html
@@ -3,6 +3,6 @@
<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>
View
35 django/contrib/admin/templatetags/admin_list.py
@@ -6,7 +6,8 @@
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
@@ -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):
@@ -75,10 +76,12 @@ def result_headers(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:
@@ -114,7 +117,7 @@ def result_headers(cl):
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
@@ -136,7 +139,7 @@ def items_for_result(cl, result):
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:
@@ -179,19 +182,19 @@ def items_for_result(cl, result):
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:
View
27 django/contrib/admin/templatetags/admin_modify.py
@@ -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 force_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 @@ 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):
@@ -61,9 +62,9 @@ def field_label(bound_field):
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):
@@ -77,7 +78,7 @@ def get_nodelist(cls, klass):
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 @@ def render(self, context):
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:
View
5 django/contrib/admin/templatetags/adminapplist.py
@@ -1,5 +1,6 @@
from django import template
from django.db.models import get_models
+from django.utils.encoding import force_unicode
register = template.Library()
@@ -36,8 +37,8 @@ def render(self, context):
# 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,
})
View
1  django/contrib/admin/views/auth.py
@@ -6,6 +6,7 @@
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'):
View
4 django/contrib/admin/views/decorators.py
@@ -3,11 +3,11 @@
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=''):
View
1  django/contrib/admin/views/doc.py
@@ -9,6 +9,7 @@
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
View
74 django/contrib/admin/views/main.py
@@ -12,6 +12,8 @@
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:
@@ -130,11 +132,11 @@ def __init__(self, field, field_mapping, original):
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:
@@ -145,9 +147,9 @@ def existing_display(self):
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):
@@ -258,8 +260,8 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
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:
@@ -271,9 +273,9 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
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)
@@ -291,7 +293,7 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
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,
@@ -345,9 +347,9 @@ def change_stage(request, app_label, model_name, object_id):
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:
@@ -355,10 +357,10 @@ def change_stage(request, app_label, model_name, object_id):
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)
@@ -393,7 +395,7 @@ def change_stage(request, app_label, model_name, object_id):
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,
@@ -434,11 +436,11 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
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:
@@ -448,11 +450,11 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
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.
@@ -466,7 +468,7 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
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)
@@ -479,17 +481,17 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
# 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)
@@ -505,21 +507,21 @@ def delete_stage(request, app_label, model_name, object_id):
# 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,
@@ -542,7 +544,7 @@ def history(request, app_label, model_name, object_id):
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()),
@@ -574,7 +576,7 @@ def __init__(self, request, model):
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
@@ -602,7 +604,7 @@ def get_query_string(self, new_params=None, remove=None):
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)
@@ -688,6 +690,12 @@ def get_query_set(self):
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)
View
2  django/contrib/auth/forms.py
@@ -4,7 +4,7 @@
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."
View
4 django/contrib/auth/management.py
@@ -7,13 +7,13 @@
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):
View
35 django/contrib/auth/models.py
@@ -2,8 +2,10 @@
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
@@ -18,16 +20,16 @@ def check_password(raw_password, enc_password):
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):
@@ -56,8 +58,8 @@ class Meta:
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.
@@ -77,7 +79,7 @@ class Meta:
class Admin:
search_fields = ('name',)
- def __str__(self):
+ def __unicode__(self):
return self.name
class UserManager(models.Manager):
@@ -133,11 +135,11 @@ class Admin:
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."
@@ -150,14 +152,14 @@ def is_authenticated(self):
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):
@@ -169,7 +171,7 @@ 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)
@@ -209,7 +211,7 @@ def get_group_permissions(self):
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
@@ -271,7 +273,7 @@ class Message(models.Model):
user = models.ForeignKey(User)
message = models.TextField(_('message'))
- def __str__(self):
+ def __unicode__(self):
return self.message
class AnonymousUser(object):
@@ -281,9 +283,12 @@ class AnonymousUser(object):
def __init__(self):
pass
- def __str__(self):
+ def __unicode__(self):
return 'AnonymousUser'
+ def __str__(self):
+ return unicode(self).encode('utf-8')
+
def __eq__(self, other):
return isinstance(other, self.__class__)
View
1  django/contrib/auth/views.py
@@ -7,6 +7,7 @@
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."
View
4 django/contrib/comments/feeds.py
@@ -11,7 +11,7 @@ class LatestFreeCommentsFeed(Feed):
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'):
@@ -21,7 +21,7 @@ def link(self):
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)
View
2  django/contrib/comments/models.py
@@ -2,7 +2,7 @@
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
View
9 django/contrib/comments/views/comments.py
@@ -11,7 +11,8 @@
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
@@ -108,7 +109,7 @@ def save(self, new_data):
# 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)
@@ -248,7 +249,7 @@ def ratings(self):
# 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)
@@ -312,7 +313,7 @@ def post_free_comment(request):
# 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)
View
1  django/contrib/comments/views/karma.py
@@ -2,6 +2,7 @@
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):
"""
View
4 django/contrib/contenttypes/generic.py
@@ -49,7 +49,7 @@ def get_content_type(self, obj):
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)
@@ -66,7 +66,7 @@ def __get__(self, instance, instance_type=None):
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
View
3  django/contrib/contenttypes/management.py
@@ -4,6 +4,7 @@
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
@@ -17,7 +18,7 @@ def create_contenttypes(app, created_models, verbosity=2):
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:
View
13 django/contrib/contenttypes/models.py
@@ -1,5 +1,6 @@
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):
@@ -13,13 +14,13 @@ def get_for_model(self, model):
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
@@ -42,7 +43,7 @@ class Meta:
ordering = ('name',)
unique_together = (('app_label', 'model'),)
- def __str__(self):
+ def __unicode__(self):
return self.name
def model_class(self):
View
32 django/contrib/databrowse/datastructures.py
@@ -7,6 +7,7 @@
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)'
@@ -19,7 +20,7 @@ def __init__(self, site, model):
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."
@@ -54,7 +55,7 @@ def __init__(self, easy_model, field):
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:
@@ -72,29 +73,32 @@ def __init__(self, easy_model, field, value, label):
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 __str__(self):
- val = str(self.instance)
+ def __unicode__(self):
+ val = smart_unicode(self.instance)
if len(val) > 30:
- return val[:30] + '...'
+ return val[:30] + u'...'
return val
+ def __str__(self):
+ 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):
"""
@@ -126,7 +130,7 @@ def __init__(self, easy_model, instance, field):
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):
"""
@@ -175,18 +179,18 @@ def urls(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
View
9 django/contrib/databrowse/plugins/calendars.py
@@ -6,6 +6,7 @@
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
@@ -27,13 +28,13 @@ def field_dict(self, model):
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(),
View
12 django/contrib/databrowse/plugins/fieldchoices.py
@@ -4,9 +4,11 @@
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):
@@ -29,15 +31,15 @@ def field_dict(self, model):
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
View
2  django/contrib/databrowse/sites.py
@@ -60,7 +60,7 @@ def root(self, request, url):
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,
View
2  django/contrib/databrowse/templates/databrowse/fieldchoice_list.html
@@ -10,7 +10,7 @@
<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>
View
6 django/contrib/flatpages/models.py
@@ -1,7 +1,7 @@
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,
@@ -26,8 +26,8 @@ class Admin:
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
View
18 django/contrib/humanize/templatetags/humanize.py
@@ -1,5 +1,5 @@
-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
@@ -16,8 +16,8 @@ def ordinal(value):
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):
@@ -25,8 +25,8 @@ 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:
@@ -44,13 +44,13 @@ def intword(value):
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)
View
12 django/contrib/localflavor/au/forms.py
@@ -5,7 +5,7 @@
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})$')
@@ -15,14 +15,14 @@ class AUPostCodeField(RegexField):
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:
@@ -39,5 +39,5 @@ class AUStateSelect(Select):
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)
View
20 django/contrib/localflavor/br/forms.py
@@ -6,7 +6,7 @@
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})$')
@@ -15,8 +15,8 @@ class BRZipCodeField(RegexField):
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):
@@ -27,7 +27,7 @@ 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):
"""
@@ -35,7 +35,7 @@ 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)
@@ -69,9 +69,9 @@ def clean(self, value):
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))])
@@ -81,7 +81,7 @@ def clean(self, value):
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
@@ -103,7 +103,7 @@ def clean(self, 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))])
@@ -113,7 +113,7 @@ def clean(self, value):
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
View
2  django/contrib/localflavor/ch/ch_states.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ugettext_lazy as _
STATE_CHOICES = (
('AG', _('Aargau')),
View
6 django/contrib/localflavor/ch/forms.py
@@ -5,7 +5,7 @@
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})$")
@@ -15,7 +15,7 @@ class CHZipCodeField(RegexField):
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):
@@ -87,7 +87,7 @@ def has_valid_checksum(self, number):
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''
View
15 django/contrib/localflavor/cl/forms.py
@@ -4,7 +4,8 @@
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):
"""