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 https://github.com/django/django

  • Loading branch information...
commit eee791e9b216333ad0b4c6c441a88828bf9aee62 2 parents fbb7389 + 840ffd8
bohyn authored June 05, 2012

Showing 190 changed files with 3,275 additions and 2,324 deletions. Show diff stats Hide diff stats

  1. 5  AUTHORS
  2. 22  django/contrib/admin/static/admin/js/actions.js
  3. 13  django/contrib/admin/static/admin/js/actions.min.js
  4. 26  django/contrib/admin/static/admin/js/inlines.js
  5. 10  django/contrib/admin/static/admin/js/inlines.min.js
  6. 8  django/contrib/admin/templates/admin/index.html
  7. 1  django/contrib/admin/views/main.py
  8. 14  django/contrib/auth/management/commands/createsuperuser.py
  9. 13  django/contrib/auth/tests/management.py
  10. 11  django/contrib/flatpages/fixtures/example_site.json
  11. 3  django/contrib/flatpages/tests/csrf.py
  12. 5  django/contrib/flatpages/tests/forms.py
  13. 12  django/contrib/flatpages/tests/middleware.py
  14. 1  django/contrib/flatpages/tests/templatetags.py
  15. 8  django/contrib/flatpages/tests/views.py
  16. 57  django/contrib/formtools/tests/__init__.py
  17. 14  django/contrib/formtools/tests/wizard/namedwizardtests/tests.py
  18. 12  django/contrib/formtools/tests/wizard/wizardtests/tests.py
  19. 6  django/contrib/formtools/utils.py
  20. 8  django/contrib/gis/admin/options.py
  21. 4  django/contrib/gis/gdal/base.py
  22. 4  django/contrib/gis/gdal/tests/__init__.py
  23. 4  django/contrib/gis/geoip/__init__.py
  24. 4  django/contrib/gis/geos/base.py
  25. 29  django/contrib/gis/geos/mutable_list.py
  26. 4  django/contrib/gis/geos/tests/__init__.py
  27. 125  django/contrib/gis/geos/tests/test_geos.py
  28. 12  django/contrib/gis/maps/google/overlays.py
  29. 24  django/contrib/gis/measure.py
  30. 2  django/contrib/gis/templates/gis/admin/openlayers.js
  31. 19  django/contrib/gis/tests/geoadmin/tests.py
  32. 1  django/contrib/gis/tests/layermap/models.py
  33. 65  django/contrib/gis/tests/layermap/tests.py
  34. 2  django/contrib/gis/utils/layermapping.py
  35. 2  django/contrib/humanize/tests.py
  36. 2  django/contrib/localflavor/es/es_provinces.py
  37. 3  django/contrib/messages/tests/base.py
  38. 10  django/contrib/sitemaps/tests/base.py
  39. 13  django/contrib/sitemaps/tests/http.py
  40. 7  django/contrib/staticfiles/management/commands/collectstatic.py
  41. 6  django/contrib/staticfiles/management/commands/findstatic.py
  42. 23  django/contrib/staticfiles/storage.py
  43. 2  django/core/context_processors.py
  44. 1  django/core/exceptions.py
  45. 5  django/core/files/base.py
  46. 4  django/core/files/uploadedfile.py
  47. 10  django/core/handlers/wsgi.py
  48. 78  django/core/management/base.py
  49. 2  django/core/management/commands/compilemessages.py
  50. 15  django/core/management/commands/createcachetable.py
  51. 28  django/core/management/commands/dumpdata.py
  52. 5  django/core/management/commands/inspectdb.py
  53. 36  django/core/management/commands/loaddata.py
  54. 4  django/core/management/commands/runserver.py
  55. 6  django/core/management/templates.py
  56. 3  django/core/serializers/base.py
  57. 29  django/core/serializers/json.py
  58. 13  django/core/serializers/python.py
  59. 26  django/core/servers/basehttp.py
  60. 6  django/core/urlresolvers.py
  61. 15  django/db/backends/__init__.py
  62. 13  django/db/backends/mysql/base.py
  63. 1  django/db/backends/oracle/base.py
  64. 18  django/db/backends/sqlite3/base.py
  65. 12  django/db/models/base.py
  66. 25  django/db/models/fields/__init__.py
  67. 21  django/db/models/fields/files.py
  68. 63  django/db/models/fields/related.py
  69. 21  django/db/models/query.py
  70. 49  django/db/models/query_utils.py
  71. 14  django/db/models/sql/compiler.py
  72. 3  django/db/models/sql/where.py
  73. 10  django/dispatch/saferef.py
  74. 6  django/forms/fields.py
  75. 4  django/forms/models.py
  76. 6  django/http/__init__.py
  77. 38  django/http/multipartparser.py
  78. 2  django/template/loaders/app_directories.py
  79. 2  django/template/loaders/filesystem.py
  80. 2  django/templatetags/i18n.py
  81. 70  django/test/client.py
  82. 4  django/utils/cache.py
  83. 9  django/utils/crypto.py
  84. 9  django/utils/encoding.py
  85. 23  django/utils/functional.py
  86. 2  django/utils/html.py
  87. 19  django/views/debug.py
  88. 12  django/views/decorators/debug.py
  89. 12  django/views/generic/base.py
  90. 245  django/views/generic/dates.py
  91. 5  django/views/generic/detail.py
  92. 23  django/views/generic/list.py
  93. 12  docs/howto/custom-management-commands.txt
  94. BIN  docs/intro/_images/admin10.png
  95. BIN  docs/intro/_images/admin11.png
  96. BIN  docs/intro/_images/admin11t.png
  97. BIN  docs/intro/_images/admin12.png
  98. 45  docs/intro/tutorial01.txt
  99. 12  docs/intro/tutorial02.txt
  100. 4  docs/intro/tutorial03.txt
  101. 4  docs/intro/tutorial04.txt
  102. 18  docs/ref/class-based-views.txt
  103. 1  docs/ref/contrib/formtools/form-wizard.txt
  104. 2  docs/ref/contrib/gis/geoquerysets.txt
  105. 9  docs/ref/contrib/staticfiles.txt
  106. 2  docs/ref/files/file.txt
  107. 5  docs/ref/settings.txt
  108. 7  docs/ref/templates/api.txt
  109. 4  docs/ref/unicode.txt
  110. 61  docs/releases/1.5.txt
  111. 3  docs/topics/class-based-views.txt
  112. 2  docs/topics/forms/formsets.txt
  113. 2  docs/topics/forms/index.txt
  114. 2  docs/topics/i18n/timezones.txt
  115. 138  docs/topics/install.txt
  116. 23  docs/topics/security.txt
  117. 13  docs/topics/settings.txt
  118. 57  docs/topics/testing.txt
  119. 36  setup.py
  120. 15  tests/modeltests/defer/tests.py
  121. 4  tests/modeltests/field_subclassing/tests.py
  122. 13  tests/modeltests/files/tests.py
  123. 30  tests/modeltests/fixtures/tests.py
  124. 0  tests/modeltests/known_related_objects/__init__.py
  125. 65  tests/modeltests/known_related_objects/fixtures/tournament.json
  126. 19  tests/modeltests/known_related_objects/models.py
  127. 88  tests/modeltests/known_related_objects/tests.py
  128. 14  tests/modeltests/model_forms/tests.py
  129. 18  tests/modeltests/model_inheritance/tests.py
  130. 18  tests/modeltests/serializers/tests.py
  131. 8  tests/modeltests/str/tests.py
  132. 5  tests/modeltests/update_only_fields/tests.py
  133. 8  tests/modeltests/user_commands/management/commands/dance.py
  134. 21  tests/modeltests/user_commands/tests.py
  135. 156  tests/modeltests/validation/test_error_messages.py
  136. 11  tests/regressiontests/admin_scripts/tests.py
  137. 2  tests/regressiontests/admin_util/tests.py
  138. 2  tests/regressiontests/admin_widgets/tests.py
  139. 12  tests/regressiontests/backends/tests.py
  140. 12  tests/regressiontests/cache/tests.py
  141. 4  tests/regressiontests/conditional_processing/models.py
  142. 2  tests/regressiontests/csrf_tests/tests.py
  143. 54  tests/regressiontests/file_storage/tests.py
  144. 32  tests/regressiontests/file_uploads/tests.py
  145. 19  tests/regressiontests/fixtures_regress/tests.py
  146. 59  tests/regressiontests/forms/tests/fields.py
  147. 0  tests/regressiontests/forms/tests/filepath_test_files/.dot-file
  148. 0  tests/regressiontests/forms/tests/filepath_test_files/directory/.keep
  149. 0  tests/regressiontests/forms/tests/filepath_test_files/fake-image.jpg
  150. 0  tests/regressiontests/forms/tests/filepath_test_files/real-text-file.txt
  151. 6  tests/regressiontests/forms/tests/forms.py
  152. 6  tests/regressiontests/forms/tests/models.py
  153. 5  tests/regressiontests/forms/tests/regressions.py
  154. 2  tests/regressiontests/forms/tests/widgets.py
  155. 52  tests/regressiontests/generic_views/base.py
  156. 31  tests/regressiontests/generic_views/dates.py
  157. 10  tests/regressiontests/generic_views/list.py
  158. 2  tests/regressiontests/generic_views/templates/generic_views/book_archive.html
  159. 2  tests/regressiontests/generic_views/templates/generic_views/book_archive_year.html
  160. 9  tests/regressiontests/generic_views/urls.py
  161. 2  tests/regressiontests/handlers/tests.py
  162. 10  tests/regressiontests/httpwrappers/tests.py
  163. 23  tests/regressiontests/i18n/commands/compilation.py
  164. BIN  tests/regressiontests/i18n/other/locale/fr/LC_MESSAGES/django.mo
  165. 6  tests/regressiontests/i18n/other/locale/fr/LC_MESSAGES/django.po
  166. 18  tests/regressiontests/i18n/tests.py
  167. 26  tests/regressiontests/inspectdb/tests.py
  168. 2  tests/regressiontests/localflavor/es/tests.py
  169. 2  tests/regressiontests/localflavor/mk/tests.py
  170. 50  tests/regressiontests/mail/tests.py
  171. 14  tests/regressiontests/model_fields/tests.py
  172. 6  tests/regressiontests/model_forms_regress/tests.py
  173. 2  tests/regressiontests/queries/models.py
  174. 59  tests/regressiontests/queries/tests.py
  175. 88  tests/regressiontests/requests/tests.py
  176. 6  tests/regressiontests/servers/tests.py
  177. 6  tests/regressiontests/signing/tests.py
  178. 7  tests/regressiontests/staticfiles_tests/storage.py
  179. 122  tests/regressiontests/staticfiles_tests/tests.py
  180. 2  tests/regressiontests/string_lookup/tests.py
  181. 14  tests/regressiontests/templates/tests.py
  182. 12  tests/regressiontests/templates/unicode.py
  183. 1,034  tests/regressiontests/test_client_regress/models.py
  184. 1,006  tests/regressiontests/test_client_regress/tests.py
  185. 5  tests/regressiontests/test_client_regress/views.py
  186. 11  tests/regressiontests/test_runner/tests.py
  187. 6  tests/regressiontests/views/__init__.py
  188. 104  tests/regressiontests/views/tests/debug.py
  189. 10  tests/regressiontests/views/tests/static.py
  190. 23  tests/regressiontests/views/views.py
5  AUTHORS
@@ -93,7 +93,7 @@ answer newbie questions, and generally made Django that much better:
93 93
     Simon Blanchard
94 94
     David Blewett <david@dawninglight.net>
95 95
     Matt Boersma <matt@sprout.org>
96  
-    boobsd@gmail.com
  96
+    Artem Gnilov <boobsd@gmail.com>
97 97
     Matías Bordese
98 98
     Nate Bragg <jonathan.bragg@alum.rpi.edu>
99 99
     Sean Brant
@@ -211,7 +211,6 @@ answer newbie questions, and generally made Django that much better:
211 211
     Dimitris Glezos <dimitris@glezos.com>
212 212
     glin@seznam.cz
213 213
     martin.glueck@gmail.com
214  
-    Artyom Gnilov <boobsd@gmail.com>
215 214
     Ben Godfrey <http://aftnn.org>
216 215
     GomoX <gomo@datafull.com>
217 216
     Guilherme Mesquita Gondim <semente@taurinus.org>
@@ -347,6 +346,7 @@ answer newbie questions, and generally made Django that much better:
347 346
     Frantisek Malina <vizualbod@vizualbod.com>
348 347
     Mike Malone <mjmalone@gmail.com>
349 348
     Martin Maney <http://www.chipy.org/Martin_Maney>
  349
+    Michael Manfre <mmanfre@gmail.com>
350 350
     masonsimon+django@gmail.com
351 351
     Manuzhai
352 352
     Petr Marhoun <petr.marhoun@gmail.com>
@@ -401,6 +401,7 @@ answer newbie questions, and generally made Django that much better:
401 401
     Christian Oudard <christian.oudard@gmail.com>
402 402
     oggie rob <oz.robharvey@gmail.com>
403 403
     oggy <ognjen.maric@gmail.com>
  404
+    Jens Page
404 405
     Jay Parlar <parlar@gmail.com>
405 406
     Carlos Eduardo de Paula <carlosedp@gmail.com>
406 407
     John Paulett <john@paulett.org>
22  django/contrib/admin/static/admin/js/actions.js
@@ -3,7 +3,7 @@
3 3
 		var options = $.extend({}, $.fn.actions.defaults, opts);
4 4
 		var actionCheckboxes = $(this);
5 5
 		var list_editable_changed = false;
6  
-		checker = function(checked) {
  6
+		var checker = function(checked) {
7 7
 			if (checked) {
8 8
 				showQuestion();
9 9
 			} else {
@@ -11,7 +11,7 @@
11 11
 			}
12 12
 			$(actionCheckboxes).attr("checked", checked)
13 13
 				.parent().parent().toggleClass(options.selectedClass, checked);
14  
-		}
  14
+		},
15 15
 		updateCounter = function() {
16 16
 			var sel = $(actionCheckboxes).filter(":checked").length;
17 17
 			$(options.counterContainer).html(interpolate(
@@ -29,30 +29,30 @@
29 29
 				}
30 30
 				return value;
31 31
 			});
32  
-		}
  32
+		},
33 33
 		showQuestion = function() {
34 34
 			$(options.acrossClears).hide();
35 35
 			$(options.acrossQuestions).show();
36 36
 			$(options.allContainer).hide();
37  
-		}
  37
+		},
38 38
 		showClear = function() {
39 39
 			$(options.acrossClears).show();
40 40
 			$(options.acrossQuestions).hide();
41 41
 			$(options.actionContainer).toggleClass(options.selectedClass);
42 42
 			$(options.allContainer).show();
43 43
 			$(options.counterContainer).hide();
44  
-		}
  44
+		},
45 45
 		reset = function() {
46 46
 			$(options.acrossClears).hide();
47 47
 			$(options.acrossQuestions).hide();
48 48
 			$(options.allContainer).hide();
49 49
 			$(options.counterContainer).show();
50  
-		}
  50
+		},
51 51
 		clearAcross = function() {
52 52
 			reset();
53 53
 			$(options.acrossInput).val(0);
54 54
 			$(options.actionContainer).removeClass(options.selectedClass);
55  
-		}
  55
+		};
56 56
 		// Show counter by default
57 57
 		$(options.counterContainer).show();
58 58
 		// Check state of checkboxes and reinit state if needed
@@ -81,9 +81,9 @@
81 81
 		});
82 82
 		lastChecked = null;
83 83
 		$(actionCheckboxes).click(function(event) {
84  
-			if (!event) { var event = window.event; }
  84
+			if (!event) { event = window.event; }
85 85
 			var target = event.target ? event.target : event.srcElement;
86  
-			if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey == true) {
  86
+			if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) {
87 87
 				var inrange = false;
88 88
 				$(lastChecked).attr("checked", target.checked)
89 89
 					.parent().parent().toggleClass(options.selectedClass, target.checked);
@@ -124,7 +124,7 @@
124 124
 				}
125 125
 			}
126 126
 		});
127  
-	}
  127
+	};
128 128
 	/* Setup plugin defaults */
129 129
 	$.fn.actions.defaults = {
130 130
 		actionContainer: "div.actions",
@@ -135,5 +135,5 @@
135 135
 		acrossClears: "div.actions span.clear",
136 136
 		allToggle: "#action-toggle",
137 137
 		selectedClass: "selected"
138  
-	}
  138
+	};
139 139
 })(django.jQuery);
13  django/contrib/admin/static/admin/js/actions.min.js
... ...
@@ -1,7 +1,6 @@
1  
-(function(a){a.fn.actions=function(g){var b=a.extend({},a.fn.actions.defaults,g),f=a(this),e=!1;checker=function(c){c?showQuestion():reset();a(f).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(f).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).attr("checked",function(){c==f.length?(value=!0,showQuestion()):(value=
2  
-!1,clearAcross());return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};
3  
-a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();1==a(b.acrossInput).val()&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",!1);clearAcross();checker(0);
4  
-updateCounter()});lastChecked=null;a(f).click(function(c){if(!c)c=window.event;var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&!0==c.shiftKey){var e=!1;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(f).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,
5  
-d.checked);lastChecked=d;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var b=!1;a("div.actions select option:selected").each(function(){a(this).val()&&(b=!0)});
6  
-if(b)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",
7  
-acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
  1
+(function(a){a.fn.actions=function(m){var b=a.extend({},a.fn.actions.defaults,m),f=a(this),e=!1,j=function(c){c?h():i();a(f).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)},g=function(){var c=a(f).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).attr("checked",function(){c==f.length?(value=!0,h()):(value=!1,k());return value})},h=function(){a(b.acrossClears).hide();
  2
+a(b.acrossQuestions).show();a(b.allContainer).hide()},l=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},i=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},k=function(){i();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);
  3
+g();1==a(b.acrossInput).val()&&l()});a(b.allToggle).show().click(function(){j(a(this).attr("checked"));g()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);l()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",!1);k();j(0);g()});lastChecked=null;a(f).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(lastChecked).attr("checked",
  4
+d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(f).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))e=e?false:true;e&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);lastChecked=d;g()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});
  5
+a('form#changelist-form input[name="_save"]').click(function(){var b=!1;a("div.actions select option:selected").each(function(){a(this).val()&&(b=!0)});if(b)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};
  6
+a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
26  django/contrib/admin/static/admin/js/inlines.js
@@ -31,11 +31,11 @@
31 31
 			}
32 32
 		};
33 33
 		var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").attr("autocomplete", "off");
34  
-		var nextIndex = parseInt(totalForms.val());
  34
+		var nextIndex = parseInt(totalForms.val(), 10);
35 35
 		var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").attr("autocomplete", "off");
36 36
 		// only show the add button if we are allowed to add more items,
37 37
         // note that max_num = None translates to a blank string.
38  
-		var showAddButton = maxForms.val() == '' || (maxForms.val()-totalForms.val()) > 0;
  38
+		var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0;
39 39
 		$(this).each(function(i) {
40 40
 			$(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
41 41
 		});
@@ -52,13 +52,14 @@
52 52
 				$(this).filter(":last").after('<div class="' + options.addCssClass + '"><a href="javascript:void(0)">' + options.addText + "</a></div>");
53 53
 				addButton = $(this).filter(":last").next().find("a");
54 54
 			}
55  
-			addButton.click(function() {
  55
+			addButton.click(function(e) {
  56
+				e.preventDefault();
56 57
 				var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS");
57 58
 				var template = $("#" + options.prefix + "-empty");
58 59
 				var row = template.clone(true);
59 60
 				row.removeClass(options.emptyCssClass)
60  
-				    .addClass(options.formCssClass)
61  
-				    .attr("id", options.prefix + "-" + nextIndex);
  61
+					.addClass(options.formCssClass)
  62
+					.attr("id", options.prefix + "-" + nextIndex);
62 63
 				if (row.is("tr")) {
63 64
 					// If the forms are laid out in table rows, insert
64 65
 					// the remove button into the last table cell:
@@ -78,14 +79,15 @@
78 79
 				// Insert the new form when it has been fully edited
79 80
 				row.insertBefore($(template));
80 81
 				// Update number of total forms
81  
-				$(totalForms).val(parseInt(totalForms.val()) + 1);
  82
+				$(totalForms).val(parseInt(totalForms.val(), 10) + 1);
82 83
 				nextIndex += 1;
83 84
 				// Hide add button in case we've hit the max, except we want to add infinitely
84  
-				if ((maxForms.val() != '') && (maxForms.val()-totalForms.val()) <= 0) {
  85
+				if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) {
85 86
 					addButton.parent().hide();
86 87
 				}
87 88
 				// The delete button of each row triggers a bunch of other things
88  
-				row.find("a." + options.deleteCssClass).click(function() {
  89
+				row.find("a." + options.deleteCssClass).click(function(e) {
  90
+					e.preventDefault();
89 91
 					// Remove the parent form containing this button:
90 92
 					var row = $(this).parents("." + options.formCssClass);
91 93
 					row.remove();
@@ -98,7 +100,7 @@
98 100
 					var forms = $("." + options.formCssClass);
99 101
 					$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
100 102
 					// Show add button again once we drop below max
101  
-					if ((maxForms.val() == '') || (maxForms.val()-forms.length) > 0) {
  103
+					if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) {
102 104
 						addButton.parent().show();
103 105
 					}
104 106
 					// Also, update names and ids for all remaining form controls
@@ -110,17 +112,15 @@
110 112
 							updateElementIndex(this, options.prefix, i);
111 113
 						});
112 114
 					}
113  
-					return false;
114 115
 				});
115 116
 				// If a post-add callback was supplied, call it with the added form:
116 117
 				if (options.added) {
117 118
 					options.added(row);
118 119
 				}
119  
-				return false;
120 120
 			});
121 121
 		}
122 122
 		return this;
123  
-	}
  123
+	};
124 124
 	/* Setup plugin defaults */
125 125
 	$.fn.formset.defaults = {
126 126
 		prefix: "form",					// The form prefix for your django formset
@@ -132,5 +132,5 @@
132 132
 		formCssClass: "dynamic-form",	// CSS class applied to each form in a formset
133 133
 		added: null,					// Function called each time a new form is added
134 134
 		removed: null					// Function called each time a form is deleted
135  
-	}
  135
+	};
136 136
 })(django.jQuery);
10  django/contrib/admin/static/admin/js/inlines.min.js
... ...
@@ -1,5 +1,5 @@
1  
-(function(b){b.fn.formset=function(c){var a=b.extend({},b.fn.formset.defaults,c),j=function(a,e,d){var i=RegExp("("+e+"-(\\d+|__prefix__))"),e=e+"-"+d;b(a).attr("for")&&b(a).attr("for",b(a).attr("for").replace(i,e));if(a.id)a.id=a.id.replace(i,e);if(a.name)a.name=a.name.replace(i,e)},c=b("#id_"+a.prefix+"-TOTAL_FORMS").attr("autocomplete","off"),g=parseInt(c.val()),f=b("#id_"+a.prefix+"-MAX_NUM_FORMS").attr("autocomplete","off"),c=""==f.val()||0<f.val()-c.val();b(this).each(function(){b(this).not("."+
2  
-a.emptyCssClass).addClass(a.formCssClass)});if(b(this).length&&c){var h;"TR"==b(this).attr("tagName")?(c=this.eq(0).children().length,b(this).parent().append('<tr class="'+a.addCssClass+'"><td colspan="'+c+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),h=b(this).parent().find("tr:last a")):(b(this).filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),h=b(this).filter(":last").next().find("a"));h.click(function(){var c=b("#id_"+a.prefix+
3  
-"-TOTAL_FORMS"),e=b("#"+a.prefix+"-empty"),d=e.clone(!0);d.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+g);d.is("tr")?d.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):d.is("ul")||d.is("ol")?d.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):d.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+
4  
-"</a></span>");d.find("*").each(function(){j(this,a.prefix,c.val())});d.insertBefore(b(e));b(c).val(parseInt(c.val())+1);g+=1;""!=f.val()&&0>=f.val()-c.val()&&h.parent().hide();d.find("a."+a.deleteCssClass).click(function(){var c=b(this).parents("."+a.formCssClass);c.remove();g-=1;a.removed&&a.removed(c);c=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(c.length);(""==f.val()||0<f.val()-c.length)&&h.parent().show();for(var d=0,e=c.length;d<e;d++)j(b(c).get(d),a.prefix,d),b(c.get(d)).find("*").each(function(){j(this,
5  
-a.prefix,d)});return!1});a.added&&a.added(d);return!1})}return this};b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null}})(django.jQuery);
  1
+(function(b){b.fn.formset=function(c){var a=b.extend({},b.fn.formset.defaults,c),j=function(a,f,d){var e=RegExp("("+f+"-(\\d+|__prefix__))"),f=f+"-"+d;b(a).attr("for")&&b(a).attr("for",b(a).attr("for").replace(e,f));a.id&&(a.id=a.id.replace(e,f));a.name&&(a.name=a.name.replace(e,f))},c=b("#id_"+a.prefix+"-TOTAL_FORMS").attr("autocomplete","off"),h=parseInt(c.val(),10),g=b("#id_"+a.prefix+"-MAX_NUM_FORMS").attr("autocomplete","off"),c=""===g.val()||0<g.val()-c.val();b(this).each(function(){b(this).not("."+
  2
+a.emptyCssClass).addClass(a.formCssClass)});if(b(this).length&&c){var i;"TR"==b(this).attr("tagName")?(c=this.eq(0).children().length,b(this).parent().append('<tr class="'+a.addCssClass+'"><td colspan="'+c+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),i=b(this).parent().find("tr:last a")):(b(this).filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),i=b(this).filter(":last").next().find("a"));i.click(function(c){c.preventDefault();
  3
+var f=b("#id_"+a.prefix+"-TOTAL_FORMS"),c=b("#"+a.prefix+"-empty"),d=c.clone(true);d.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+h);d.is("tr")?d.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):d.is("ul")||d.is("ol")?d.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):d.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+
  4
+a.deleteText+"</a></span>");d.find("*").each(function(){j(this,a.prefix,f.val())});d.insertBefore(b(c));b(f).val(parseInt(f.val(),10)+1);h=h+1;g.val()!==""&&g.val()-f.val()<=0&&i.parent().hide();d.find("a."+a.deleteCssClass).click(function(e){e.preventDefault();e=b(this).parents("."+a.formCssClass);e.remove();h=h-1;a.removed&&a.removed(e);e=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(e.length);(g.val()===""||g.val()-e.length>0)&&i.parent().show();for(var c=0,d=e.length;c<d;c++){j(b(e).get(c),
  5
+a.prefix,c);b(e.get(c)).find("*").each(function(){j(this,a.prefix,c)})}});a.added&&a.added(d)})}return this};b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null}})(django.jQuery);
8  django/contrib/admin/templates/admin/index.html
@@ -15,8 +15,12 @@
15 15
 {% if app_list %}
16 16
     {% for app in app_list %}
17 17
         <div class="module">
18  
-        <table summary="{% blocktrans with name=app.name %}Models available in the {{ name }} application.{% endblocktrans %}">
19  
-        <caption><a href="{{ app.app_url }}" class="section">{% blocktrans with name=app.name %}{{ name }}{% endblocktrans %}</a></caption>
  18
+        <table>
  19
+        <caption>
  20
+            <a href="{{ app.app_url }}" class="section" title="{% blocktrans with name=app.name %}Models in the {{ name }} application{% endblocktrans %}">
  21
+                {% blocktrans with name=app.name %}{{ name }}{% endblocktrans %}
  22
+            </a>
  23
+        </caption>
20 24
         {% for model in app.models %}
21 25
             <tr>
22 26
             {% if model.admin_url %}
1  django/contrib/admin/views/main.py
... ...
@@ -1,4 +1,5 @@
1 1
 import operator
  2
+from functools import reduce
2 3
 
3 4
 from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured
4 5
 from django.core.paginator import InvalidPage
14  django/contrib/auth/management/commands/createsuperuser.py
@@ -80,7 +80,7 @@ def handle(self, *args, **options):
80 80
                     if default_username and username == '':
81 81
                         username = default_username
82 82
                     if not RE_VALID_USERNAME.match(username):
83  
-                        sys.stderr.write("Error: That username is invalid. Use only letters, digits and underscores.\n")
  83
+                        self.stderr.write("Error: That username is invalid. Use only letters, digits and underscores.")
84 84
                         username = None
85 85
                         continue
86 86
                     try:
@@ -88,7 +88,7 @@ def handle(self, *args, **options):
88 88
                     except User.DoesNotExist:
89 89
                         break
90 90
                     else:
91  
-                        sys.stderr.write("Error: That username is already taken.\n")
  91
+                        self.stderr.write("Error: That username is already taken.")
92 92
                         username = None
93 93
 
94 94
                 # Get an email
@@ -98,7 +98,7 @@ def handle(self, *args, **options):
98 98
                     try:
99 99
                         is_valid_email(email)
100 100
                     except exceptions.ValidationError:
101  
-                        sys.stderr.write("Error: That e-mail address is invalid.\n")
  101
+                        self.stderr.write("Error: That e-mail address is invalid.")
102 102
                         email = None
103 103
                     else:
104 104
                         break
@@ -109,19 +109,19 @@ def handle(self, *args, **options):
109 109
                         password = getpass.getpass()
110 110
                         password2 = getpass.getpass('Password (again): ')
111 111
                         if password != password2:
112  
-                            sys.stderr.write("Error: Your passwords didn't match.\n")
  112
+                            self.stderr.write("Error: Your passwords didn't match.")
113 113
                             password = None
114 114
                             continue
115 115
                     if password.strip() == '':
116  
-                        sys.stderr.write("Error: Blank passwords aren't allowed.\n")
  116
+                        self.stderr.write("Error: Blank passwords aren't allowed.")
117 117
                         password = None
118 118
                         continue
119 119
                     break
120 120
             except KeyboardInterrupt:
121  
-                sys.stderr.write("\nOperation cancelled.\n")
  121
+                self.stderr.write("\nOperation cancelled.")
122 122
                 sys.exit(1)
123 123
 
124 124
         User.objects.db_manager(database).create_superuser(username, email, password)
125 125
         if verbosity >= 1:
126  
-          self.stdout.write("Superuser created successfully.\n")
  126
+          self.stdout.write("Superuser created successfully.")
127 127
 
13  django/contrib/auth/tests/management.py
@@ -2,6 +2,7 @@
2 2
 
3 3
 from django.contrib.auth import models, management
4 4
 from django.contrib.auth.management.commands import changepassword
  5
+from django.core.management.base import CommandError
5 6
 from django.test import TestCase
6 7
 
7 8
 
@@ -56,16 +57,10 @@ def test_that_changepassword_command_changes_joes_password(self):
56 57
     def test_that_max_tries_exits_1(self):
57 58
         """
58 59
         A CommandError should be thrown by handle() if the user enters in
59  
-        mismatched passwords three times. This should be caught by execute() and
60  
-        converted to a SystemExit
  60
+        mismatched passwords three times.
61 61
         """
62 62
         command = changepassword.Command()
63 63
         command._get_pass = lambda *args: args or 'foo'
64 64
 
65  
-        self.assertRaises(
66  
-            SystemExit,
67  
-            command.execute,
68  
-            "joe",
69  
-            stdout=self.stdout,
70  
-            stderr=self.stderr
71  
-        )
  65
+        with self.assertRaises(CommandError):
  66
+            command.execute("joe", stdout=self.stdout, stderr=self.stderr)
11  django/contrib/flatpages/fixtures/example_site.json
... ...
@@ -0,0 +1,11 @@
  1
+[
  2
+  {
  3
+    "pk": 1,
  4
+    "model": "sites.site",
  5
+    "fields": {
  6
+      "domain": "example.com",
  7
+      "name": "example.com"
  8
+    }
  9
+  }
  10
+]
  11
+
3  django/contrib/flatpages/tests/csrf.py
@@ -18,9 +18,10 @@
18 18
     TEMPLATE_DIRS=(
19 19
         os.path.join(os.path.dirname(__file__), 'templates'),
20 20
     ),
  21
+    SITE_ID=1,
21 22
 )
22 23
 class FlatpageCSRFTests(TestCase):
23  
-    fixtures = ['sample_flatpages']
  24
+    fixtures = ['sample_flatpages', 'example_site']
24 25
     urls = 'django.contrib.flatpages.tests.urls'
25 26
 
26 27
     def setUp(self):
5  django/contrib/flatpages/tests/forms.py
@@ -5,7 +5,10 @@
5 5
 from django.test.utils import override_settings
6 6
 from django.utils import translation
7 7
 
  8
+@override_settings(SITE_ID=1)
8 9
 class FlatpageAdminFormTests(TestCase):
  10
+    fixtures = ['example_site']
  11
+
9 12
     def setUp(self):
10 13
         self.form_data = {
11 14
             'title': "A test page",
@@ -89,5 +92,5 @@ def test_flatpage_nosites(self):
89 92
 
90 93
         self.assertEqual(
91 94
             f.errors,
92  
-            {'sites': [u'This field is required.']})
  95
+            {'sites': [translation.ugettext(u'This field is required.')]})
93 96
 
12  django/contrib/flatpages/tests/middleware.py
@@ -19,9 +19,10 @@
19 19
     TEMPLATE_DIRS=(
20 20
         os.path.join(os.path.dirname(__file__), 'templates'),
21 21
     ),
  22
+    SITE_ID=1,
22 23
 )
23 24
 class FlatpageMiddlewareTests(TestCase):
24  
-    fixtures = ['sample_flatpages']
  25
+    fixtures = ['sample_flatpages', 'example_site']
25 26
     urls = 'django.contrib.flatpages.tests.urls'
26 27
 
27 28
     def test_view_flatpage(self):
@@ -75,7 +76,7 @@ def test_fallback_flatpage_special_chars(self):
75 76
             enable_comments=False,
76 77
             registration_required=False,
77 78
         )
78  
-        fp.sites.add(1)
  79
+        fp.sites.add(settings.SITE_ID)
79 80
 
80 81
         response = self.client.get('/some.very_special~chars-here/')
81 82
         self.assertEqual(response.status_code, 200)
@@ -96,9 +97,10 @@ def test_fallback_flatpage_special_chars(self):
96 97
     TEMPLATE_DIRS=(
97 98
         os.path.join(os.path.dirname(__file__), 'templates'),
98 99
     ),
  100
+    SITE_ID=1,
99 101
 )
100 102
 class FlatpageMiddlewareAppendSlashTests(TestCase):
101  
-    fixtures = ['sample_flatpages']
  103
+    fixtures = ['sample_flatpages', 'example_site']
102 104
     urls = 'django.contrib.flatpages.tests.urls'
103 105
 
104 106
     def test_redirect_view_flatpage(self):
@@ -130,7 +132,7 @@ def test_redirect_fallback_flatpage_special_chars(self):
130 132
             enable_comments=False,
131 133
             registration_required=False,
132 134
         )
133  
-        fp.sites.add(1)
  135
+        fp.sites.add(settings.SITE_ID)
134 136
 
135 137
         response = self.client.get('/some.very_special~chars-here')
136 138
         self.assertRedirects(response, '/some.very_special~chars-here/', status_code=301)
@@ -144,7 +146,7 @@ def test_redirect_fallback_flatpage_root(self):
144 146
             enable_comments=False,
145 147
             registration_required=False,
146 148
         )
147  
-        fp.sites.add(1)
  149
+        fp.sites.add(settings.SITE_ID)
148 150
 
149 151
         response = self.client.get('/')
150 152
         self.assertEqual(response.status_code, 200)
1  django/contrib/flatpages/tests/templatetags.py
@@ -18,6 +18,7 @@
18 18
     TEMPLATE_DIRS=(
19 19
         os.path.join(os.path.dirname(__file__), 'templates'),
20 20
     ),
  21
+    SITE_ID=1,
21 22
 )
22 23
 class FlatpageTemplateTagTests(TestCase):
23 24
     fixtures = ['sample_flatpages']
8  django/contrib/flatpages/tests/views.py
@@ -19,9 +19,10 @@
19 19
     TEMPLATE_DIRS=(
20 20
         os.path.join(os.path.dirname(__file__), 'templates'),
21 21
     ),
  22
+    SITE_ID=1,
22 23
 )
23 24
 class FlatpageViewTests(TestCase):
24  
-    fixtures = ['sample_flatpages']
  25
+    fixtures = ['sample_flatpages', 'example_site']
25 26
     urls = 'django.contrib.flatpages.tests.urls'
26 27
 
27 28
     def test_view_flatpage(self):
@@ -85,9 +86,10 @@ def test_view_flatpage_special_chars(self):
85 86
     TEMPLATE_DIRS=(
86 87
         os.path.join(os.path.dirname(__file__), 'templates'),
87 88
     ),
  89
+    SITE_ID=1,
88 90
 )
89 91
 class FlatpageViewAppendSlashTests(TestCase):
90  
-    fixtures = ['sample_flatpages']
  92
+    fixtures = ['sample_flatpages', 'example_site']
91 93
     urls = 'django.contrib.flatpages.tests.urls'
92 94
 
93 95
     def test_redirect_view_flatpage(self):
@@ -119,7 +121,7 @@ def test_redirect_view_flatpage_special_chars(self):
119 121
             enable_comments=False,
120 122
             registration_required=False,
121 123
         )
122  
-        fp.sites.add(1)
  124
+        fp.sites.add(settings.SITE_ID)
123 125
 
124 126
         response = self.client.get('/flatpage_root/some.very_special~chars-here')
125 127
         self.assertRedirects(response, '/flatpage_root/some.very_special~chars-here/', status_code=301)
57  django/contrib/formtools/tests/__init__.py
@@ -156,9 +156,6 @@ def test_form_submit_bad_hash(self):
156 156
 
157 157
 
158 158
 class FormHmacTests(unittest.TestCase):
159  
-    """
160  
-    Same as SecurityHashTests, but with form_hmac
161  
-    """
162 159
 
163 160
     def test_textfield_hash(self):
164 161
         """
@@ -166,8 +163,8 @@ def test_textfield_hash(self):
166 163
         leading/trailing whitespace so as to be friendly to broken browsers that
167 164
         submit it (usually in textareas).
168 165
         """
169  
-        f1 = HashTestForm({'name': 'joe', 'bio': 'Nothing notable.'})
170  
-        f2 = HashTestForm({'name': '  joe', 'bio': 'Nothing notable.  '})
  166
+        f1 = HashTestForm({'name': u'joe', 'bio': u'Nothing notable.'})
  167
+        f2 = HashTestForm({'name': u'  joe', 'bio': u'Nothing notable.  '})
171 168
         hash1 = utils.form_hmac(f1)
172 169
         hash2 = utils.form_hmac(f2)
173 170
         self.assertEqual(hash1, hash2)
@@ -269,10 +266,10 @@ def test_good_hash(self):
269 266
         Form should advance if the hash is present and good, as calculated using
270 267
         current method.
271 268
         """
272  
-        data = {"0-field": "test",
273  
-                "1-field": "test2",
274  
-                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
275  
-                "wizard_step": "1"}
  269
+        data = {"0-field": u"test",
  270
+                "1-field": u"test2",
  271
+                "hash_0": u"cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  272
+                "wizard_step": u"1"}
276 273
         response = self.client.post('/wizard1/', data)
277 274
         self.assertEqual(2, response.context['step0'])
278 275
 
@@ -294,18 +291,18 @@ def process_step(self, request, form, step):
294 291
                     reached[0] = True
295 292
 
296 293
         wizard = WizardWithProcessStep([WizardPageOneForm])
297  
-        data = {"0-field": "test",
298  
-                "1-field": "test2",
299  
-                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
300  
-                "wizard_step": "1"}
  294
+        data = {"0-field": u"test",
  295
+                "1-field": u"test2",
  296
+                "hash_0": u"cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  297
+                "wizard_step": u"1"}
301 298
         wizard(DummyRequest(POST=data))
302 299
         self.assertTrue(reached[0])
303 300
 
304  
-        data = {"0-field": "test",
305  
-                "1-field": "test2",
306  
-                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
307  
-                "hash_1": "d5b434e3934cc92fee4bd2964c4ebc06f81d362d",
308  
-                "wizard_step": "2"}
  301
+        data = {"0-field": u"test",
  302
+                "1-field": u"test2",
  303
+                "hash_0": "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  304
+                "hash_1": u"1e6f6315da42e62f33a30640ec7e007ad3fbf1a1",
  305
+                "wizard_step": u"2"}
309 306
         self.assertRaises(http.Http404, wizard, DummyRequest(POST=data))
310 307
 
311 308
     def test_14498(self):
@@ -324,10 +321,10 @@ def process_step(self, request, form, step):
324 321
         wizard = WizardWithProcessStep([WizardPageOneForm,
325 322
                                         WizardPageTwoForm,
326 323
                                         WizardPageThreeForm])
327  
-        data = {"0-field": "test",
328  
-                "1-field": "test2",
329  
-                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
330  
-                "wizard_step": "1"}
  324
+        data = {"0-field": u"test",
  325
+                "1-field": u"test2",
  326
+                "hash_0": u"cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  327
+                "wizard_step": u"1"}
331 328
         wizard(DummyRequest(POST=data))
332 329
         self.assertTrue(reached[0])
333 330
 
@@ -348,10 +345,10 @@ def done(self, request, form_list):
348 345
         wizard = Wizard([WizardPageOneForm,
349 346
                          WizardPageTwoForm])
350 347
 
351  
-        data = {"0-field": "test",
352  
-                "1-field": "test2",
353  
-                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
354  
-                "wizard_step": "1"}
  348
+        data = {"0-field": u"test",
  349
+                "1-field": u"test2",
  350
+                "hash_0": u"cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  351
+                "wizard_step": u"1"}
355 352
         wizard(DummyRequest(POST=data))
356 353
         self.assertTrue(reached[0])
357 354
 
@@ -374,10 +371,10 @@ def process_step(self, request, form, step):
374 371
         wizard = WizardWithProcessStep([WizardPageOneForm,
375 372
                                         WizardPageTwoForm,
376 373
                                         WizardPageThreeForm])
377  
-        data = {"0-field": "test",
378  
-                "1-field": "test2",
379  
-                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
380  
-                "wizard_step": "1"}
  374
+        data = {"0-field": u"test",
  375
+                "1-field": u"test2",
  376
+                "hash_0": u"cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  377
+                "wizard_step": u"1"}
381 378
         wizard(DummyRequest(POST=data))
382 379
         self.assertTrue(reached[0])
383 380
 
14  django/contrib/formtools/tests/wizard/namedwizardtests/tests.py
@@ -120,7 +120,7 @@ def test_form_finish(self):
120 120
         self.assertEqual(response.context['wizard']['steps'].current, 'form2')
121 121
 
122 122
         post_data = self.wizard_step_data[1]
123  
-        post_data['form2-file1'] = open(__file__)
  123
+        post_data['form2-file1'] = open(__file__, 'rb')
124 124
         response = self.client.post(
125 125
             reverse(self.wizard_urlname,
126 126
                     kwargs={'step': response.context['wizard']['steps'].current}),
@@ -147,7 +147,7 @@ def test_form_finish(self):
147 147
         self.assertEqual(response.status_code, 200)
148 148
 
149 149
         all_data = response.context['form_list']
150  
-        self.assertEqual(all_data[1]['file1'].read(), open(__file__).read())
  150
+        self.assertEqual(all_data[1]['file1'].read(), open(__file__, 'rb').read())
151 151
         del all_data[1]['file1']
152 152
         self.assertEqual(all_data, [
153 153
             {'name': u'Pony', 'thirsty': True, 'user': self.testuser},
@@ -168,7 +168,7 @@ def test_cleaned_data(self):
168 168
         self.assertEqual(response.status_code, 200)
169 169
 
170 170
         post_data = self.wizard_step_data[1]
171  
-        post_data['form2-file1'] = open(__file__)
  171
+        post_data['form2-file1'] = open(__file__, 'rb')
172 172
         response = self.client.post(
173 173
             reverse(self.wizard_urlname,
174 174
                     kwargs={'step': response.context['wizard']['steps'].current}),
@@ -180,7 +180,9 @@ def test_cleaned_data(self):
180 180
         response = self.client.get(step2_url)
181 181
         self.assertEqual(response.status_code, 200)
182 182
         self.assertEqual(response.context['wizard']['steps'].current, 'form2')
183  
-        self.assertEqual(response.context['wizard']['form'].files['form2-file1'].read(), open(__file__).read())
  183
+        self.assertEqual(
  184
+            response.context['wizard']['form'].files['form2-file1'].read(),
  185
+            open(__file__, 'rb').read())
184 186
 
185 187
         response = self.client.post(
186 188
             reverse(self.wizard_urlname,
@@ -197,7 +199,7 @@ def test_cleaned_data(self):
197 199
         self.assertEqual(response.status_code, 200)
198 200
 
199 201
         all_data = response.context['all_cleaned_data']
200  
-        self.assertEqual(all_data['file1'].read(), open(__file__).read())
  202
+        self.assertEqual(all_data['file1'].read(), open(__file__, 'rb').read())
201 203
         del all_data['file1']
202 204
         self.assertEqual(
203 205
             all_data,
@@ -221,7 +223,7 @@ def test_manipulated_data(self):
221 223
         self.assertEqual(response.status_code, 200)
222 224
 
223 225
         post_data = self.wizard_step_data[1]
224  
-        post_data['form2-file1'] = open(__file__)
  226
+        post_data['form2-file1'] = open(__file__, 'rb')
225 227
         response = self.client.post(
226 228
             reverse(self.wizard_urlname,
227 229
                     kwargs={'step': response.context['wizard']['steps'].current}),
12  django/contrib/formtools/tests/wizard/wizardtests/tests.py
@@ -80,7 +80,7 @@ def test_form_finish(self):
80 80
         self.assertEqual(response.context['wizard']['steps'].current, 'form2')
81 81
 
82 82
         post_data = self.wizard_step_data[1]
83  
-        post_data['form2-file1'] = open(__file__)
  83
+        post_data['form2-file1'] = open(__file__, 'rb')
84 84
         response = self.client.post(self.wizard_url, post_data)
85 85
         self.assertEqual(response.status_code, 200)
86 86
         self.assertEqual(response.context['wizard']['steps'].current, 'form3')
@@ -93,7 +93,7 @@ def test_form_finish(self):
93 93
         self.assertEqual(response.status_code, 200)
94 94
 
95 95
         all_data = response.context['form_list']
96  
-        self.assertEqual(all_data[1]['file1'].read(), open(__file__).read())
  96
+        self.assertEqual(all_data[1]['file1'].read(), open(__file__, 'rb').read())
97 97
         del all_data[1]['file1']
98 98
         self.assertEqual(all_data, [
99 99
             {'name': u'Pony', 'thirsty': True, 'user': self.testuser},
@@ -110,7 +110,7 @@ def test_cleaned_data(self):
110 110
         self.assertEqual(response.status_code, 200)
111 111
 
112 112
         post_data = self.wizard_step_data[1]
113  
-        post_data['form2-file1'] = open(__file__)
  113
+        post_data['form2-file1'] = open(__file__, 'rb')
114 114
         response = self.client.post(self.wizard_url, post_data)
115 115
         self.assertEqual(response.status_code, 200)
116 116
 
@@ -121,7 +121,7 @@ def test_cleaned_data(self):
121 121
         self.assertEqual(response.status_code, 200)
122 122
 
123 123
         all_data = response.context['all_cleaned_data']
124  
-        self.assertEqual(all_data['file1'].read(), open(__file__).read())
  124
+        self.assertEqual(all_data['file1'].read(), open(__file__, 'rb').read())
125 125
         del all_data['file1']
126 126
         self.assertEqual(all_data, {
127 127
             'name': u'Pony', 'thirsty': True, 'user': self.testuser,
@@ -138,7 +138,7 @@ def test_manipulated_data(self):
138 138
         self.assertEqual(response.status_code, 200)
139 139
 
140 140
         post_data = self.wizard_step_data[1]
141  
-        post_data['form2-file1'] = open(__file__)
  141
+        post_data['form2-file1'] = open(__file__, 'rb')
142 142
         response = self.client.post(self.wizard_url, post_data)
143 143
         self.assertEqual(response.status_code, 200)
144 144
 
@@ -165,7 +165,7 @@ def test_form_refresh(self):
165 165
         self.assertEqual(response.context['wizard']['steps'].current, 'form2')
166 166
 
167 167
         post_data = self.wizard_step_data[1]
168  
-        post_data['form2-file1'] = open(__file__)
  168
+        post_data['form2-file1'] = open(__file__, 'rb')
169 169
         response = self.client.post(self.wizard_url, post_data)
170 170
         self.assertEqual(response.status_code, 200)
171 171
         self.assertEqual(response.context['wizard']['steps'].current, 'form3')
6  django/contrib/formtools/utils.py
... ...
@@ -1,7 +1,5 @@
1  
-try:
2  
-    import cPickle as pickle
3  
-except ImportError:
4  
-    import pickle
  1
+# Do not try cPickle here (see #18340)
  2
+import pickle
5 3
 
6 4
 from django.utils.crypto import salted_hmac
7 5
 
8  django/contrib/gis/admin/options.py
@@ -36,6 +36,7 @@ class GeoModelAdmin(ModelAdmin):
36 36
     wms_url = 'http://vmap0.tiles.osgeo.org/wms/vmap0'
37 37
     wms_layer = 'basic'
38 38
     wms_name = 'OpenLayers WMS'
  39
+    wms_options = {'format': 'image/jpeg'}
39 40
     debug = False
40 41
     widget = OpenLayersWidget
41 42
 
@@ -76,6 +77,12 @@ def get_map_widget(self, db_field):
76 77
         class OLMap(self.widget):
77 78
             template = self.map_template
78 79
             geom_type = db_field.geom_type
  80
+
  81
+            wms_options = ''
  82
+            if self.wms_options:
  83
+                wms_options = ["%s: '%s'" % pair for pair in self.wms_options.items()]
  84
+                wms_options = ', %s' % ', '.join(wms_options)
  85
+
79 86
             params = {'default_lon' : self.default_lon,
80 87
                       'default_lat' : self.default_lat,
81 88
                       'default_zoom' : self.default_zoom,
@@ -106,6 +113,7 @@ class OLMap(self.widget):
106 113
                       'wms_url' : self.wms_url,
107 114
                       'wms_layer' : self.wms_layer,
108 115
                       'wms_name' : self.wms_name,
  116
+                      'wms_options' : wms_options,
109 117
                       'debug' : self.debug,
110 118
                       }
111 119
         return OLMap
4  django/contrib/gis/gdal/base.py
... ...
@@ -1,5 +1,5 @@
1 1
 from ctypes import c_void_p
2  
-from types import NoneType
  2
+
3 3
 from django.contrib.gis.gdal.error import GDALException
4 4
 
5 5
 class GDALBase(object):
@@ -26,7 +26,7 @@ def _set_ptr(self, ptr):
26 26
         # compatible type or None (NULL).
27 27
         if isinstance(ptr, (int, long)):
28 28
             self._ptr = self.ptr_type(ptr)
29  
-        elif isinstance(ptr, (self.ptr_type, NoneType)):
  29
+        elif ptr is None or isinstance(ptr, self.ptr_type):
30 30
             self._ptr = ptr
31 31
         else:
32 32
             raise TypeError('Incompatible pointer type')
4  django/contrib/gis/gdal/tests/__init__.py
@@ -2,10 +2,12 @@
2 2
 Module for executing all of the GDAL tests.  None
3 3
 of these tests require the use of the database.
4 4
 """
  5
+from __future__ import absolute_import
  6
+
5 7
 from django.utils.unittest import TestSuite, TextTestRunner
6 8
 
7 9
 # Importing the GDAL test modules.
8  
-import test_driver, test_ds, test_envelope, test_geom, test_srs
  10
+from . import test_driver, test_ds, test_envelope, test_geom, test_srs
9 11
 
10 12
 test_suites = [test_driver.suite(),
11 13
                test_ds.suite(),
4  django/contrib/gis/geoip/__init__.py
@@ -11,8 +11,10 @@
11 11
  Grab GeoIP.dat.gz and GeoLiteCity.dat.gz, and unzip them in the directory
12 12
  corresponding to settings.GEOIP_PATH.
13 13
 """
  14
+from __future__ import absolute_import
  15
+
14 16
 try:
15  
-    from django.contrib.gis.geoip.base import GeoIP, GeoIPException
  17
+    from .base import GeoIP, GeoIPException
16 18
     HAS_GEOIP = True
17 19
 except:
18 20
     HAS_GEOIP = False
4  django/contrib/gis/geos/base.py
... ...
@@ -1,5 +1,5 @@
1 1
 from ctypes import c_void_p
2  
-from types import NoneType
  2
+
3 3
 from django.contrib.gis.geos.error import GEOSException
4 4
 
5 5
 # Trying to import GDAL libraries, if available.  Have to place in
@@ -41,7 +41,7 @@ def _get_ptr(self):
41 41
     def _set_ptr(self, ptr):
42 42
         # Only allow the pointer to be set with pointers of the
43 43
         # compatible type or None (NULL).
44  
-        if isinstance(ptr, (self.ptr_type, NoneType)):
  44
+        if ptr is None or isinstance(ptr, self.ptr_type):
45 45
             self._ptr = ptr
46 46
         else:
47 47
             raise TypeError('Incompatible pointer type')
29  django/contrib/gis/geos/mutable_list.py
@@ -8,6 +8,9 @@
8 8
 
9 9
 Author: Aryeh Leib Taurog.
10 10
 """
  11
+from django.utils.functional import total_ordering
  12
+
  13
+@total_ordering
11 14
 class ListMixin(object):
12 15
     """
13 16
     A base class which provides complete list interface.
@@ -143,20 +146,28 @@ def __imul__(self, n):
143 146
                 self.extend(cache)
144 147
         return self
145 148
 
146  
-    def __cmp__(self, other):
147  
-        'cmp'
  149
+    def __eq__(self, other):
  150
+        for i in range(len(self)):
  151
+            try:
  152
+                c = self[i] == other[i]
  153
+            except IndexError:
  154
+                # must be other is shorter
  155
+                return False
  156
+            if not c:
  157
+                return False
  158
+        return True
  159
+
  160
+    def __lt__(self, other):
148 161
         slen = len(self)
149 162
         for i in range(slen):
150 163
             try:
151  
-                c = cmp(self[i], other[i])
  164
+                c = self[i] < other[i]
152 165
             except IndexError:
153 166
                 # must be other is shorter
154  
-                return 1
155  
-            else:
156  
-                # elements not equal
157  
-                if c: return c
158  
-
159  
-        return cmp(slen, len(other))
  167
+                return False
  168
+            if c:
  169
+                return c
  170
+        return slen < len(other)
160 171
 
161 172
     ### Public list interface Methods ###
162 173
     ## Non-mutating ##
4  django/contrib/gis/geos/tests/__init__.py
... ...
@@ -1,8 +1,10 @@
1 1
 """
2 2
 GEOS Testing module.
3 3
 """
  4
+from __future__ import absolute_import
  5
+
4 6
 from django.utils.unittest import TestSuite, TextTestRunner
5  
-import test_geos, test_io, test_geos_mutation, test_mutable_list
  7
+from . import test_geos, test_io, test_geos_mutation, test_mutable_list
6 8
 
7 9
 test_suites = [
8 10
     test_geos.suite(),
125  django/contrib/gis/geos/tests/test_geos.py
... ...
@@ -1,18 +1,23 @@
1 1
 import ctypes
2 2
 import random
3  
-import unittest
4  
-from django.contrib.gis.geos import *
  3
+
  4
+from django.contrib.gis.geos import (GEOSException, GEOSIndexError, GEOSGeometry,
  5
+    GeometryCollection, Point, MultiPoint, Polygon, MultiPolygon, LinearRing,
  6
+    LineString, MultiLineString, fromfile, fromstr, geos_version_info)
5 7
 from django.contrib.gis.geos.base import gdal, numpy, GEOSBase
6 8
 from django.contrib.gis.geos.libgeos import GEOS_PREPARE
7 9
 from django.contrib.gis.geometry.test_data import TestDataMixin
8 10
 
  11
+from django.utils import unittest
  12
+
  13
+
9 14
 class GEOSTest(unittest.TestCase, TestDataMixin):
10 15
 
11 16
     @property
12 17
     def null_srid(self):
13 18
         """
14 19
         Returns the proper null SRID depending on the GEOS version.
15  
-        See the comments in `test15_srid` for more details.
  20
+        See the comments in `test_srid` for more details.
16 21
         """
17 22
         info = geos_version_info()
18 23
         if info['version'] == '3.0.0' and info['release_candidate']:
@@ -20,7 +25,7 @@ def null_srid(self):
20 25
         else:
21 26
             return None
22 27
 
23  
-    def test00_base(self):
  28
+    def test_base(self):
24 29
         "Tests out the GEOSBase class."
25 30
         # Testing out GEOSBase class, which provides a `ptr` property
26 31
         # that abstracts out access to underlying C pointers.
@@ -62,19 +67,19 @@ class FakeGeom2(GEOSBase):
62 67
             self.assertRaises(TypeError, fg1._set_ptr, bad_ptr)
63 68
             self.assertRaises(TypeError, fg2._set_ptr, bad_ptr)
64 69
 
65  
-    def test01a_wkt(self):
  70
+    def test_wkt(self):
66 71
         "Testing WKT output."
67 72
         for g in self.geometries.wkt_out:
68 73
             geom = fromstr(g.wkt)
69 74
             self.assertEqual(g.ewkt, geom.wkt)
70 75
 
71  
-    def test01b_hex(self):
  76
+    def test_hex(self):
72 77
         "Testing HEX output."
73 78
         for g in self.geometries.hex_wkt:
74 79
             geom = fromstr(g.wkt)
75 80
             self.assertEqual(g.hex, geom.hex)
76 81
 
77  
-    def test01b_hexewkb(self):
  82
+    def test_hexewkb(self):
78 83
         "Testing (HEX)EWKB output."
79 84
         from binascii import a2b_hex
80 85
 
@@ -124,14 +129,14 @@ def test01b_hexewkb(self):
124 129
         # Redundant sanity check.
125 130
         self.assertEqual(4326, GEOSGeometry(hexewkb_2d).srid)
126 131
 
127  
-    def test01c_kml(self):
  132
+    def test_kml(self):
128 133
         "Testing KML output."
129 134
         for tg in self.geometries.wkt_out:
130 135
             geom = fromstr(tg.wkt)
131 136
             kml = getattr(tg, 'kml', False)
132 137
             if kml: self.assertEqual(kml, geom.kml)
133 138
 
134  
-    def test01d_errors(self):
  139
+    def test_errors(self):
135 140
         "Testing the Error handlers."
136 141
         # string-based
137 142
         print("\nBEGIN - expecting GEOS_ERROR; safe to ignore.\n")
@@ -154,7 +159,7 @@ class NotAGeometry(object):
154 159
         # None
155 160
         self.assertRaises(TypeError, GEOSGeometry, None)
156 161
 
157  
-    def test01e_wkb(self):
  162
+    def test_wkb(self):
158 163
         "Testing WKB output."
159 164
         from binascii import b2a_hex
160 165
         for g in self.geometries.hex_wkt:
@@ -162,7 +167,7 @@ def test01e_wkb(self):
162 167
             wkb = geom.wkb
163 168
             self.assertEqual(b2a_hex(wkb).upper(), g.hex)
164 169
 
165  
-    def test01f_create_hex(self):
  170
+    def test_create_hex(self):
166 171
         "Testing creation from HEX."
167 172
         for g in self.geometries.hex_wkt:
168 173
             geom_h = GEOSGeometry(g.hex)
@@ -170,7 +175,7 @@ def test01f_create_hex(self):
170 175
             geom_t = fromstr(g.wkt)