Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'master' of github.com:django/django into schema-alteration

Conflicts:
	django/db/backends/postgresql_psycopg2/base.py
  • Loading branch information...
commit 4a2e80fff44d0eb1856b593ac5f31ab1492b3e45 2 parents 959a3f9 + ab6cd1c
Andrew Godwin authored July 26, 2012

Showing 302 changed files with 3,199 additions and 2,083 deletions. Show diff stats Hide diff stats

  1. 2  AUTHORS
  2. 8  django/conf/__init__.py
  3. 5  django/conf/urls/__init__.py
  4. 15  django/contrib/admin/helpers.py
  5. 3  django/contrib/admin/models.py
  6. 9  django/contrib/admin/options.py
  7. 3  django/contrib/admin/sites.py
  8. 3  django/contrib/admin/static/admin/css/widgets.css
  9. 3  django/contrib/admin/templates/admin/auth/user/change_password.html
  10. 5  django/contrib/admin/templates/admin/change_form.html
  11. 3  django/contrib/admin/templates/admin/change_list.html
  12. 2  django/contrib/admin/templates/admin/delete_confirmation.html
  13. 2  django/contrib/admin/templates/admin/edit_inline/stacked.html
  14. 2  django/contrib/admin/templates/admin/edit_inline/tabular.html
  15. 2  django/contrib/admin/templates/admin/object_history.html
  16. 42  django/contrib/admin/templatetags/admin_list.py
  17. 2  django/contrib/admin/templatetags/admin_modify.py
  18. 8  django/contrib/admin/templatetags/admin_urls.py
  19. 20  django/contrib/admin/util.py
  20. 18  django/contrib/admin/widgets.py
  21. 2  django/contrib/admindocs/templates/admin_doc/bookmarklets.html
  22. 2  django/contrib/admindocs/views.py
  23. 2  django/contrib/auth/admin.py
  24. 10  django/contrib/auth/decorators.py
  25. 24  django/contrib/auth/forms.py
  26. 17  django/contrib/auth/models.py
  27. 6  django/contrib/auth/tests/basic.py
  28. 3  django/contrib/auth/tests/management.py
  29. 36  django/contrib/auth/tests/models.py
  30. 10  django/contrib/auth/tests/views.py
  31. 5  django/contrib/auth/tokens.py
  32. 13  django/contrib/auth/views.py
  33. 6  django/contrib/comments/views/moderation.py
  34. 10  django/contrib/comments/views/utils.py
  35. 9  django/contrib/contenttypes/tests.py
  36. 15  django/contrib/databrowse/datastructures.py
  37. 11  django/contrib/databrowse/plugins/calendars.py
  38. 17  django/contrib/databrowse/plugins/fieldchoices.py
  39. 8  django/contrib/databrowse/plugins/objects.py
  40. 2  django/contrib/flatpages/views.py
  41. 3  django/contrib/formtools/utils.py
  42. 10  django/contrib/formtools/wizard/views.py
  43. 5  django/contrib/gis/admin/widgets.py
  44. 7  django/contrib/gis/db/backends/base.py
  45. 5  django/contrib/gis/db/backends/oracle/operations.py
  46. 5  django/contrib/gis/db/backends/postgis/operations.py
  47. 3  django/contrib/gis/db/backends/spatialite/introspection.py
  48. 5  django/contrib/gis/db/backends/spatialite/operations.py
  49. 6  django/contrib/gis/db/backends/util.py
  50. 3  django/contrib/gis/db/models/fields.py
  51. 3  django/contrib/gis/db/models/proxy.py
  52. 15  django/contrib/gis/db/models/query.py
  53. 2  django/contrib/gis/db/models/sql/compiler.py
  54. 18  django/contrib/gis/forms/fields.py
  55. 4  django/contrib/gis/gdal/__init__.py
  56. 3  django/contrib/gis/gdal/base.py
  57. 11  django/contrib/gis/gdal/datasource.py
  58. 10  django/contrib/gis/gdal/driver.py
  59. 17  django/contrib/gis/gdal/feature.py
  60. 35  django/contrib/gis/gdal/geometries.py
  61. 8  django/contrib/gis/gdal/geomtype.py
  62. 19  django/contrib/gis/gdal/layer.py
  63. 28  django/contrib/gis/gdal/libgdal.py
  64. 19  django/contrib/gis/gdal/prototypes/errcheck.py
  65. 15  django/contrib/gis/gdal/prototypes/geom.py
  66. 32  django/contrib/gis/gdal/srs.py
  67. 8  django/contrib/gis/gdal/tests/test_geom.py
  68. 6  django/contrib/gis/geoip/base.py
  69. 4  django/contrib/gis/geoip/tests.py
  70. 1  django/contrib/gis/geos/base.py
  71. 9  django/contrib/gis/geos/collections.py
  72. 1  django/contrib/gis/geos/coordseq.py
  73. 4  django/contrib/gis/geos/factory.py
  74. 19  django/contrib/gis/geos/geometry.py
  75. 3  django/contrib/gis/geos/linestring.py
  76. 8  django/contrib/gis/geos/mutable_list.py
  77. 6  django/contrib/gis/geos/point.py
  78. 4  django/contrib/gis/geos/polygon.py
  79. 8  django/contrib/gis/geos/prototypes/io.py
  80. 1  django/contrib/gis/geos/prototypes/misc.py
  81. 11  django/contrib/gis/geos/tests/test_geos.py
  82. 11  django/contrib/gis/geos/tests/test_io.py
  83. 3  django/contrib/gis/geos/tests/test_mutable_list.py
  84. 19  django/contrib/gis/maps/google/gmap.py
  85. 11  django/contrib/gis/maps/google/overlays.py
  86. 21  django/contrib/gis/maps/google/zoom.py
  87. 5  django/contrib/gis/measure.py
  88. 3  django/contrib/gis/tests/geoapp/tests.py
  89. 17  django/contrib/gis/tests/test_geoforms.py
  90. 11  django/contrib/gis/utils/layermapping.py
  91. 5  django/contrib/gis/utils/ogrinspect.py
  92. 8  django/contrib/gis/utils/wkt.py
  93. 12  django/contrib/humanize/templatetags/humanize.py
  94. 78  django/contrib/humanize/tests.py
  95. 12  django/contrib/localflavor/ar/forms.py
  96. 11  django/contrib/localflavor/fr/forms.py
  97. 9  django/contrib/localflavor/mx/forms.py
  98. 5  django/contrib/localflavor/se/utils.py
  99. 6  django/contrib/localflavor/tr/forms.py
  100. 10  django/contrib/messages/tests/base.py
  101. 2  django/contrib/messages/tests/cookie.py
  102. 2  django/contrib/sessions/backends/base.py
  103. 1  django/contrib/sessions/backends/cache.py
  104. 2  django/contrib/sessions/backends/signed_cookies.py
  105. 16  django/contrib/sessions/middleware.py
  106. 16  django/contrib/sessions/tests.py
  107. 10  django/contrib/sitemaps/__init__.py
  108. 2  django/contrib/sitemaps/tests/generic.py
  109. 10  django/contrib/staticfiles/handlers.py
  110. 32  django/contrib/staticfiles/storage.py
  111. 30  django/contrib/staticfiles/templatetags/staticfiles.py
  112. 7  django/contrib/staticfiles/views.py
  113. 11  django/contrib/syndication/views.py
  114. 5  django/core/cache/__init__.py
  115. 16  django/core/cache/backends/db.py
  116. 2  django/core/cache/backends/filebased.py
  117. 2  django/core/cache/backends/locmem.py
  118. 4  django/core/cache/backends/memcached.py
  119. 7  django/core/files/storage.py
  120. 3  django/core/handlers/base.py
  121. 5  django/core/handlers/wsgi.py
  122. 28  django/core/mail/backends/console.py
  123. 3  django/core/mail/backends/filebased.py
  124. 5  django/core/mail/backends/smtp.py
  125. 9  django/core/mail/message.py
  126. 2  django/core/management/__init__.py
  127. 4  django/core/management/commands/dumpdata.py
  128. 4  django/core/management/commands/flush.py
  129. 3  django/core/management/commands/inspectdb.py
  130. 67  django/core/management/commands/makemessages.py
  131. 24  django/core/management/commands/shell.py
  132. 34  django/core/management/sql.py
  133. 10  django/core/management/templates.py
  134. 11  django/core/management/validation.py
  135. 3  django/core/serializers/base.py
  136. 8  django/core/serializers/json.py
  137. 6  django/core/serializers/pyyaml.py
  138. 15  django/core/servers/basehttp.py
  139. 15  django/core/urlresolvers.py
  140. 12  django/core/validators.py
  141. 103  django/db/backends/__init__.py
  142. 2  django/db/backends/creation.py
  143. 54  django/db/backends/mysql/base.py
  144. 74  django/db/backends/oracle/base.py
  145. 17  django/db/backends/postgresql_psycopg2/base.py
  146. 34  django/db/backends/postgresql_psycopg2/operations.py
  147. 26  django/db/backends/sqlite3/base.py
  148. 2  django/db/models/__init__.py
  149. 118  django/db/models/base.py
  150. 7  django/db/models/fields/__init__.py
  151. 11  django/db/models/fields/files.py
  152. 21  django/db/models/fields/related.py
  153. 17  django/db/models/loading.py
  154. 7  django/db/models/options.py
  155. 41  django/db/models/query.py
  156. 13  django/db/models/query_utils.py
  157. 9  django/db/models/sql/compiler.py
  158. 3  django/db/models/sql/datastructures.py
  159. 25  django/db/models/sql/query.py
  160. 2  django/db/models/sql/subqueries.py
  161. 83  django/db/models/sql/where.py
  162. 3  django/db/utils.py
  163. 68  django/dispatch/dispatcher.py
  164. 3  django/forms/extras/widgets.py
  165. 20  django/forms/fields.py
  166. 20  django/forms/forms.py
  167. 8  django/forms/formsets.py
  168. 12  django/forms/models.py
  169. 21  django/forms/util.py
  170. 71  django/forms/widgets.py
  171. 103  django/http/__init__.py
  172. 3  django/http/multipartparser.py
  173. 2  django/shortcuts/__init__.py
  174. 14  django/template/base.py
  175. 35  django/template/defaultfilters.py
  176. 19  django/template/defaulttags.py
  177. 3  django/template/loader.py
  178. 17  django/template/response.py
  179. 3  django/templatetags/i18n.py
  180. 69  django/templatetags/static.py
  181. 3  django/templatetags/tz.py
  182. 28  django/test/_doctest.py
  183. 16  django/test/client.py
  184. 28  django/test/html.py
  185. 12  django/test/signals.py
  186. 4  django/test/simple.py
  187. 79  django/test/testcases.py
  188. 3  django/test/utils.py
  189. 4  django/utils/archive.py
  190. 2  django/utils/autoreload.py
  191. 2  django/utils/baseconv.py
  192. 4  django/utils/checksums.py
  193. 7  django/utils/crypto.py
  194. 4  django/utils/daemonize.py
  195. 186  django/utils/datastructures.py
  196. 5  django/utils/dateformat.py
  197. 4  django/utils/dictconfig.py
  198. 61  django/utils/encoding.py
  199. 11  django/utils/feedgenerator.py
  200. 11  django/utils/formats.py
  201. 11  django/utils/functional.py
  202. 77  django/utils/html.py
  203. 24  django/utils/html_parser.py
  204. 31  django/utils/http.py
  205. 2  django/utils/importlib.py
  206. 1  django/utils/ipv6.py
  207. 6  django/utils/itercompat.py
  208. 5  django/utils/numberformat.py
  209. 109  django/utils/py3.py
  210. 4  django/utils/regex_helper.py
  211. 33  django/utils/safestring.py
  212. 367  django/utils/six.py
  213. 29  django/utils/text.py
  214. 5  django/utils/timezone.py
  215. 15  django/utils/translation/__init__.py
  216. 2  django/utils/translation/trans_real.py
  217. 2  django/views/csrf.py
  218. 13  django/views/debug.py
  219. 6  django/views/defaults.py
  220. 2  django/views/generic/detail.py
  221. 7  django/views/i18n.py
  222. 11  django/views/static.py
  223. 1  docs/conf.py
  224. 6  docs/faq/install.txt
  225. 11  docs/faq/models.txt
  226. 2  docs/howto/custom-management-commands.txt
  227. 8  docs/howto/custom-model-fields.txt
  228. 2  docs/howto/deployment/wsgi/uwsgi.txt
  229. 12  docs/howto/initial-data.txt
  230. 2  docs/howto/jython.txt
  231. 37  docs/internals/committers.txt
  232. 6  docs/internals/contributing/localizing.txt
  233. 2  docs/internals/contributing/writing-code/unit-tests.txt
  234. 2  docs/internals/contributing/writing-documentation.txt
  235. 7  docs/internals/deprecation.txt
  236. BIN  docs/intro/_images/admin12t.png
  237. 2  docs/intro/install.txt
  238. 23  docs/intro/tutorial02.txt
  239. 6  docs/intro/whatsnext.txt
  240. 18  docs/ref/class-based-views/generic-display.txt
  241. 35  docs/ref/contrib/admin/index.txt
  242. 2  docs/ref/contrib/comments/index.txt
  243. 5  docs/ref/contrib/formtools/form-wizard.txt
  244. 59  docs/ref/contrib/gis/deployment.txt
  245. 2  docs/ref/contrib/gis/gdal.txt
  246. 6  docs/ref/contrib/gis/geoquerysets.txt
  247. 4  docs/ref/contrib/gis/geos.txt
  248. 91  docs/ref/contrib/gis/install.txt
  249. 4  docs/ref/contrib/gis/model-api.txt
  250. 9  docs/ref/contrib/gis/sitemaps.txt
  251. 2  docs/ref/contrib/gis/tutorial.txt
  252. 6  docs/ref/contrib/localflavor.txt
  253. 7  docs/ref/contrib/messages.txt
  254. 2  docs/ref/contrib/sitemaps.txt
  255. 11  docs/ref/contrib/staticfiles.txt
  256. 8  docs/ref/databases.txt
  257. 26  docs/ref/django-admin.txt
  258. 6  docs/ref/forms/fields.txt
  259. 2  docs/ref/forms/widgets.txt
  260. 22  docs/ref/models/fields.txt
  261. 36  docs/ref/models/instances.txt
  262. 4  docs/ref/models/options.txt
  263. 47  docs/ref/models/querysets.txt
  264. 23  docs/ref/request-response.txt
  265. 2  docs/ref/settings.txt
  266. 23  docs/ref/templates/api.txt
  267. 23  docs/ref/templates/builtins.txt
  268. 71  docs/ref/utils.txt
  269. 2  docs/releases/1.0-beta-2.txt
  270. 4  docs/releases/1.0.1.txt
  271. 2  docs/releases/1.0.txt
  272. 4  docs/releases/1.1.txt
  273. 2  docs/releases/1.3.txt
  274. 12  docs/releases/1.4.txt
  275. 88  docs/releases/1.5.txt
  276. 10  docs/topics/class-based-views/generic-display.txt
  277. 4  docs/topics/class-based-views/index.txt
  278. 3  docs/topics/db/models.txt
  279. 7  docs/topics/db/transactions.txt
  280. 2  docs/topics/email.txt
  281. 23  docs/topics/files.txt
  282. 3  docs/topics/forms/index.txt
  283. 3  docs/topics/forms/modelforms.txt
  284. 3  docs/topics/http/middleware.txt
  285. 5  docs/topics/http/sessions.txt
  286. 4  docs/topics/http/shortcuts.txt
  287. 4  docs/topics/http/urls.txt
  288. 2  docs/topics/i18n/timezones.txt
  289. 10  docs/topics/i18n/translation.txt
  290. 6  docs/topics/install.txt
  291. 4  docs/topics/logging.txt
  292. 283  docs/topics/python3.txt
  293. 15  docs/topics/signals.txt
  294. 143  docs/topics/testing.txt
  295. 20  tests/modeltests/aggregation/tests.py
  296. 24  tests/modeltests/basic/tests.py
  297. 9  tests/modeltests/custom_columns/tests.py
  298. 3  tests/modeltests/custom_managers/tests.py
  299. 5  tests/modeltests/custom_pk/fields.py
  300. 15  tests/modeltests/custom_pk/tests.py
  301. 20  tests/modeltests/defer/tests.py
2  AUTHORS
@@ -30,6 +30,7 @@ The PRIMARY AUTHORS are (and/or have been):
30 30
     * Aymeric Augustin
31 31
     * Claude Paroz
32 32
     * Anssi Kääriäinen
  33
+    * Florian Apolloner
33 34
 
34 35
 More information on the main contributors to Django can be found in
35 36
 docs/internals/committers.txt.
@@ -61,7 +62,6 @@ answer newbie questions, and generally made Django that much better:
61 62
     andy@jadedplanet.net
62 63
     Fabrice Aneche <akh@nobugware.com>
63 64
     ant9000@netwise.it
64  
-    Florian Apolloner <florian@apolloner.eu>
65 65
     arien <regexbot@gmail.com>
66 66
     David Ascher <http://ascher.ca/>
67 67
     atlithorn <atlithorn@gmail.com>
8  django/conf/__init__.py
@@ -15,6 +15,7 @@
15 15
 from django.core.exceptions import ImproperlyConfigured
16 16
 from django.utils.functional import LazyObject, empty
17 17
 from django.utils import importlib
  18
+from django.utils import six
18 19
 
19 20
 ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
20 21
 
@@ -73,7 +74,7 @@ def __setattr__(self, name, value):
73 74
         elif name == "ADMIN_MEDIA_PREFIX":
74 75
             warnings.warn("The ADMIN_MEDIA_PREFIX setting has been removed; "
75 76
                           "use STATIC_URL instead.", DeprecationWarning)
76  
-        elif name == "ALLOWED_INCLUDE_ROOTS" and isinstance(value, basestring):
  77
+        elif name == "ALLOWED_INCLUDE_ROOTS" and isinstance(value, six.string_types):
77 78
             raise ValueError("The ALLOWED_INCLUDE_ROOTS setting must be set "
78 79
                 "to a tuple, not a string.")
79 80
         object.__setattr__(self, name, value)
@@ -102,7 +103,10 @@ def __init__(self, settings_module):
102 103
             if setting == setting.upper():
103 104
                 setting_value = getattr(mod, setting)
104 105
                 if setting in tuple_settings and \
105  
-                        isinstance(setting_value, basestring):
  106
+                        isinstance(setting_value, six.string_types):
  107
+                    warnings.warn("The %s setting must be a tuple. Please fix your "
  108
+                                  "settings, as auto-correction is now deprecated." % setting,
  109
+                        PendingDeprecationWarning)
106 110
                     setting_value = (setting_value,) # In case the user forgot the comma.
107 111
                 setattr(self, setting, setting_value)
108 112
 
5  django/conf/urls/__init__.py
@@ -2,6 +2,7 @@
2 2
     RegexURLResolver, LocaleRegexURLResolver)
3 3
 from django.core.exceptions import ImproperlyConfigured
4 4
 from django.utils.importlib import import_module
  5
+from django.utils import six
5 6
 
6 7
 
7 8
 __all__ = ['handler403', 'handler404', 'handler500', 'include', 'patterns', 'url']
@@ -20,7 +21,7 @@ def include(arg, namespace=None, app_name=None):
20 21
         # No namespace hint - use manually provided namespace
21 22
         urlconf_module = arg
22 23
 
23  
-    if isinstance(urlconf_module, basestring):
  24
+    if isinstance(urlconf_module, six.string_types):
24 25
         urlconf_module = import_module(urlconf_module)
25 26
     patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
26 27
 
@@ -52,7 +53,7 @@ def url(regex, view, kwargs=None, name=None, prefix=''):
52 53
         urlconf_module, app_name, namespace = view
53 54
         return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
54 55
     else:
55  
-        if isinstance(view, basestring):
  56
+        if isinstance(view, six.string_types):
56 57
             if not view:
57 58
                 raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex)
58 59
             if prefix:
15  django/contrib/admin/helpers.py
@@ -10,8 +10,9 @@
10 10
 from django.forms.util import flatatt
11 11
 from django.template.defaultfilters import capfirst
12 12
 from django.utils.encoding import force_unicode, smart_unicode
13  
-from django.utils.html import escape, conditional_escape
  13
+from django.utils.html import conditional_escape, format_html
14 14
 from django.utils.safestring import mark_safe
  15
+from django.utils import six
15 16
 from django.utils.translation import ugettext_lazy as _
16 17
 from django.conf import settings
17 18
 
@@ -49,7 +50,7 @@ def first_field(self):
49 50
         try:
50 51
             fieldset_name, fieldset_options = self.fieldsets[0]
51 52
             field_name = fieldset_options['fields'][0]
52  
-            if not isinstance(field_name, basestring):
  53
+            if not isinstance(field_name, six.string_types):
53 54
                 field_name = field_name[0]
54 55
             return self.form[field_name]
55 56
         except (KeyError, IndexError):
@@ -163,11 +164,9 @@ def label_tag(self):
163 164
         if not self.is_first:
164 165
             attrs["class"] = "inline"
165 166
         label = self.field['label']
166  
-        contents = capfirst(force_unicode(escape(label))) + ":"
167  
-        return mark_safe('<label%(attrs)s>%(contents)s</label>' % {
168  
-            "attrs": flatatt(attrs),
169  
-            "contents": contents,
170  
-        })
  167
+        return format_html('<label{0}>{1}:</label>',
  168
+                           flatatt(attrs),
  169
+                           capfirst(force_unicode(label)))
171 170
 
172 171
     def contents(self):
173 172
         from django.contrib.admin.templatetags.admin_list import _boolean_icon
@@ -190,7 +189,7 @@ def contents(self):
190 189
                 if value is None:
191 190
                     result_repr = EMPTY_CHANGELIST_VALUE
192 191
                 elif isinstance(f.rel, ManyToManyRel):
193  
-                    result_repr = ", ".join(map(unicode, value.all()))
  192
+                    result_repr = ", ".join(map(six.text_type, value.all()))
194 193
                 else:
195 194
                     result_repr = display_for_field(value, f)
196 195
         return conditional_escape(result_repr)
3  django/contrib/admin/models.py
@@ -6,7 +6,6 @@
6 6
 from django.contrib.admin.util import quote
7 7
 from django.utils.translation import ugettext_lazy as _
8 8
 from django.utils.encoding import smart_unicode
9  
-from django.utils.safestring import mark_safe
10 9
 
11 10
 ADDITION = 1
12 11
 CHANGE = 2
@@ -66,5 +65,5 @@ def get_admin_url(self):
66 65
         This is relative to the Django admin index page.
67 66
         """
68 67
         if self.content_type and self.object_id:
69  
-            return mark_safe("%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, quote(self.object_id)))
  68
+            return "%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, quote(self.object_id))
70 69
         return None
9  django/contrib/admin/options.py
@@ -24,6 +24,7 @@
24 24
 from django.utils.datastructures import SortedDict
25 25
 from django.utils.html import escape, escapejs
26 26
 from django.utils.safestring import mark_safe
  27
+from django.utils import six
27 28
 from django.utils.text import capfirst, get_text_list
28 29
 from django.utils.translation import ugettext as _
29 30
 from django.utils.translation import ungettext
@@ -57,9 +58,8 @@ class IncorrectLookupParameters(Exception):
57 58
 
58 59
 csrf_protect_m = method_decorator(csrf_protect)
59 60
 
60  
-class BaseModelAdmin(object):
  61
+class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
61 62
     """Functionality common to both ModelAdmin and InlineAdmin."""
62  
-    __metaclass__ = forms.MediaDefiningClass
63 63
 
64 64
     raw_id_fields = ()
65 65
     fields = None
@@ -745,7 +745,7 @@ def render_change_form(self, request, context, add=False, change=False, form_url
745 745
             'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
746 746
             'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
747 747
             'ordered_objects': ordered_objects,
748  
-            'form_url': mark_safe(form_url),
  748
+            'form_url': form_url,
749 749
             'opts': opts,
750 750
             'content_type_id': ContentType.objects.get_for_model(self.model).id,
751 751
             'save_as': self.save_as,
@@ -998,7 +998,6 @@ def add_view(self, request, form_url='', extra_context=None):
998 998
             'title': _('Add %s') % force_unicode(opts.verbose_name),
999 999
             'adminform': adminForm,
1000 1000
             'is_popup': "_popup" in request.REQUEST,
1001  
-            'show_delete': False,
1002 1001
             'media': media,
1003 1002
             'inline_admin_formsets': inline_admin_formsets,
1004 1003
             'errors': helpers.AdminErrorList(form, formsets),
@@ -1321,7 +1320,7 @@ def history_view(self, request, object_id, extra_context=None):
1321 1320
         opts = model._meta
1322 1321
         app_label = opts.app_label
1323 1322
         action_list = LogEntry.objects.filter(
1324  
-            object_id = object_id,
  1323
+            object_id = unquote(object_id),
1325 1324
             content_type__id__exact = ContentType.objects.get_for_model(model).id
1326 1325
         ).select_related().order_by('action_time')
1327 1326
         # If no history was found, see whether this object even exists.
3  django/contrib/admin/sites.py
@@ -231,7 +231,8 @@ def wrapper(*args, **kwargs):
231 231
                 wrap(self.i18n_javascript, cacheable=True),
232 232
                 name='jsi18n'),
233 233
             url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$',
234  
-                wrap(contenttype_views.shortcut)),
  234
+                wrap(contenttype_views.shortcut),
  235
+                name='view_on_site'),
235 236
             url(r'^(?P<app_label>\w+)/$',
236 237
                 wrap(self.app_index),
237 238
                 name='app_list')
3  django/contrib/admin/static/admin/css/widgets.css
@@ -41,7 +41,8 @@
41 41
     text-align: left;
42 42
 }
43 43
 
44  
-.selector .selector-filter label {
  44
+.selector .selector-filter label,
  45
+.inline-group .aligned .selector .selector-filter label {
45 46
     width: 16px;
46 47
     padding: 2px;
47 48
 }
3  django/contrib/admin/templates/admin/auth/user/change_password.html
@@ -3,8 +3,7 @@
3 3
 {% load admin_urls %}
4 4
 
5 5
 {% block extrahead %}{{ block.super }}
6  
-{% url 'admin:jsi18n' as jsi18nurl %}
7  
-<script type="text/javascript" src="{{ jsi18nurl|default:"../../../../jsi18n/" }}"></script>
  6
+<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
8 7
 {% endblock %}
9 8
 {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
10 9
 {% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
5  django/contrib/admin/templates/admin/change_form.html
@@ -3,8 +3,7 @@
3 3
 {% load admin_urls %}
4 4
 
5 5
 {% block extrahead %}{{ block.super }}
6  
-{% url 'admin:jsi18n' as jsi18nurl %}
7  
-<script type="text/javascript" src="{{ jsi18nurl|default:"../../../jsi18n/" }}"></script>
  6
+<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
8 7
 {{ media }}
9 8
 {% endblock %}
10 9
 
@@ -31,7 +30,7 @@
31 30
   <ul class="object-tools">
32 31
     {% block object-tools-items %}
33 32
     <li><a href="history/" class="historylink">{% trans "History" %}</a></li>
34  
-    {% if has_absolute_url %}<li><a href="../../../r/{{ content_type_id }}/{{ original.pk }}/" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
  33
+    {% if has_absolute_url %}<li><a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
35 34
     {% endblock %}
36 35
   </ul>
37 36
 {% endif %}{% endif %}
3  django/contrib/admin/templates/admin/change_list.html
@@ -9,8 +9,7 @@
9 9
     <link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
10 10
   {% endif %}
11 11
   {% if cl.formset or action_form %}
12  
-    {% url 'admin:jsi18n' as jsi18nurl %}
13  
-    <script type="text/javascript" src="{{ jsi18nurl|default:'../../jsi18n/' }}"></script>
  12
+    <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
14 13
   {% endif %}
15 14
   {{ media.css }}
16 15
   {% if not actions_on_top and not actions_on_bottom %}
2  django/contrib/admin/templates/admin/delete_confirmation.html
@@ -7,7 +7,7 @@
7 7
 <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
8 8
 &rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ app_label|capfirst }}</a>
9 9
 &rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
10  
-&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}{{ object.pk }}">{{ object|truncatewords:"18" }}</a>
  10
+&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
11 11
 &rsaquo; {% trans 'Delete' %}
12 12
 </div>
13 13
 {% endblock %}
2  django/contrib/admin/templates/admin/edit_inline/stacked.html
@@ -6,7 +6,7 @@
6 6
 
7 7
 {% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if forloop.last %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
8 8
   <h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b>&nbsp;<span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span>
9  
-    {% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.pk }}/">{% trans "View on site" %}</a>{% endif %}
  9
+    {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
10 10
     {% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
11 11
   </h3>
12 12
   {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
2  django/contrib/admin/templates/admin/edit_inline/tabular.html
@@ -27,7 +27,7 @@
27 27
         <td class="original">
28 28
           {% if inline_admin_form.original or inline_admin_form.show_url %}<p>
29 29
           {% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
30  
-          {% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.pk }}/">{% trans "View on site" %}</a>{% endif %}
  30
+          {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
31 31
             </p>{% endif %}
32 32
           {% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
33 33
           {{ inline_admin_form.fk_field.field }}
2  django/contrib/admin/templates/admin/object_history.html
@@ -7,7 +7,7 @@
7 7
 <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
8 8
 &rsaquo; <a href="{% url 'admin:app_list' app_label=app_label %}">{{ app_label|capfirst|escape }}</a>
9 9
 &rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ module_name }}</a>
10  
-&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk %}">{{ object|truncatewords:"18" }}</a>
  10
+&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
11 11
 &rsaquo; {% trans 'History' %}
12 12
 </div>
13 13
 {% endblock %}
42  django/contrib/admin/templatetags/admin_list.py
@@ -10,7 +10,7 @@
10 10
 from django.core.exceptions import ObjectDoesNotExist
11 11
 from django.db import models
12 12
 from django.utils import formats
13  
-from django.utils.html import escape, conditional_escape
  13
+from django.utils.html import format_html
14 14
 from django.utils.safestring import mark_safe
15 15
 from django.utils.text import capfirst
16 16
 from django.utils.translation import ugettext as _
@@ -31,9 +31,12 @@ def paginator_number(cl,i):
31 31
     if i == DOT:
32 32
         return '... '
33 33
     elif i == cl.page_num:
34  
-        return mark_safe('<span class="this-page">%d</span> ' % (i+1))
  34
+        return format_html('<span class="this-page">{0}</span> ', i+1)
35 35
     else:
36  
-        return mark_safe('<a href="%s"%s>%d</a> ' % (escape(cl.get_query_string({PAGE_VAR: i})), (i == cl.paginator.num_pages-1 and ' class="end"' or ''), i+1))
  36
+        return format_html('<a href="{0}"{1}>{2}</a> ',
  37
+                           cl.get_query_string({PAGE_VAR: i}),
  38
+                           mark_safe(' class="end"' if i == cl.paginator.num_pages-1 else ''),
  39
+                           i+1)
37 40
 
38 41
 @register.inclusion_tag('admin/pagination.html')
39 42
 def pagination(cl):
@@ -159,13 +162,14 @@ def result_headers(cl):
159 162
             "url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),
160 163
             "url_remove": cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}),
161 164
             "url_toggle": cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}),
162  
-            "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '')
  165
+            "class_attrib": format_html(' class="{0}"', ' '.join(th_classes))
  166
+                            if th_classes else '',
163 167
         }
164 168
 
165 169
 def _boolean_icon(field_val):
166 170
     icon_url = static('admin/img/icon-%s.gif' %
167 171
                       {True: 'yes', False: 'no', None: 'unknown'}[field_val])
168  
-    return mark_safe('<img src="%s" alt="%s" />' % (icon_url, field_val))
  172
+    return format_html('<img src="{0}" alt="{1}" />', icon_url, field_val)
169 173
 
170 174
 def items_for_result(cl, result, form):
171 175
     """
@@ -182,7 +186,7 @@ def items_for_result(cl, result, form):
182 186
         else:
183 187
             if f is None:
184 188
                 if field_name == 'action_checkbox':
185  
-                    row_class = ' class="action-checkbox"'
  189
+                    row_class = mark_safe(' class="action-checkbox"')
186 190
                 allow_tags = getattr(attr, 'allow_tags', False)
187 191
                 boolean = getattr(attr, 'boolean', False)
188 192
                 if boolean:
@@ -190,23 +194,21 @@ def items_for_result(cl, result, form):
190 194
                 result_repr = display_for_value(value, boolean)
191 195
                 # Strip HTML tags in the resulting text, except if the
192 196
                 # function has an "allow_tags" attribute set to True.
193  
-                if not allow_tags:
194  
-                    result_repr = escape(result_repr)
195  
-                else:
  197
+                if allow_tags:
196 198
                     result_repr = mark_safe(result_repr)
197 199
                 if isinstance(value, (datetime.date, datetime.time)):
198  
-                    row_class = ' class="nowrap"'
  200
+                    row_class = mark_safe(' class="nowrap"')
199 201
             else:
200 202
                 if isinstance(f.rel, models.ManyToOneRel):
201 203
                     field_val = getattr(result, f.name)
202 204
                     if field_val is None:
203 205
                         result_repr = EMPTY_CHANGELIST_VALUE
204 206
                     else:
205  
-                        result_repr = escape(field_val)
  207
+                        result_repr = field_val
206 208
                 else:
207 209
                     result_repr = display_for_field(value, f)
208 210
                 if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
209  
-                    row_class = ' class="nowrap"'
  211
+                    row_class = mark_safe(' class="nowrap"')
210 212
         if force_unicode(result_repr) == '':
211 213
             result_repr = mark_safe('&nbsp;')
212 214
         # If list_display_links not defined, add the link tag to the first field
@@ -222,8 +224,14 @@ def items_for_result(cl, result, form):
222 224
                 attr = pk
223 225
             value = result.serializable_value(attr)
224 226
             result_id = repr(force_unicode(value))[1:]
225  
-            yield mark_safe('<%s%s><a href="%s"%s>%s</a></%s>' % \
226  
-                (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
  227
+            yield format_html('<{0}{1}><a href="{2}"{3}>{4}</a></{5}>',
  228
+                              table_tag,
  229
+                              row_class,
  230
+                              url,
  231
+                              format_html(' onclick="opener.dismissRelatedLookupPopup(window, {0}); return false;"', result_id)
  232
+                                if cl.is_popup else '',
  233
+                              result_repr,
  234
+                              table_tag)
227 235
         else:
228 236
             # By default the fields come from ModelAdmin.list_editable, but if we pull
229 237
             # the fields out of the form instead of list_editable custom admins
@@ -233,11 +241,9 @@ def items_for_result(cl, result, form):
233 241
                         form[cl.model._meta.pk.name].is_hidden)):
234 242
                 bf = form[field_name]
235 243
                 result_repr = mark_safe(force_unicode(bf.errors) + force_unicode(bf))
236  
-            else:
237  
-                result_repr = conditional_escape(result_repr)
238  
-            yield mark_safe('<td%s>%s</td>' % (row_class, result_repr))
  244
+            yield format_html('<td{0}>{1}</td>', row_class, result_repr)
239 245
     if form and not form[cl.model._meta.pk.name].is_hidden:
240  
-        yield mark_safe('<td>%s</td>' % force_unicode(form[cl.model._meta.pk.name]))
  246
+        yield format_html('<td>{0}</td>', force_unicode(form[cl.model._meta.pk.name]))
241 247
 
242 248
 class ResultList(list):
243 249
     # Wrapper class used to return items in a list_editable
2  django/contrib/admin/templatetags/admin_modify.py
@@ -32,7 +32,7 @@ def submit_row(context):
32 32
         'onclick_attrib': (opts.get_ordered_objects() and change
33 33
                             and 'onclick="submitOrderForm();"' or ''),
34 34
         'show_delete_link': (not is_popup and context['has_delete_permission']
35  
-                              and (change or context['show_delete'])),
  35
+                              and change and context.get('show_delete', True)),
36 36
         'show_save_as_new': not is_popup and change and save_as,
37 37
         'show_save_and_add_another': context['has_add_permission'] and
38 38
                             not is_popup and (not save_as or context['add']),
8  django/contrib/admin/templatetags/admin_urls.py
... ...
@@ -1,8 +1,14 @@
1  
-from django.core.urlresolvers import reverse, NoReverseMatch
  1
+from django.core.urlresolvers import reverse
2 2
 from django import template
  3
+from django.contrib.admin.util import quote
3 4
 
4 5
 register = template.Library()
5 6
 
6 7
 @register.filter
7 8
 def admin_urlname(value, arg):
8 9
     return 'admin:%s_%s_%s' % (value.app_label, value.module_name, arg)
  10
+
  11
+
  12
+@register.filter
  13
+def admin_urlquote(value):
  14
+    return quote(value)
20  django/contrib/admin/util.py
@@ -9,11 +9,11 @@
9 9
 from django.db.models.related import RelatedObject
10 10
 from django.forms.forms import pretty_name
11 11
 from django.utils import formats
12  
-from django.utils.html import escape
13  
-from django.utils.safestring import mark_safe
  12
+from django.utils.html import format_html
14 13
 from django.utils.text import capfirst
15 14
 from django.utils import timezone
16 15
 from django.utils.encoding import force_unicode, smart_unicode, smart_str
  16
+from django.utils import six
17 17
 from django.utils.translation import ungettext
18 18
 from django.core.urlresolvers import reverse
19 19
 
@@ -52,7 +52,7 @@ def quote(s):
52 52
     quoting is slightly different so that it doesn't get automatically
53 53
     unquoted by the Web browser.
54 54
     """
55  
-    if not isinstance(s, basestring):
  55
+    if not isinstance(s, six.string_types):
56 56
         return s
57 57
     res = list(s)
58 58
     for i in range(len(res)):
@@ -124,10 +124,10 @@ def format_callback(obj):
124 124
             if not user.has_perm(p):
125 125
                 perms_needed.add(opts.verbose_name)
126 126
             # Display a link to the admin page.
127  
-            return mark_safe('%s: <a href="%s">%s</a>' %
128  
-                             (escape(capfirst(opts.verbose_name)),
129  
-                              admin_url,
130  
-                              escape(obj)))
  127
+            return format_html('{0}: <a href="{1}">{2}</a>',
  128
+                               capfirst(opts.verbose_name),
  129
+                               admin_url,
  130
+                               obj)
131 131
         else:
132 132
             # Don't display link to edit, because it either has no
133 133
             # admin or is edited inline.
@@ -275,10 +275,10 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
275 275
     except models.FieldDoesNotExist:
276 276
         if name == "__unicode__":
277 277
             label = force_unicode(model._meta.verbose_name)
278  
-            attr = unicode
  278
+            attr = six.text_type
279 279
         elif name == "__str__":
280 280
             label = smart_str(model._meta.verbose_name)
281  
-            attr = str
  281
+            attr = bytes
282 282
         else:
283 283
             if callable(name):
284 284
                 attr = name
@@ -350,7 +350,7 @@ def display_for_value(value, boolean=False):
350 350
         return formats.localize(timezone.template_localtime(value))
351 351
     elif isinstance(value, (datetime.date, datetime.time)):
352 352
         return formats.localize(value)
353  
-    elif isinstance(value, (decimal.Decimal, float, int, long)):
  353
+    elif isinstance(value, six.integer_types + (decimal.Decimal, float)):
354 354
         return formats.number_format(value)
355 355
     else:
356 356
         return smart_unicode(value)
18  django/contrib/admin/widgets.py
@@ -10,11 +10,12 @@
10 10
 from django.core.urlresolvers import reverse
11 11
 from django.forms.widgets import RadioFieldRenderer
12 12
 from django.forms.util import flatatt
13  
-from django.utils.html import escape
  13
+from django.utils.html import escape, format_html, format_html_join
14 14
 from django.utils.text import Truncator
15 15
 from django.utils.translation import ugettext as _
16 16
 from django.utils.safestring import mark_safe
17 17
 from django.utils.encoding import force_unicode
  18
+from django.utils import six
18 19
 
19 20
 
20 21
 class FilteredSelectMultiple(forms.SelectMultiple):
@@ -85,16 +86,17 @@ def __init__(self, attrs=None):
85 86
         forms.MultiWidget.__init__(self, widgets, attrs)
86 87
 
87 88
     def format_output(self, rendered_widgets):
88  
-        return mark_safe('<p class="datetime">%s %s<br />%s %s</p>' % \
89  
-            (_('Date:'), rendered_widgets[0], _('Time:'), rendered_widgets[1]))
  89
+        return format_html('<p class="datetime">{0} {1}<br />{2} {3}</p>',
  90
+                           _('Date:'), rendered_widgets[0],
  91
+                           _('Time:'), rendered_widgets[1])
90 92
 
91 93
 class AdminRadioFieldRenderer(RadioFieldRenderer):
92 94
     def render(self):
93 95
         """Outputs a <ul> for this set of radio fields."""
94  
-        return mark_safe('<ul%s>\n%s\n</ul>' % (
95  
-            flatatt(self.attrs),
96  
-            '\n'.join(['<li>%s</li>' % force_unicode(w) for w in self]))
97  
-        )
  96
+        return format_html('<ul{0}>\n{1}\n</ul>',
  97
+                           flatatt(self.attrs),
  98
+                           format_html_join('\n', '<li>{0}</li>',
  99
+                                            ((force_unicode(w),) for w in self)))
98 100
 
99 101
 class AdminRadioSelect(forms.RadioSelect):
100 102
     renderer = AdminRadioFieldRenderer
@@ -120,7 +122,7 @@ def url_params_from_lookup_dict(lookups):
120 122
                 # See django.db.fields.BooleanField.get_prep_lookup
121 123
                 v = ('0', '1')[v]
122 124
             else:
123  
-                v = unicode(v)
  125
+                v = six.text_type(v)
124 126
             items.append((k, v))
125 127
         params.update(dict(items))
126 128
     return params
2  django/contrib/admindocs/templates/admin_doc/bookmarklets.html
@@ -22,7 +22,7 @@
22 22
 {% endblocktrans %}
23 23
 
24 24
 <div id="content-main">
25  
-    <h3><a href="javascript:(function(){if(typeof ActiveXObject!='undefined'){x=new ActiveXObject('Microsoft.XMLHTTP')}else if(typeof XMLHttpRequest!='undefined'){x=new XMLHttpRequest()}else{return;}x.open('HEAD',location.href,false);x.send(null);try{view=x.getResponseHeader('x-view');}catch(e){alert('No view found for this page');return;}if(view=='undefined'){alert('No view found for this page');}document.location='{{ admin_url }}doc/views/'+view+'/';})()">{% trans "Documentation for this page" %}</a></h3>
  25
+    <h3><a href="javascript:(function(){if(typeof ActiveXObject!='undefined'){x=new ActiveXObject('Microsoft.XMLHTTP')}else if(typeof XMLHttpRequest!='undefined'){x=new XMLHttpRequest()}else{return;}x.open('HEAD',location.href,false);x.send(null);try{view=x.getResponseHeader('x-view');}catch(e){alert('No view found for this page');return;}if(view=='undefined'){alert('No view found for this page');}document.location='{{ admin_url|escapejs }}doc/views/'+view+'/';})()">{% trans "Documentation for this page" %}</a></h3>
26 26
     <p>{% trans "Jumps you from any page to the documentation for the view that generates that page." %}</p>
27 27
 
28 28
     <h3><a href="javascript:(function(){if(typeof ActiveXObject!='undefined'){x=new ActiveXObject('Microsoft.XMLHTTP')}else if(typeof XMLHttpRequest!='undefined'){x=new XMLHttpRequest()}else{return;}x.open('GET',location.href,false);x.send(null);try{type=x.getResponseHeader('x-object-type');id=x.getResponseHeader('x-object-id');}catch(e){type='(none)';id='(none)';}d=document;b=d.body;e=d.createElement('div');e.id='xxxhhh';s=e.style;s.position='absolute';s.left='10px';s.top='10px';s.font='10px monospace';s.border='1px black solid';s.padding='4px';s.backgroundColor='#eee';e.appendChild(d.createTextNode('Type: '+type));e.appendChild(d.createElement('br'));e.appendChild(d.createTextNode('ID: '+id));e.appendChild(d.createElement('br'));l=d.createElement('a');l.href='#';l.onclick=function(){b.removeChild(e);};l.appendChild(d.createTextNode('[close]'));l.style.textDecoration='none';e.appendChild(l);b.appendChild(e);})();">{% trans "Show object ID" %}</a></h3>
2  django/contrib/admindocs/views.py
@@ -37,7 +37,7 @@ def bookmarklets(request):
37 37
     admin_root = urlresolvers.reverse('admin:index')
38 38
     return render_to_response('admin_doc/bookmarklets.html', {
39 39
         'root_path': admin_root,
40  
-        'admin_url': mark_safe("%s://%s%s" % (request.is_secure() and 'https' or 'http', request.get_host(), admin_root)),
  40
+        'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', request.get_host(), admin_root),
41 41
     }, context_instance=RequestContext(request))
42 42
 
43 43
 @staff_member_required
2  django/contrib/auth/admin.py
@@ -134,7 +134,7 @@ def user_change_password(self, request, id, form_url=''):
134 134
         context = {
135 135
             'title': _('Change password: %s') % escape(user.username),
136 136
             'adminForm': adminForm,
137  
-            'form_url': mark_safe(form_url),
  137
+            'form_url': form_url,
138 138
             'form': form,
139 139
             'is_popup': '_popup' in request.REQUEST,
140 140
             'add': True,
10  django/contrib/auth/decorators.py
... ...
@@ -1,4 +1,7 @@
1  
-import urlparse
  1
+try:
  2
+    from urllib.parse import urlparse
  3
+except ImportError:     # Python 2
  4
+    from urlparse import urlparse
2 5
 from functools import wraps
3 6
 from django.conf import settings
4 7
 from django.contrib.auth import REDIRECT_FIELD_NAME
@@ -21,9 +24,8 @@ def _wrapped_view(request, *args, **kwargs):
21 24
             path = request.build_absolute_uri()
22 25
             # If the login url is the same scheme and net location then just
23 26
             # use the path as the "next" url.
24  
-            login_scheme, login_netloc = urlparse.urlparse(login_url or
25  
-                                                        settings.LOGIN_URL)[:2]
26  
-            current_scheme, current_netloc = urlparse.urlparse(path)[:2]
  27
+            login_scheme, login_netloc = urlparse(login_url or settings.LOGIN_URL)[:2]
  28
+            current_scheme, current_netloc = urlparse(path)[:2]
27 29
             if ((not login_scheme or login_scheme == current_scheme) and
28 30
                 (not login_netloc or login_netloc == current_netloc)):
29 31
                 path = request.get_full_path()
24  django/contrib/auth/forms.py
... ...
@@ -1,6 +1,10 @@
  1
+from __future__ import unicode_literals
  2
+
1 3
 from django import forms
2 4
 from django.forms.util import flatatt
3 5
 from django.template import loader
  6
+from django.utils.datastructures import SortedDict
  7
+from django.utils.html import format_html, format_html_join
4 8
 from django.utils.http import int_to_base36
5 9
 from django.utils.safestring import mark_safe
6 10
 from django.utils.translation import ugettext, ugettext_lazy as _
@@ -11,6 +15,7 @@
11 15
 from django.contrib.auth.tokens import default_token_generator
12 16
 from django.contrib.sites.models import get_current_site
13 17
 
  18
+
14 19
 UNMASKED_DIGITS_TO_SHOW = 6
15 20
 
16 21
 mask_password = lambda p: "%s%s" % (p[:UNMASKED_DIGITS_TO_SHOW], "*" * max(len(p) - UNMASKED_DIGITS_TO_SHOW, 0))
@@ -28,13 +33,15 @@ def render(self, name, value, attrs):
28 33
         try:
29 34
             hasher = identify_hasher(encoded)
30 35
         except ValueError:
31  
-            summary = "<strong>Invalid password format or unknown hashing algorithm.</strong>"
  36
+            summary = mark_safe("<strong>Invalid password format or unknown hashing algorithm.</strong>")
32 37
         else:
33  
-            summary = ""
34  
-            for key, value in hasher.safe_summary(encoded).iteritems():
35  
-                summary += "<strong>%(key)s</strong>: %(value)s " % {"key": ugettext(key), "value": value}
  38
+            summary = format_html_join('',
  39
+                                       "<strong>{0}</strong>: {1} ",
  40
+                                       ((ugettext(key), value)
  41
+                                        for key, value in hasher.safe_summary(encoded).items())
  42
+                                       )
36 43
 
37  
-        return mark_safe("<div%(attrs)s>%(summary)s</div>" % {"attrs": flatatt(final_attrs), "summary": summary})
  44
+        return format_html("<div{0}>{1}</div>", flatatt(final_attrs), summary)
38 45
 
39 46
 
40 47
 class ReadOnlyPasswordHashField(forms.Field):
@@ -288,8 +295,11 @@ def clean_old_password(self):
288 295
             raise forms.ValidationError(
289 296
                 self.error_messages['password_incorrect'])
290 297
         return old_password
291  
-PasswordChangeForm.base_fields.keyOrder = ['old_password', 'new_password1',
292  
-                                           'new_password2']
  298
+
  299
+PasswordChangeForm.base_fields = SortedDict([
  300
+    (k, PasswordChangeForm.base_fields[k])
  301
+    for k in ['old_password', 'new_password1', 'new_password2']
  302
+])
293 303
 
294 304
 
295 305
 class AdminPasswordChangeForm(forms.Form):
17  django/contrib/auth/models.py
... ...
@@ -1,13 +1,12 @@
1 1
 from __future__ import unicode_literals
2 2
 
3  
-import urllib
4  
-
5 3
 from django.core.exceptions import ImproperlyConfigured
6 4
 from django.core.mail import send_mail
7 5
 from django.db import models
8 6
 from django.db.models.manager import EmptyManager
9 7
 from django.utils.crypto import get_random_string
10  
-from django.utils.encoding import smart_str
  8
+from django.utils.http import urlquote
  9
+from django.utils import six
11 10
 from django.utils.translation import ugettext_lazy as _
12 11
 from django.utils import timezone
13 12
 
@@ -79,9 +78,9 @@ class Meta:
79 78
 
80 79
     def __unicode__(self):
81 80
         return "%s | %s | %s" % (
82  
-            unicode(self.content_type.app_label),
83  
-            unicode(self.content_type),
84  
-            unicode(self.name))
  81
+            six.text_type(self.content_type.app_label),
  82
+            six.text_type(self.content_type),
  83
+            six.text_type(self.name))
85 84
 
86 85
     def natural_key(self):
87 86
         return (self.codename,) + self.content_type.natural_key()
@@ -267,7 +266,7 @@ def natural_key(self):
267 266
         return (self.username,)
268 267
 
269 268
     def get_absolute_url(self):
270  
-        return "/users/%s/" % urllib.quote(smart_str(self.username))
  269
+        return "/users/%s/" % urlquote(self.username)
271 270
 
272 271
     def is_anonymous(self):
273 272
         """
@@ -300,7 +299,7 @@ def check_password(self, raw_password):
300 299
         """
301 300
         def setter(raw_password):
302 301
             self.set_password(raw_password)
303  
-            self.save()
  302
+            self.save(update_fields=["password"])
304 303
         return check_password(raw_password, self.password, setter)
305 304
 
306 305
     def set_unusable_password(self):
@@ -421,7 +420,7 @@ def __unicode__(self):
421 420
         return 'AnonymousUser'
422 421
 
423 422
     def __str__(self):
424  
-        return unicode(self).encode('utf-8')
  423
+        return six.text_type(self).encode('utf-8')
425 424
 
426 425
     def __eq__(self, other):
427 426
         return isinstance(other, self.__class__)
6  django/contrib/auth/tests/basic.py
... ...
@@ -1,8 +1,8 @@
1  
-from django.test import TestCase
2  
-from django.utils.unittest import skipUnless
3 1
 from django.contrib.auth.models import User, AnonymousUser
4 2
 from django.core.management import call_command
5  
-from StringIO import StringIO
  3
+from django.test import TestCase
  4
+from django.utils.six import StringIO
  5
+from django.utils.unittest import skipUnless
6 6
 
7 7
 try:
8 8
     import crypt as crypt_module
3  django/contrib/auth/tests/management.py
... ...
@@ -1,11 +1,10 @@
1 1
 from __future__ import unicode_literals
2 2
 
3  
-from StringIO import StringIO
4  
-
5 3
 from django.contrib.auth import models, management
6 4
 from django.contrib.auth.management.commands import changepassword
7 5
 from django.core.management.base import CommandError
8 6
 from django.test import TestCase
  7
+from django.utils.six import StringIO
9 8
 
10 9
 
11 10
 class GetDefaultUsernameTestCase(TestCase):
36  django/contrib/auth/tests/models.py
@@ -5,39 +5,29 @@
5 5
     SiteProfileNotAvailable, UserManager)
6 6
 
7 7
 
8  
-@override_settings(USE_TZ=False)
  8
+@override_settings(USE_TZ=False, AUTH_PROFILE_MODULE='')
9 9
 class ProfileTestCase(TestCase):
10  
-    fixtures = ['authtestdata.json']
11  
-
12  
-    def setUp(self):
13  
-        """Backs up the AUTH_PROFILE_MODULE"""
14  
-        self.old_AUTH_PROFILE_MODULE = getattr(settings,
15  
-                                               'AUTH_PROFILE_MODULE', None)
16  
-
17  
-    def tearDown(self):
18  
-        """Restores the AUTH_PROFILE_MODULE -- if it was not set it is deleted,
19  
-        otherwise the old value is restored"""
20  
-        if self.old_AUTH_PROFILE_MODULE is None and \
21  
-                hasattr(settings, 'AUTH_PROFILE_MODULE'):
22  
-            del settings.AUTH_PROFILE_MODULE
23  
-
24  
-        if self.old_AUTH_PROFILE_MODULE is not None:
25  
-            settings.AUTH_PROFILE_MODULE = self.old_AUTH_PROFILE_MODULE
26 10
 
27 11
     def test_site_profile_not_available(self):
  12
+        user = User.objects.create(username='testclient')
  13
+
28 14
         # calling get_profile without AUTH_PROFILE_MODULE set
29  
-        if hasattr(settings, 'AUTH_PROFILE_MODULE'):
30  
-            del settings.AUTH_PROFILE_MODULE
31  
-        user = User.objects.get(username='testclient')
32  
-        self.assertRaises(SiteProfileNotAvailable, user.get_profile)
  15
+        del settings.AUTH_PROFILE_MODULE
  16
+        with self.assertRaisesRegexp(SiteProfileNotAvailable,
  17
+                "You need to set AUTH_PROFILE_MODULE in your project"):
  18
+            user.get_profile()
33 19
 
34 20
         # Bad syntax in AUTH_PROFILE_MODULE:
35 21
         settings.AUTH_PROFILE_MODULE = 'foobar'
36  
-        self.assertRaises(SiteProfileNotAvailable, user.get_profile)
  22
+        with self.assertRaisesRegexp(SiteProfileNotAvailable,
  23
+                "app_label and model_name should be separated by a dot"):
  24
+            user.get_profile()
37 25
 
38 26
         # module that doesn't exist
39 27
         settings.AUTH_PROFILE_MODULE = 'foo.bar'
40  
-        self.assertRaises(SiteProfileNotAvailable, user.get_profile)
  28
+        with self.assertRaisesRegexp(SiteProfileNotAvailable,
  29
+                "Unable to load the profile model"):
  30
+            user.get_profile()
41 31
 
42 32
 
43 33
 @override_settings(USE_TZ=False)
10  django/contrib/auth/tests/views.py
... ...
@@ -1,6 +1,5 @@
1 1
 import os
2 2
 import re
3  
-import urllib
4 3
 
5 4
 from django.conf import settings
6 5
 from django.contrib.sites.models import Site, RequestSite
@@ -10,6 +9,7 @@
10 9
 from django.http import QueryDict
11 10
 from django.utils.encoding import force_unicode
12 11
 from django.utils.html import escape
  12
+from django.utils.http import urlquote
13 13
 from django.test import TestCase
14 14
 from django.test.utils import override_settings
15 15
 
@@ -256,7 +256,7 @@ def test_security_check(self, password='password'):
256 256
             nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
257 257
                 'url': login_url,
258 258
                 'next': REDIRECT_FIELD_NAME,
259  
-                'bad_url': urllib.quote(bad_url),
  259
+                'bad_url': urlquote(bad_url),
260 260
             }
261 261
             response = self.client.post(nasty_url, {
262 262
                 'username': 'testclient',
@@ -277,7 +277,7 @@ def test_security_check(self, password='password'):
277 277
             safe_url = '%(url)s?%(next)s=%(good_url)s' % {
278 278
                 'url': login_url,
279 279
                 'next': REDIRECT_FIELD_NAME,
280  
-                'good_url': urllib.quote(good_url),
  280
+                'good_url': urlquote(good_url),
281 281
             }
282 282
             response = self.client.post(safe_url, {
283 283
                     'username': 'testclient',
@@ -412,7 +412,7 @@ def test_security_check(self, password='password'):
412 412
             nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
413 413
                 'url': logout_url,
414 414
                 'next': REDIRECT_FIELD_NAME,
415  
-                'bad_url': urllib.quote(bad_url),
  415
+                'bad_url': urlquote(bad_url),
416 416
             }
417 417
             self.login()
418 418
             response = self.client.get(nasty_url)
@@ -432,7 +432,7 @@ def test_security_check(self, password='password'):
432 432
             safe_url = '%(url)s?%(next)s=%(good_url)s' % {
433 433
                 'url': logout_url,
434 434
                 'next': REDIRECT_FIELD_NAME,
435  
-                'good_url': urllib.quote(good_url),
  435
+                'good_url': urlquote(good_url),
436 436
             }
437 437
             self.login()
438 438
             response = self.client.get(safe_url)
5  django/contrib/auth/tokens.py
@@ -2,6 +2,7 @@
2 2
 from django.conf import settings
3 3
 from django.utils.http import int_to_base36, base36_to_int
4 4
 from django.utils.crypto import constant_time_compare, salted_hmac
  5
+from django.utils import six
5 6
 
6 7
 class PasswordResetTokenGenerator(object):
7 8
     """
@@ -56,8 +57,8 @@ def _make_token_with_timestamp(self, user, timestamp):
56 57
         # Ensure results are consistent across DB backends
57 58
         login_timestamp = user.last_login.replace(microsecond=0, tzinfo=None)
58 59
 
59  
-        value = (unicode(user.id) + user.password +
60  
-                unicode(login_timestamp) + unicode(timestamp))
  60
+        value = (six.text_type(user.id) + user.password +
  61
+                six.text_type(login_timestamp) + six.text_type(timestamp))
61 62
         hash = salted_hmac(key_salt, value).hexdigest()[::2]
62 63
         return "%s-%s" % (ts_b36, hash)
63 64
 
13  django/contrib/auth/views.py
... ...
@@ -1,4 +1,7 @@
1  
-import urlparse
  1
+try:
  2
+    from urllib.parse import urlparse, urlunparse
  3
+except ImportError:     # Python 2
  4
+    from urlparse import urlparse, urlunparse
2 5
 
3 6
 from django.conf import settings
4 7
 from django.core.urlresolvers import reverse
@@ -34,7 +37,7 @@ def login(request, template_name='registration/login.html',
34 37
     if request.method == "POST":
35 38
         form = authentication_form(data=request.POST)
36 39
         if form.is_valid():
37  
-            netloc = urlparse.urlparse(redirect_to)[1]
  40
+            netloc = urlparse(redirect_to)[1]
38 41
 
39 42
             # Use default setting if redirect_to is empty
40 43
             if not redirect_to:
@@ -80,7 +83,7 @@ def logout(request, next_page=None,
80 83
     auth_logout(request)
81 84
     redirect_to = request.REQUEST.get(redirect_field_name, '')
82 85
     if redirect_to:
83  
-        netloc = urlparse.urlparse(redirect_to)[1]
  86
+        netloc = urlparse(redirect_to)[1]
84 87
         # Security check -- don't allow redirection to a different host.
85 88
         if not (netloc and netloc != request.get_host()):
86 89
             return HttpResponseRedirect(redirect_to)
@@ -116,13 +119,13 @@ def redirect_to_login(next, login_url=None,
116 119
     if not login_url:
117 120
         login_url = settings.LOGIN_URL
118 121
 
119  
-    login_url_parts = list(urlparse.urlparse(login_url))
  122
+    login_url_parts = list(urlparse(login_url))
120 123
     if redirect_field_name:
121 124
         querystring = QueryDict(login_url_parts[4], mutable=True)
122 125
         querystring[redirect_field_name] = next
123 126
         login_url_parts[4] = querystring.urlencode(safe='/')
124 127
 
125  
-    return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))
  128
+    return HttpResponseRedirect(urlunparse(login_url_parts))
126 129
 
127 130
 # 4 views for password reset:
128 131
 # - password_reset sends the mail
6  django/contrib/comments/views/moderation.py
@@ -17,7 +17,7 @@ def flag(request, comment_id, next=None):
17 17
     """
18 18
     Flags a comment. Confirmation on GET, action on POST.
19 19
 
20  
-    Templates: `comments/flag.html`,
  20
+    Templates: :template:`comments/flag.html`,
21 21
     Context:
22 22
         comment
23 23
             the flagged `comments.comment` object
@@ -43,7 +43,7 @@ def delete(request, comment_id, next=None):
43 43
     Deletes a comment. Confirmation on GET, action on POST. Requires the "can
44 44
     moderate comments" permission.
45 45
 
46  
-    Templates: `comments/delete.html`,
  46
+    Templates: :template:`comments/delete.html`,
47 47
     Context:
48 48
         comment
49 49
             the flagged `comments.comment` object
@@ -70,7 +70,7 @@ def approve(request, comment_id, next=None):
70 70
     Approve a comment (that is, mark it as public and non-removed). Confirmation
71 71
     on GET, action on POST. Requires the "can moderate comments" permission.
72 72
 
73  
-    Templates: `comments/approve.html`,
  73
+    Templates: :template:`comments/approve.html`,
74 74
     Context:
75 75
         comment
76 76
             the `comments.comment` object for approval
10  django/contrib/comments/views/utils.py