summaryrefslogtreecommitdiff
path: root/django/contrib/admin
diff options
context:
space:
mode:
authorDerek Anderson <public@kered.org>2006-10-26 19:09:51 +0000
committerDerek Anderson <public@kered.org>2006-10-26 19:09:51 +0000
commit42851d90dadbf62f5d342ce5c4f496ba1eeba987 (patch)
treea5d0e5c178afb2d7dbb7bf5ab37db9ced42f4b52 /django/contrib/admin
parent450889c9a6f7da3c2fce77a0ccf4c4cea9e29710 (diff)
committing to schema-evolution
merge from HEAD git-svn-id: http://code.djangoproject.com/svn/django/branches/schema-evolution@3937 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/contrib/admin')
-rw-r--r--django/contrib/admin/filterspecs.py2
-rw-r--r--django/contrib/admin/media/css/changelists.css4
-rw-r--r--django/contrib/admin/media/css/forms.css4
-rw-r--r--django/contrib/admin/media/css/global.css8
-rw-r--r--django/contrib/admin/media/css/layout.css8
-rw-r--r--django/contrib/admin/media/css/rtl.css2
-rw-r--r--django/contrib/admin/media/js/admin/CollapsedFieldsets.js144
-rw-r--r--django/contrib/admin/media/js/admin/DateTimeShortcuts.js67
-rw-r--r--django/contrib/admin/media/js/admin/RelatedObjectLookups.js2
-rw-r--r--django/contrib/admin/templates/admin/auth/user/add_form.html28
-rw-r--r--django/contrib/admin/templates/admin/base.html9
-rw-r--r--django/contrib/admin/templates/admin/base_site.html2
-rw-r--r--django/contrib/admin/templates/admin/change_form.html6
-rw-r--r--django/contrib/admin/templates/admin/change_list.html4
-rw-r--r--django/contrib/admin/templates/admin/date_hierarchy.html6
-rw-r--r--django/contrib/admin/templates/admin/delete_confirmation.html10
-rw-r--r--django/contrib/admin/templates/admin/edit_inline_stacked.html2
-rw-r--r--django/contrib/admin/templates/admin/edit_inline_tabular.html5
-rw-r--r--django/contrib/admin/templates/admin/filter.html2
-rw-r--r--django/contrib/admin/templates/admin/index.html6
-rw-r--r--django/contrib/admin/templates/admin/invalid_setup.html2
-rw-r--r--django/contrib/admin/templates/admin/login.html22
-rw-r--r--django/contrib/admin/templates/admin/object_history.html2
-rw-r--r--django/contrib/admin/templates/admin/pagination.html2
-rw-r--r--django/contrib/admin/templates/admin_doc/index.html16
-rw-r--r--django/contrib/admin/templates/admin_doc/missing_docutils.html4
-rw-r--r--django/contrib/admin/templates/admin_doc/model_detail.html6
-rw-r--r--django/contrib/admin/templates/admin_doc/template_detail.html10
-rw-r--r--django/contrib/admin/templates/widget/file.html2
-rw-r--r--django/contrib/admin/templates/widget/foreign.html2
-rw-r--r--django/contrib/admin/templates/widget/one_to_one.html2
-rw-r--r--django/contrib/admin/templatetags/admin_list.py11
-rw-r--r--django/contrib/admin/templatetags/admin_modify.py8
-rw-r--r--django/contrib/admin/urls.py4
-rw-r--r--django/contrib/admin/utils.py1
-rw-r--r--django/contrib/admin/views/auth.py44
-rw-r--r--django/contrib/admin/views/decorators.py4
-rw-r--r--django/contrib/admin/views/doc.py48
-rw-r--r--django/contrib/admin/views/main.py21
-rw-r--r--django/contrib/admin/views/template.py4
40 files changed, 320 insertions, 216 deletions
diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py
index 25376be12a..8c2b82147e 100644
--- a/django/contrib/admin/filterspecs.py
+++ b/django/contrib/admin/filterspecs.py
@@ -123,7 +123,7 @@ class DateFieldFilterSpec(FilterSpec):
def choices(self, cl):
for title, param_dict in self.links:
yield {'selected': self.date_params == param_dict,
- 'query_string': cl.get_query_string(param_dict, self.field_generic),
+ 'query_string': cl.get_query_string(param_dict, [self.field_generic]),
'display': title}
FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec)
diff --git a/django/contrib/admin/media/css/changelists.css b/django/contrib/admin/media/css/changelists.css
index fbcbe56f06..4834be4685 100644
--- a/django/contrib/admin/media/css/changelists.css
+++ b/django/contrib/admin/media/css/changelists.css
@@ -42,9 +42,9 @@
/* PAGINATOR */
.paginator { font-size:11px; padding-top:10px; padding-bottom:10px; line-height:22px; margin:0; border-top:1px solid #ddd; }
-.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; }
+.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; }
.paginator a.showall { padding:0 !important; border:none !important; }
.paginator a.showall:hover { color:#036 !important; background:transparent !important; }
-.paginator .end { border-width:2px !important; margin-right:6px; }
+.paginator .end { border-width:2px !important; margin-right:6px; }
.paginator .this-page { padding:2px 6px; font-weight:bold; font-size:13px; vertical-align:top; }
.paginator a:hover { color:white; background:#5b80b2; border-color:#036; }
diff --git a/django/contrib/admin/media/css/forms.css b/django/contrib/admin/media/css/forms.css
index b66f268fec..468e06a8a2 100644
--- a/django/contrib/admin/media/css/forms.css
+++ b/django/contrib/admin/media/css/forms.css
@@ -7,10 +7,10 @@
form .form-row p { padding-left:0; font-size:11px; }
/* FORM LABELS */
-form h4 { margin:0 !important; padding:0 !important; border:none !important; }
+form h4 { margin:0 !important; padding:0 !important; border:none !important; }
label { font-weight:normal !important; color:#666; font-size:12px; }
label.inline { margin-left:20px; }
-.required label, label.required { font-weight:bold !important; color:#333 !important; }
+.required label, label.required { font-weight:bold !important; color:#333 !important; }
/* RADIO BUTTONS */
form ul.radiolist li { list-style-type:none; }
diff --git a/django/contrib/admin/media/css/global.css b/django/contrib/admin/media/css/global.css
index a87931681c..d50601bde7 100644
--- a/django/contrib/admin/media/css/global.css
+++ b/django/contrib/admin/media/css/global.css
@@ -1,4 +1,4 @@
-body { margin:0; padding:0; font-size:12px; font-family:"Lucida Grande","Bitstream Vera Sans",Verdana,Arial,sans-serif; color:#333; background:#fff; }
+body { margin:0; padding:0; font-size:12px; font-family:"Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; color:#333; background:#fff; }
/* LINKS */
a:link, a:visited { color: #5b80b2; text-decoration:none; }
@@ -31,7 +31,7 @@ fieldset { margin:0; padding:0; }
blockquote { font-size:11px; color:#777; margin-left:2px; padding-left:10px; border-left:5px solid #ddd; }
code, pre { font-family:"Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; background:inherit; color:#666; font-size:11px; }
pre.literal-block { margin:10px; background:#eee; padding:6px 8px; }
-code strong { color:#930; }
+code strong { color:#930; }
hr { clear:both; color:#eee; background-color:#eee; height:1px; border:none; margin:0; padding:0; font-size:1px; line-height:1px; }
/* TEXT STYLES & MODIFIERS */
@@ -81,7 +81,7 @@ table.orderable tbody tr td:first-child { padding-left:14px; background-image:ur
table.orderable-initalized .order-cell, body>tr>td.order-cell { display:none; }
/* FORM DEFAULTS */
-input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; }
+input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; }
textarea { vertical-align:top !important; }
input[type=text], input[type=password], textarea, select, .vTextField { border:1px solid #ccc; }
@@ -92,7 +92,7 @@ input[type=submit].default, .submit-row input.default { border:2px solid #5b80b2
input[type=submit].default:active { background-image:url(../img/admin/default-bg-reverse.gif); background-position:top; }
/* MODULES */
-.module { border:1px solid #ccc; margin-bottom:5px; background:white; }
+.module { border:1px solid #ccc; margin-bottom:5px; background:white; }
.module p, .module ul, .module h3, .module h4, .module dl, .module pre { padding-left:10px; padding-right:10px; }
.module blockquote { margin-left:12px; }
.module ul, .module ol { margin-left:1.5em; }
diff --git a/django/contrib/admin/media/css/layout.css b/django/contrib/admin/media/css/layout.css
index befe4fc1ca..17c52861ee 100644
--- a/django/contrib/admin/media/css/layout.css
+++ b/django/contrib/admin/media/css/layout.css
@@ -4,7 +4,7 @@
#header { width:100%; }
#content-main { float:left; width:100%; }
#content-related { float:right; width:18em; position:relative; margin-right:-19em; }
-#footer { clear:both; padding:10px; }
+#footer { clear:both; padding:10px; }
/* COLUMN TYPES */
.colMS { margin-right:20em !important; }
@@ -16,14 +16,14 @@
.dashboard #content { width:500px; }
/* HEADER */
-#header { background:#417690; color:#ffc; overflow:hidden; }
+#header { background:#417690; color:#ffc; overflow:hidden; }
#header a:link, #header a:visited { color:white; }
#header a:hover { text-decoration:underline; }
#branding h1 { padding:0 10px; font-size:18px; margin:8px 0; font-weight:normal; color:#f4f379; }
#branding h2 { padding:0 10px; font-size:14px; margin:-8px 0 8px 0; font-weight:normal; color:#ffc; }
-#user-tools { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:11px; text-align:right; }
+#user-tools { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:11px; text-align:right; }
/* SIDEBAR */
#content-related h3 { font-size:12px; color:#666; margin-bottom:3px; }
#content-related h4 { font-size:11px; }
-#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } \ No newline at end of file
+#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } \ No newline at end of file
diff --git a/django/contrib/admin/media/css/rtl.css b/django/contrib/admin/media/css/rtl.css
index c29391cabf..1974e7c2ec 100644
--- a/django/contrib/admin/media/css/rtl.css
+++ b/django/contrib/admin/media/css/rtl.css
@@ -16,7 +16,7 @@ th { text-align: right; }
/* layout styles */
-#user-tools { right:auto; left:0; text-align:left; }
+#user-tools { right:auto; left:0; text-align:left; }
div.breadcrumbs { text-align:right; }
#content-main { float:right;}
#content-related { float:left; margin-left:-19em; margin-right:auto;}
diff --git a/django/contrib/admin/media/js/admin/CollapsedFieldsets.js b/django/contrib/admin/media/js/admin/CollapsedFieldsets.js
index 97f0a68d04..c8426db228 100644
--- a/django/contrib/admin/media/js/admin/CollapsedFieldsets.js
+++ b/django/contrib/admin/media/js/admin/CollapsedFieldsets.js
@@ -3,83 +3,83 @@
// link when the fieldset is visible.
function findForm(node) {
- // returns the node of the form containing the given node
- if (node.tagName.toLowerCase() != 'form') {
- return findForm(node.parentNode);
- }
- return node;
+ // returns the node of the form containing the given node
+ if (node.tagName.toLowerCase() != 'form') {
+ return findForm(node.parentNode);
+ }
+ return node;
}
var CollapsedFieldsets = {
- collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with.
- collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden.
- collapsed_class: 'collapsed',
- init: function() {
- var fieldsets = document.getElementsByTagName('fieldset');
- var collapsed_seen = false;
- for (var i = 0, fs; fs = fieldsets[i]; i++) {
- // Collapse this fieldset if it has the correct class, and if it
- // doesn't have any errors. (Collapsing shouldn't apply in the case
- // of error messages.)
- if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) {
- collapsed_seen = true;
- // Give it an additional class, used by CSS to hide it.
- fs.className += ' ' + CollapsedFieldsets.collapsed_class;
- // (<a id="fieldsetcollapser3" class="collapse-toggle" href="#">Show</a>)
- var collapse_link = document.createElement('a');
- collapse_link.className = 'collapse-toggle';
- collapse_link.id = 'fieldsetcollapser' + i;
- collapse_link.onclick = new Function('CollapsedFieldsets.show('+i+'); return false;');
- collapse_link.href = '#';
- collapse_link.innerHTML = gettext('Show');
- var h2 = fs.getElementsByTagName('h2')[0];
- h2.appendChild(document.createTextNode(' ('));
- h2.appendChild(collapse_link);
- h2.appendChild(document.createTextNode(')'));
- }
- }
- if (collapsed_seen) {
- // Expand all collapsed fieldsets when form is submitted.
- addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); });
- }
- },
- fieldset_has_errors: function(fs) {
- // Returns true if any fields in the fieldset have validation errors.
- var divs = fs.getElementsByTagName('div');
- for (var i=0; i<divs.length; i++) {
- if (divs[i].className.match(/\berror\b/)) {
- return true;
- }
- }
- return false;
- },
- show: function(fieldset_index) {
- var fs = document.getElementsByTagName('fieldset')[fieldset_index];
- // Remove the class name that causes the "display: none".
- fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, '');
- // Toggle the "Show" link to a "Hide" link
- var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
- collapse_link.onclick = new Function('CollapsedFieldsets.hide('+fieldset_index+'); return false;');
- collapse_link.innerHTML = gettext('Hide');
- },
- hide: function(fieldset_index) {
- var fs = document.getElementsByTagName('fieldset')[fieldset_index];
- // Add the class name that causes the "display: none".
- fs.className += ' ' + CollapsedFieldsets.collapsed_class;
- // Toggle the "Hide" link to a "Show" link
- var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
+ collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with.
+ collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden.
+ collapsed_class: 'collapsed',
+ init: function() {
+ var fieldsets = document.getElementsByTagName('fieldset');
+ var collapsed_seen = false;
+ for (var i = 0, fs; fs = fieldsets[i]; i++) {
+ // Collapse this fieldset if it has the correct class, and if it
+ // doesn't have any errors. (Collapsing shouldn't apply in the case
+ // of error messages.)
+ if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) {
+ collapsed_seen = true;
+ // Give it an additional class, used by CSS to hide it.
+ fs.className += ' ' + CollapsedFieldsets.collapsed_class;
+ // (<a id="fieldsetcollapser3" class="collapse-toggle" href="#">Show</a>)
+ var collapse_link = document.createElement('a');
+ collapse_link.className = 'collapse-toggle';
+ collapse_link.id = 'fieldsetcollapser' + i;
+ collapse_link.onclick = new Function('CollapsedFieldsets.show('+i+'); return false;');
+ collapse_link.href = '#';
+ collapse_link.innerHTML = gettext('Show');
+ var h2 = fs.getElementsByTagName('h2')[0];
+ h2.appendChild(document.createTextNode(' ('));
+ h2.appendChild(collapse_link);
+ h2.appendChild(document.createTextNode(')'));
+ }
+ }
+ if (collapsed_seen) {
+ // Expand all collapsed fieldsets when form is submitted.
+ addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); });
+ }
+ },
+ fieldset_has_errors: function(fs) {
+ // Returns true if any fields in the fieldset have validation errors.
+ var divs = fs.getElementsByTagName('div');
+ for (var i=0; i<divs.length; i++) {
+ if (divs[i].className.match(/\berror\b/)) {
+ return true;
+ }
+ }
+ return false;
+ },
+ show: function(fieldset_index) {
+ var fs = document.getElementsByTagName('fieldset')[fieldset_index];
+ // Remove the class name that causes the "display: none".
+ fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, '');
+ // Toggle the "Show" link to a "Hide" link
+ var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
+ collapse_link.onclick = new Function('CollapsedFieldsets.hide('+fieldset_index+'); return false;');
+ collapse_link.innerHTML = gettext('Hide');
+ },
+ hide: function(fieldset_index) {
+ var fs = document.getElementsByTagName('fieldset')[fieldset_index];
+ // Add the class name that causes the "display: none".
+ fs.className += ' ' + CollapsedFieldsets.collapsed_class;
+ // Toggle the "Hide" link to a "Show" link
+ var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
collapse_link.onclick = new Function('CollapsedFieldsets.show('+fieldset_index+'); return false;');
- collapse_link.innerHTML = gettext('Show');
- },
+ collapse_link.innerHTML = gettext('Show');
+ },
- uncollapse_all: function() {
- var fieldsets = document.getElementsByTagName('fieldset');
- for (var i=0; i<fieldsets.length; i++) {
- if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) {
- CollapsedFieldsets.show(i);
- }
- }
- }
+ uncollapse_all: function() {
+ var fieldsets = document.getElementsByTagName('fieldset');
+ for (var i=0; i<fieldsets.length; i++) {
+ if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) {
+ CollapsedFieldsets.show(i);
+ }
+ }
+ }
}
addEvent(window, 'load', CollapsedFieldsets.init);
diff --git a/django/contrib/admin/media/js/admin/DateTimeShortcuts.js b/django/contrib/admin/media/js/admin/DateTimeShortcuts.js
index 35199baf84..77c536b865 100644
--- a/django/contrib/admin/media/js/admin/DateTimeShortcuts.js
+++ b/django/contrib/admin/media/js/admin/DateTimeShortcuts.js
@@ -8,7 +8,9 @@ var DateTimeShortcuts = {
clockInputs: [],
calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
calendarDivName2: 'calendarin', // name of <div> that contains calendar
+ calendarLinkName: 'calendarlink',// name of the link that is used to toggle
clockDivName: 'clockbox', // name of clock <div> that gets toggled
+ clockLinkName: 'clocklink', // name of the link that is used to toggle
admin_media_prefix: '',
init: function() {
// Deduce admin_media_prefix by looking at the <script>s in the
@@ -46,6 +48,7 @@ var DateTimeShortcuts = {
now_link.appendChild(document.createTextNode(gettext('Now')));
var clock_link = document.createElement('a');
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');');
+ clock_link.id = DateTimeShortcuts.clockLinkName + num;
quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_clock.gif', 'alt', gettext('Clock'));
shortcuts_span.appendChild(document.createTextNode('\240'));
shortcuts_span.appendChild(now_link);
@@ -69,17 +72,6 @@ var DateTimeShortcuts = {
var clock_box = document.createElement('div');
clock_box.style.display = 'none';
clock_box.style.position = 'absolute';
- if (getStyle(document.body,'direction')!='rtl') {
- clock_box.style.left = findPosX(clock_link) + 17 + 'px';
- }
- else {
- // since style's width is in em, it'd be tough to calculate
- // px value of it. let's use an estimated px for now
- // TODO: IE returns wrong value for findPosX when in rtl mode
- // (it returns as it was left aligned), needs to be fixed.
- clock_box.style.left = findPosX(clock_link) - 110 + 'px';
- }
- clock_box.style.top = findPosY(clock_link) - 30 + 'px';
clock_box.className = 'clockbox module';
clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num);
document.body.appendChild(clock_box);
@@ -98,7 +90,25 @@ var DateTimeShortcuts = {
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');');
},
openClock: function(num) {
- document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'block';
+ var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num)
+ var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName+num)
+
+ // Recalculate the clockbox position
+ // is it left-to-right or right-to-left layout ?
+ if (getStyle(document.body,'direction')!='rtl') {
+ clock_box.style.left = findPosX(clock_link) + 17 + 'px';
+ }
+ else {
+ // since style's width is in em, it'd be tough to calculate
+ // px value of it. let's use an estimated px for now
+ // TODO: IE returns wrong value for findPosX when in rtl mode
+ // (it returns as it was left aligned), needs to be fixed.
+ clock_box.style.left = findPosX(clock_link) - 110 + 'px';
+ }
+ clock_box.style.top = findPosY(clock_link) - 30 + 'px';
+
+ // Show the clock box
+ clock_box.style.display = 'block';
addEvent(window, 'click', function() { DateTimeShortcuts.dismissClock(num); return true; });
},
dismissClock: function(num) {
@@ -123,6 +133,7 @@ var DateTimeShortcuts = {
today_link.appendChild(document.createTextNode(gettext('Today')));
var cal_link = document.createElement('a');
cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');');
+ cal_link.id = DateTimeShortcuts.calendarLinkName + num;
quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_calendar.gif', 'alt', gettext('Calendar'));
shortcuts_span.appendChild(document.createTextNode('\240'));
shortcuts_span.appendChild(today_link);
@@ -149,18 +160,6 @@ var DateTimeShortcuts = {
var cal_box = document.createElement('div');
cal_box.style.display = 'none';
cal_box.style.position = 'absolute';
- // is it left-to-right or right-to-left layout ?
- if (getStyle(document.body,'direction')!='rtl') {
- cal_box.style.left = findPosX(cal_link) + 17 + 'px';
- }
- else {
- // since style's width is in em, it'd be tough to calculate
- // px value of it. let's use an estimated px for now
- // TODO: IE returns wrong value for findPosX when in rtl mode
- // (it returns as it was left aligned), needs to be fixed.
- cal_box.style.left = findPosX(cal_link) - 180 + 'px';
- }
- cal_box.style.top = findPosY(cal_link) - 75 + 'px';
cal_box.className = 'calendarbox module';
cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num);
document.body.appendChild(cal_box);
@@ -172,7 +171,6 @@ var DateTimeShortcuts = {
cal_nav_prev.className = 'calendarnav-previous';
var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext('+num+');');
cal_nav_next.className = 'calendarnav-next';
- cal_box.appendChild(cal_nav);
// main box
var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
@@ -195,7 +193,24 @@ var DateTimeShortcuts = {
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
},
openCalendar: function(num) {
- document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'block';
+ var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
+ var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
+
+ // Recalculate the clockbox position
+ // is it left-to-right or right-to-left layout ?
+ if (getStyle(document.body,'direction')!='rtl') {
+ cal_box.style.left = findPosX(cal_link) + 17 + 'px';
+ }
+ else {
+ // since style's width is in em, it'd be tough to calculate
+ // px value of it. let's use an estimated px for now
+ // TODO: IE returns wrong value for findPosX when in rtl mode
+ // (it returns as it was left aligned), needs to be fixed.
+ cal_box.style.left = findPosX(cal_link) - 180 + 'px';
+ }
+ cal_box.style.top = findPosY(cal_link) - 75 + 'px';
+
+ cal_box.style.display = 'block';
addEvent(window, 'click', function() { DateTimeShortcuts.dismissCalendar(num); return true; });
},
dismissCalendar: function(num) {
diff --git a/django/contrib/admin/media/js/admin/RelatedObjectLookups.js b/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
index cf57fc4dfb..db4ed1a9d1 100644
--- a/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
+++ b/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
@@ -11,7 +11,7 @@ function showRelatedObjectLookupPopup(triggeringLink) {
} else {
href = triggeringLink.href + '?pop=1';
}
- var win = window.open(href, name, 'height=500,width=740,resizable=yes,scrollbars=yes');
+ var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
return false;
}
diff --git a/django/contrib/admin/templates/admin/auth/user/add_form.html b/django/contrib/admin/templates/admin/auth/user/add_form.html
new file mode 100644
index 0000000000..139fa6a75e
--- /dev/null
+++ b/django/contrib/admin/templates/admin/auth/user/add_form.html
@@ -0,0 +1,28 @@
+{% extends "admin/change_form.html" %}
+{% load i18n %}
+
+{% block after_field_sets %}
+
+<p>{% trans "First, enter a username and password. Then, you'll be able to edit more user options." %}</p>
+
+<fieldset class="module aligned">
+
+<div class="form-row">
+ {{ form.username.html_error_list }}
+ <label for="id_username" class="required">{% trans 'Username' %}:</label> {{ form.username }}
+ <p class="help">{{ username_help_text }}</p>
+</div>
+
+<div class="form-row">
+ {{ form.password1.html_error_list }}
+ <label for="id_password1" class="required">{% trans 'Password' %}:</label> {{ form.password1 }}
+</div>
+
+<div class="form-row">
+ {{ form.password2.html_error_list }}
+ <label for="id_password2" class="required">{% trans 'Password (again)' %}:</label> {{ form.password2 }}
+ <p class="help">{% trans 'Enter the same password as above, for verification.' %}</p>
+</div>
+
+</fieldset>
+{% endblock %}
diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html
index 67fe27529c..b63604b268 100644
--- a/django/contrib/admin/templates/admin/base.html
+++ b/django/contrib/admin/templates/admin/base.html
@@ -6,6 +6,7 @@
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% admin_media_prefix %}css/rtl.css{% endblock %}" />{% endif %}
{% block extrastyle %}{% endblock %}
{% block extrahead %}{% endblock %}
+{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
</head>
{% load i18n %}
@@ -20,13 +21,13 @@
<div id="branding">
{% block branding %}{% endblock %}
</div>
- {% if not user.is_anonymous %}{% if user.is_staff %}
+ {% if user.is_authenticated and user.is_staff %}
<div id="user-tools">{% trans 'Welcome,' %} <strong>{% if user.first_name %}{{ user.first_name|escape }}{% else %}{{ user.username }}{% endif %}</strong>. {% block userlinks %}<a href="doc/">{% trans 'Documentation' %}</a> / <a href="password_change/">{% trans 'Change password' %}</a> / <a href="logout/">{% trans 'Log out' %}</a>{% endblock %}</div>
- {% endif %}{% endif %}
+ {% endif %}
{% block nav-global %}{% endblock %}
</div>
<!-- END Header -->
- {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} &rsaquo; {{ title }}{% endif %}</div>{% endblock %}
+ {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} &rsaquo; {{ title|escape }}{% endif %}</div>{% endblock %}
{% endif %}
{% if messages %}
@@ -36,7 +37,7 @@
<!-- Content -->
<div id="content" class="{% block coltype %}colM{% endblock %}">
{% block pretitle %}{% endblock %}
- {% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
+ {% block content_title %}{% if title %}<h1>{{ title|escape }}</h1>{% endif %}{% endblock %}
{% block content %}{{ content }}{% endblock %}
{% block sidebar %}{% endblock %}
<br class="clear" />
diff --git a/django/contrib/admin/templates/admin/base_site.html b/django/contrib/admin/templates/admin/base_site.html
index b867bd29bd..2bc7310873 100644
--- a/django/contrib/admin/templates/admin/base_site.html
+++ b/django/contrib/admin/templates/admin/base_site.html
@@ -1,7 +1,7 @@
{% extends "admin/base.html" %}
{% load i18n %}
-{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
+{% block title %}{{ title|escape }} | {% trans 'Django site admin' %}{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans 'Django administration' %}</h1>
diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
index fa04969f01..b1fdc5ebdb 100644
--- a/django/contrib/admin/templates/admin/change_form.html
+++ b/django/contrib/admin/templates/admin/change_form.html
@@ -11,8 +11,8 @@
{% block breadcrumbs %}{% if not is_popup %}
<div class="breadcrumbs">
<a href="../../../">{% trans "Home" %}</a> &rsaquo;
- <a href="../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
- {% if add %}{% trans "Add" %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18"|escape }}{% endif %}
+ <a href="../">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
+ {% if add %}{% trans "Add" %} {{ opts.verbose_name|escape }}{% else %}{{ original|truncatewords:"18"|escape }}{% endif %}
</div>
{% endif %}{% endblock %}
{% block content %}<div id="content-main">
@@ -21,7 +21,7 @@
{% if has_absolute_url %}<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
</ul>
{% endif %}{% endif %}
-<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post">{% block form_top %}{% endblock %}
+<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}
{% if opts.admin.save_on_top %}{% submit_row %}{% endif %}
diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html
index 5b54bfb8cc..bd2304bd52 100644
--- a/django/contrib/admin/templates/admin/change_list.html
+++ b/django/contrib/admin/templates/admin/change_list.html
@@ -3,12 +3,12 @@
{% block stylesheet %}{% admin_media_prefix %}css/changelists.css{% endblock %}
{% block bodyclass %}change-list{% endblock %}
{% block userlinks %}<a href="../../doc/">{% trans 'Documentation' %}</a> / <a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
-{% if not is_popup %}{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> &rsaquo; {{ cl.opts.verbose_name_plural|capfirst }}</div>{% endblock %}{% endif %}
+{% if not is_popup %}{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> &rsaquo; {{ cl.opts.verbose_name_plural|capfirst|escape }}</div>{% endblock %}{% endif %}
{% block coltype %}flex{% endblock %}
{% block content %}
<div id="content-main">
{% if has_add_permission %}
-<ul class="object-tools"><li><a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}</a></li></ul>
+<ul class="object-tools"><li><a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">{% blocktrans with cl.opts.verbose_name|escape as name %}Add {{ name }}{% endblocktrans %}</a></li></ul>
{% endif %}
<div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
{% block search %}{% search_form cl %}{% endblock %}
diff --git a/django/contrib/admin/templates/admin/date_hierarchy.html b/django/contrib/admin/templates/admin/date_hierarchy.html
index a53d810f93..d2d69616c7 100644
--- a/django/contrib/admin/templates/admin/date_hierarchy.html
+++ b/django/contrib/admin/templates/admin/date_hierarchy.html
@@ -1,10 +1,10 @@
{% if show %}
<div class="xfull">
<ul class="toplinks">
-{% if back %}<li class="date-back"><a href="{{ back.link }}">&lsaquo; {{ back.title }}</a></li>{% endif %}
+{% if back %}<li class="date-back"><a href="{{ back.link }}">&lsaquo; {{ back.title|escape }}</a></li>{% endif %}
{% for choice in choices %}
-<li> {% if choice.link %}<a href="{{ choice.link }}">{% endif %}{{ choice.title }}{% if choice.link %}</a>{% endif %}</li>
+<li> {% if choice.link %}<a href="{{ choice.link }}">{% endif %}{{ choice.title|escape }}{% if choice.link %}</a>{% endif %}</li>
{% endfor %}
</ul><br class="clear" />
</div>
-{% endif %} \ No newline at end of file
+{% endif %}
diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html
index f907c18a16..3921ab69e3 100644
--- a/django/contrib/admin/templates/admin/delete_confirmation.html
+++ b/django/contrib/admin/templates/admin/delete_confirmation.html
@@ -4,21 +4,21 @@
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="../../../../">{% trans "Home" %}</a> &rsaquo;
- <a href="../../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
- <a href="../">{{ object|striptags|truncatewords:"18" }}</a> &rsaquo;
+ <a href="../../">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
+ <a href="../">{{ object|escape|truncatewords:"18" }}</a> &rsaquo;
{% trans 'Delete' %}
</div>
{% endblock %}
{% block content %}
{% if perms_lacking %}
- <p>{% blocktrans %}Deleting the {{ object_name }} '{{ object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
+ <p>{% blocktrans with object|escape as escaped_object %}Deleting the {{ object_name }} '{{ escaped_object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
<ul>
{% for obj in perms_lacking %}
- <li>{{ obj }}</li>
+ <li>{{ obj|escape }}</li>
{% endfor %}
</ul>
{% else %}
- <p>{% blocktrans %}Are you sure you want to delete the {{ object_name }} "{{ object }}"? All of the following related items will be deleted:{% endblocktrans %}</p>
+ <p>{% blocktrans with object|escape as escaped_object %}Are you sure you want to delete the {{ object_name }} "{{ escaped_object }}"? All of the following related items will be deleted:{% endblocktrans %}</p>
<ul>{{ deleted_objects|unordered_list }}</ul>
<form action="" method="post">
<div>
diff --git a/django/contrib/admin/templates/admin/edit_inline_stacked.html b/django/contrib/admin/templates/admin/edit_inline_stacked.html
index 45aa0a4f58..48ecc698d9 100644
--- a/django/contrib/admin/templates/admin/edit_inline_stacked.html
+++ b/django/contrib/admin/templates/admin/edit_inline_stacked.html
@@ -1,7 +1,7 @@
{% load admin_modify %}
<fieldset class="module aligned">
{% for fcw in bound_related_object.form_field_collection_wrappers %}
- <h2>{{ bound_related_object.relation.opts.verbose_name|capfirst }}&nbsp;#{{ forloop.counter }}</h2>
+ <h2>{{ bound_related_object.relation.opts.verbose_name|capfirst|escape }}&nbsp;#{{ forloop.counter }}</h2>
{% if bound_related_object.show_url %}{% if fcw.obj.original %}
<p><a href="/r/{{ fcw.obj.original.content_type_id }}/{{ fcw.obj.original.id }}/">View on site</a></p>
{% endif %}{% endif %}
diff --git a/django/contrib/admin/templates/admin/edit_inline_tabular.html b/django/contrib/admin/templates/admin/edit_inline_tabular.html
index e9535df02c..3d059c8b3d 100644
--- a/django/contrib/admin/templates/admin/edit_inline_tabular.html
+++ b/django/contrib/admin/templates/admin/edit_inline_tabular.html
@@ -1,12 +1,13 @@
{% load admin_modify %}
<fieldset class="module">
- <h2>{{ bound_related_object.relation.opts.verbose_name_plural|capfirst }}</h2><table>
+ <h2>{{ bound_related_object.relation.opts.verbose_name_plural|capfirst|escape }}</h2><table>
<thead><tr>
{% for fw in bound_related_object.field_wrapper_list %}
{% if fw.needs_header %}
- <th{{ fw.header_class_attribute }}>{{ fw.field.verbose_name|capfirst }}</th>
+ <th{{ fw.header_class_attribute }}>{{ fw.field.verbose_name|capfirst|escape }}</th>
{% endif %}
{% endfor %}
+ </tr></thead>
{% for fcw in bound_related_object.form_field_collection_wrappers %}
{% if change %}{% if original_row_needed %}
{% if fcw.obj.original %}
diff --git a/django/contrib/admin/templates/admin/filter.html b/django/contrib/admin/templates/admin/filter.html
index 5b0e78b6fc..8b5b521437 100644
--- a/django/contrib/admin/templates/admin/filter.html
+++ b/django/contrib/admin/templates/admin/filter.html
@@ -1,5 +1,5 @@
{% load i18n %}
-<h3>{% blocktrans %} By {{ title }} {% endblocktrans %}</h3>
+<h3>{% blocktrans with title|escape as filter_title %} By {{ filter_title }} {% endblocktrans %}</h3>
<ul>
{% for choice in choices %}
<li{% if choice.selected %} class="selected"{% endif %}>
diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html
index f7b121723a..aa63c14fce 100644
--- a/django/contrib/admin/templates/admin/index.html
+++ b/django/contrib/admin/templates/admin/index.html
@@ -19,9 +19,9 @@
{% for model in app.models %}
<tr>
{% if model.perms.change %}
- <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
+ <th scope="row"><a href="{{ model.admin_url }}">{{ model.name|escape }}</a></th>
{% else %}
- <th scope="row">{{ model.name }}</th>
+ <th scope="row">{{ model.name|escape }}</th>
{% endif %}
{% if model.perms.add %}
@@ -58,7 +58,7 @@
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
- <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr|escape }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{{ entry.content_type.name|capfirst }}</span></li>
+ <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr|escape }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{{ entry.content_type.name|capfirst|escape }}</span></li>
{% endfor %}
</ul>
{% endif %}
diff --git a/django/contrib/admin/templates/admin/invalid_setup.html b/django/contrib/admin/templates/admin/invalid_setup.html
index 1fa0d32358..1d7d61f0d2 100644
--- a/django/contrib/admin/templates/admin/invalid_setup.html
+++ b/django/contrib/admin/templates/admin/invalid_setup.html
@@ -1,7 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {{ title }}</div>{% endblock %}
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {{ title|escape }}</div>{% endblock %}
{% block content %}
diff --git a/django/contrib/admin/templates/admin/login.html b/django/contrib/admin/templates/admin/login.html
index 5f338f703e..0773132cec 100644
--- a/django/contrib/admin/templates/admin/login.html
+++ b/django/contrib/admin/templates/admin/login.html
@@ -13,17 +13,17 @@
{% endif %}
<div id="content-main">
<form action="{{ app_path }}" method="post" id="login-form">
- <div class="form-row">
- <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" />
- </div>
- <div class="form-row">
- <label for="id_password">{% trans 'Password:' %}</label> <input type="password" name="password" id="id_password" />
- <input type="hidden" name="this_is_the_login_form" value="1" />
- <input type="hidden" name="post_data" value="{{ post_data }}" /> {% comment %}<span class="help">{% trans 'Have you <a href="/password_reset/">forgotten your password</a>?' %}</span>{% endcomment %}
- </div>
- <div class="submit-row">
- <label>&nbsp;</label><input type="submit" value="{% trans 'Log in' %}" />
- </div>
+ <div class="form-row">
+ <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" />
+ </div>
+ <div class="form-row">
+ <label for="id_password">{% trans 'Password:' %}</label> <input type="password" name="password" id="id_password" />
+ <input type="hidden" name="this_is_the_login_form" value="1" />
+ <input type="hidden" name="post_data" value="{{ post_data }}" /> {#<span class="help">{% trans 'Have you <a href="/password_reset/">forgotten your password</a>?' %}</span>#}
+ </div>
+ <div class="submit-row">
+ <label>&nbsp;</label><input type="submit" value="{% trans 'Log in' %}" />
+ </div>
</form>
<script type="text/javascript">
diff --git a/django/contrib/admin/templates/admin/object_history.html b/django/contrib/admin/templates/admin/object_history.html
index fc568305ca..14a77b8a31 100644
--- a/django/contrib/admin/templates/admin/object_history.html
+++ b/django/contrib/admin/templates/admin/object_history.html
@@ -2,7 +2,7 @@
{% load i18n %}
{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
{% block breadcrumbs %}
-<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> &rsaquo; <a href="../../">{{ module_name }}</a> &rsaquo; <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo; {% trans 'History' %}</div>
+<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> &rsaquo; <a href="../../">{{ module_name|escape }}</a> &rsaquo; <a href="../">{{ object|escape|truncatewords:"18" }}</a> &rsaquo; {% trans 'History' %}</div>
{% endblock %}
{% block content %}
diff --git a/django/contrib/admin/templates/admin/pagination.html b/django/contrib/admin/templates/admin/pagination.html
index 7694e4c5b0..e1c09b2932 100644
--- a/django/contrib/admin/templates/admin/pagination.html
+++ b/django/contrib/admin/templates/admin/pagination.html
@@ -6,6 +6,6 @@
{% paginator_number cl i %}
{% endfor %}
{% endif %}
-{{ cl.result_count }} {% ifequal cl.result_count 1 %}{{ cl.opts.verbose_name }}{% else %}{{ cl.opts.verbose_name_plural }}{% endifequal %}
+{{ cl.result_count }} {% ifequal cl.result_count 1 %}{{ cl.opts.verbose_name|escape }}{% else %}{{ cl.opts.verbose_name_plural|escape }}{% endifequal %}
{% if show_all_url %}&nbsp;&nbsp;<a href="{{ show_all_url }}" class="showall">{% trans 'Show all' %}</a>{% endif %}
</p>
diff --git a/django/contrib/admin/templates/admin_doc/index.html b/django/contrib/admin/templates/admin_doc/index.html
index 331774d2b3..74f9f20916 100644
--- a/django/contrib/admin/templates/admin_doc/index.html
+++ b/django/contrib/admin/templates/admin_doc/index.html
@@ -9,17 +9,17 @@
<h1>Documentation</h1>
<div id="content-main">
- <h3><a href="tags/">Tags</a></h3>
- <p>List of all the template tags and their functions.</p>
+ <h3><a href="tags/">Tags</a></h3>
+ <p>List of all the template tags and their functions.</p>
- <h3><a href="filters/">Filters</a></h3>
- <p>Filters are actions which can be applied to variables in a template to alter the output.</p>
+ <h3><a href="filters/">Filters</a></h3>
+ <p>Filters are actions which can be applied to variables in a template to alter the output.</p>
- <h3><a href="models/">Models</a></h3>
- <p>Models are descriptions of all the objects in the system and their associated fields. Each model has a list of fields which can be accessed as template variables.</p>
+ <h3><a href="models/">Models</a></h3>
+ <p>Models are descriptions of all the objects in the system and their associated fields. Each model has a list of fields which can be accessed as template variables.</p>
- <h3><a href="views/">Views</a></h3>
- <p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
+ <h3><a href="views/">Views</a></h3>
+ <p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
<h3><a href="bookmarklets/">Bookmarklets</a></h3>
<p>Tools for your browser to quickly access admin functionality.</p>
diff --git a/django/contrib/admin/templates/admin_doc/missing_docutils.html b/django/contrib/admin/templates/admin_doc/missing_docutils.html
index d0b571f957..cdeab0cdd8 100644
--- a/django/contrib/admin/templates/admin_doc/missing_docutils.html
+++ b/django/contrib/admin/templates/admin_doc/missing_docutils.html
@@ -9,9 +9,9 @@
<h1>Documentation</h1>
<div id="content-main">
- <h3>The admin documentation system requires Python's <a href="http://docutils.sf.net/">docutils</a> library.</h3>
+ <h3>The admin documentation system requires Python's <a href="http://docutils.sf.net/">docutils</a> library.</h3>
- <p>Please ask your administrators to install <a href="http://docutils.sf.net/">docutils</a>.</p>
+ <p>Please ask your administrators to install <a href="http://docutils.sf.net/">docutils</a>.</p>
</div>
{% endblock %}
diff --git a/django/contrib/admin/templates/admin_doc/model_detail.html b/django/contrib/admin/templates/admin_doc/model_detail.html
index 9ac56864fa..70133e26dd 100644
--- a/django/contrib/admin/templates/admin_doc/model_detail.html
+++ b/django/contrib/admin/templates/admin_doc/model_detail.html
@@ -9,13 +9,13 @@
</style>
{% endblock %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Models</a> &rsaquo; {{ name }}</div>{% endblock %}
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Models</a> &rsaquo; {{ name|escape }}</div>{% endblock %}
-{% block title %}Model: {{ name }}{% endblock %}
+{% block title %}Model: {{ name|escape }}{% endblock %}
{% block content %}
<div id="content-main">
-<h1>{{ summary }}</h1>
+<h1>{{ summary|escape }}</h1>
{% if description %}
<p>{% filter escape|linebreaksbr %}{% trans description %}{% endfilter %}</p>
diff --git a/django/contrib/admin/templates/admin_doc/template_detail.html b/django/contrib/admin/templates/admin_doc/template_detail.html
index df67f1856b..280ea912d0 100644
--- a/django/contrib/admin/templates/admin_doc/template_detail.html
+++ b/django/contrib/admin/templates/admin_doc/template_detail.html
@@ -1,19 +1,19 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; Templates &rsaquo; {{ name }}</div>{% endblock %}
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; Templates &rsaquo; {{ name|escape }}</div>{% endblock %}
{% block userlinks %}<a href="../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
-{% block title %}Template: {{ name }}{% endblock %}
+{% block title %}Template: {{ name|escape }}{% endblock %}
{% block content %}
-<h1>Template: "{{ name }}"</h1>
+<h1>Template: "{{ name|escape }}"</h1>
{% regroup templates|dictsort:"site_id" by site as templates_by_site %}
{% for group in templates_by_site %}
- <h2>Search path for template "{{ name }}" on {{ group.grouper }}:</h2>
+ <h2>Search path for template "{{ name|escape }}" on {{ group.grouper }}:</h2>
<ol>
{% for template in group.list|dictsort:"order" %}
- <li><code>{{ template.file }}</code>{% if not template.exists %} <em>(does not exist)</em>{% endif %}</li>
+ <li><code>{{ template.file|escape }}</code>{% if not template.exists %} <em>(does not exist)</em>{% endif %}</li>
{% endfor %}
</ol>
{% endfor %}
diff --git a/django/contrib/admin/templates/widget/file.html b/django/contrib/admin/templates/widget/file.html
index e4a0756211..e584abf956 100644
--- a/django/contrib/admin/templates/widget/file.html
+++ b/django/contrib/admin/templates/widget/file.html
@@ -1,4 +1,4 @@
{% load admin_modify i18n %}{% if bound_field.original_value %}
-{% trans "Currently:" %} <a href="{{ bound_field.original_url }}" > {{ bound_field.original_value }} </a><br />
+{% trans "Currently:" %} <a href="{{ bound_field.original_url }}" > {{ bound_field.original_value|escape }} </a><br />
{% trans "Change:" %}{% output_all bound_field.form_fields %}
{% else %} {% output_all bound_field.form_fields %} {% endif %}
diff --git a/django/contrib/admin/templates/widget/foreign.html b/django/contrib/admin/templates/widget/foreign.html
index 6b43d044bd..301f5214db 100644
--- a/django/contrib/admin/templates/widget/foreign.html
+++ b/django/contrib/admin/templates/widget/foreign.html
@@ -15,6 +15,6 @@
{{ bound_field.original_value }}
{% endif %}
{% if bound_field.raw_id_admin %}
- {% if bound_field.existing_display %}&nbsp;<strong>{{ bound_field.existing_display|truncatewords:"14" }}</strong>{% endif %}
+ {% if bound_field.existing_display %}&nbsp;<strong>{{ bound_field.existing_display|truncatewords:"14"|escape }}</strong>{% endif %}
{% endif %}
{% endif %}
diff --git a/django/contrib/admin/templates/widget/one_to_one.html b/django/contrib/admin/templates/widget/one_to_one.html
index a79a12314f..efd0117bf2 100644
--- a/django/contrib/admin/templates/widget/one_to_one.html
+++ b/django/contrib/admin/templates/widget/one_to_one.html
@@ -1,2 +1,2 @@
{% if add %}{% include "widget/foreign.html" %}{% endif %}
-{% if change %}{% if bound_field.existing_display %}&nbsp;<strong>{{ bound_field.existing_display|truncatewords:"14" }}</strong>{% endif %}{% endif %}
+{% if change %}{% if bound_field.existing_display %}&nbsp;<strong>{{ bound_field.existing_display|truncatewords:"14"|escape }}</strong>{% endif %}{% endif %}
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index 3537f46755..832b3562cd 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -1,8 +1,6 @@
-from django import template
from django.conf import settings
-from django.contrib.admin.views.main import MAX_SHOW_ALL_ALLOWED, ALL_VAR
+from django.contrib.admin.views.main import ALL_VAR, EMPTY_CHANGELIST_VALUE
from django.contrib.admin.views.main import ORDER_VAR, ORDER_TYPE_VAR, PAGE_VAR, SEARCH_VAR
-from django.contrib.admin.views.main import IS_POPUP_VAR, EMPTY_CHANGELIST_VALUE
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.utils import dateformat
@@ -119,7 +117,7 @@ def items_for_result(cl, result):
if callable(attr):
attr = attr()
result_repr = str(attr)
- except AttributeError, ObjectDoesNotExist:
+ except (AttributeError, ObjectDoesNotExist):
result_repr = EMPTY_CHANGELIST_VALUE
else:
# Strip HTML tags in the resulting text, except if the
@@ -167,11 +165,12 @@ def items_for_result(cl, result):
result_repr = '&nbsp;'
# If list_display_links not defined, add the link tag to the first field
if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links:
+ table_tag = {True:'th', False:'td'}[first]
first = False
url = cl.url_for_result(result)
result_id = str(getattr(result, pk)) # str() is needed in case of 23L (long ints)
- yield ('<th%s><a href="%s"%s>%s</a></th>' % \
- (row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %r); return false;"' % result_id or ''), result_repr))
+ yield ('<%s%s><a href="%s"%s>%s</a></%s>' % \
+ (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %r); return false;"' % result_id or ''), result_repr, table_tag))
else:
yield ('<td%s>%s</td>' % (row_class, result_repr))
diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py
index 2d34452f52..d09fa28b10 100644
--- a/django/contrib/admin/templatetags/admin_modify.py
+++ b/django/contrib/admin/templatetags/admin_modify.py
@@ -1,9 +1,7 @@
from django import template
from django.contrib.admin.views.main import AdminBoundField
from django.template import loader
-from django.utils.html import escape
from django.utils.text import capfirst
-from django.utils.functional import curry
from django.db import models
from django.db.models.fields import Field
from django.db.models.related import BoundRelatedObject
@@ -162,8 +160,10 @@ class EditInlineNode(template.Node):
context.push()
if relation.field.rel.edit_inline == models.TABULAR:
bound_related_object_class = TabularBoundRelatedObject
- else:
+ elif relation.field.rel.edit_inline == models.STACKED:
bound_related_object_class = StackedBoundRelatedObject
+ else:
+ bound_related_object_class = relation.field.rel.edit_inline
original = context.get('original', None)
bound_related_object = relation.bind(context['form'], original, bound_related_object_class)
context['bound_related_object'] = bound_related_object
@@ -198,7 +198,7 @@ def filter_interface_script_maybe(bound_field):
if f.rel and isinstance(f.rel, models.ManyToManyRel) and f.rel.filter_interface:
return '<script type="text/javascript">addEvent(window, "load", function(e) {' \
' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % (
- f.name, f.verbose_name, f.rel.filter_interface-1, settings.ADMIN_MEDIA_PREFIX)
+ f.name, f.verbose_name.replace('"', '\\"'), f.rel.filter_interface-1, settings.ADMIN_MEDIA_PREFIX)
else:
return ''
filter_interface_script_maybe = register.simple_tag(filter_interface_script_maybe)
diff --git a/django/contrib/admin/urls.py b/django/contrib/admin/urls.py
index bd894d8de1..aaf9841e45 100644
--- a/django/contrib/admin/urls.py
+++ b/django/contrib/admin/urls.py
@@ -21,13 +21,15 @@ urlpatterns = patterns('',
('^doc/tags/$', 'django.contrib.admin.views.doc.template_tag_index'),
('^doc/filters/$', 'django.contrib.admin.views.doc.template_filter_index'),
('^doc/views/$', 'django.contrib.admin.views.doc.view_index'),
- ('^doc/views/jump/$', 'django.contrib.admin.views.doc.jump_to_view'),
('^doc/views/(?P<view>[^/]+)/$', 'django.contrib.admin.views.doc.view_detail'),
('^doc/models/$', 'django.contrib.admin.views.doc.model_index'),
('^doc/models/(?P<app_label>[^\.]+)\.(?P<model_name>[^/]+)/$', 'django.contrib.admin.views.doc.model_detail'),
# ('^doc/templates/$', 'django.views.admin.doc.template_index'),
('^doc/templates/(?P<template>.*)/$', 'django.contrib.admin.views.doc.template_detail'),
+ # "Add user" -- a special-case view
+ ('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'),
+
# Add/change/delete/history
('^([^/]+)/([^/]+)/$', 'django.contrib.admin.views.main.change_list'),
('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
index 0242b2f32e..9adf09b6a5 100644
--- a/django/contrib/admin/utils.py
+++ b/django/contrib/admin/utils.py
@@ -3,7 +3,6 @@
import re
from email.Parser import HeaderParser
from email.Errors import HeaderParseError
-from urlparse import urljoin
try:
import docutils.core
import docutils.nodes
diff --git a/django/contrib/admin/views/auth.py b/django/contrib/admin/views/auth.py
new file mode 100644
index 0000000000..03876bb4ac
--- /dev/null
+++ b/django/contrib/admin/views/auth.py
@@ -0,0 +1,44 @@
+from django.contrib.admin.views.decorators import staff_member_required
+from django.contrib.auth.forms import UserCreationForm
+from django.contrib.auth.models import User
+from django.core.exceptions import PermissionDenied
+from django import forms, template
+from django.shortcuts import render_to_response
+from django.http import HttpResponseRedirect
+
+def user_add_stage(request):
+ if not request.user.has_perm('auth.change_user'):
+ raise PermissionDenied
+ manipulator = UserCreationForm()
+ if request.method == 'POST':
+ new_data = request.POST.copy()
+ errors = manipulator.get_validation_errors(new_data)
+ if not errors:
+ new_user = manipulator.save(new_data)
+ msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user}
+ if request.POST.has_key("_addanother"):
+ request.user.message_set.create(message=msg)
+ return HttpResponseRedirect(request.path)
+ else:
+ request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
+ return HttpResponseRedirect('../%s/' % new_user.id)
+ else:
+ errors = new_data = {}
+ form = forms.FormWrapper(manipulator, new_data, errors)
+ return render_to_response('admin/auth/user/add_form.html', {
+ 'title': _('Add user'),
+ 'form': form,
+ 'is_popup': request.REQUEST.has_key('_popup'),
+ 'add': True,
+ 'change': False,
+ 'has_delete_permission': False,
+ 'has_change_permission': True,
+ 'has_file_field': False,
+ 'has_absolute_url': False,
+ 'auto_populated_fields': (),
+ 'bound_field_sets': (),
+ 'first_form_field_id': 'id_username',
+ 'opts': User._meta,
+ 'username_help_text': User._meta.get_field('username').help_text,
+ }, context_instance=template.RequestContext(request))
+user_add_stage = staff_member_required(user_add_stage)
diff --git a/django/contrib/admin/views/decorators.py b/django/contrib/admin/views/decorators.py
index 250c585220..9dfe651fe6 100644
--- a/django/contrib/admin/views/decorators.py
+++ b/django/contrib/admin/views/decorators.py
@@ -46,7 +46,7 @@ def staff_member_required(view_func):
member, displaying the login page if necessary.
"""
def _checklogin(request, *args, **kwargs):
- if not request.user.is_anonymous() and request.user.is_staff:
+ if request.user.is_authenticated() and request.user.is_staff:
# The user is valid. Continue to the admin page.
if request.POST.has_key('post_data'):
# User must have re-authenticated through a different window
@@ -87,7 +87,7 @@ def staff_member_required(view_func):
# The user data is correct; log in the user in and continue.
else:
- if user.is_staff:
+ if user.is_active and user.is_staff:
login(request, user)
# TODO: set last_login with an event.
user.last_login = datetime.datetime.now()
diff --git a/django/contrib/admin/views/doc.py b/django/contrib/admin/views/doc.py
index 5aa143e1fd..435d76f276 100644
--- a/django/contrib/admin/views/doc.py
+++ b/django/contrib/admin/views/doc.py
@@ -28,7 +28,7 @@ def bookmarklets(request):
# Hack! This couples this view to the URL it lives at.
admin_root = request.path[:-len('doc/bookmarklets/')]
return render_to_response('admin_doc/bookmarklets.html', {
- 'admin_url': "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', get_host(request), admin_root),
+ 'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', get_host(request), admin_root),
}, context_instance=RequestContext(request))
bookmarklets = staff_member_required(bookmarklets)
@@ -43,11 +43,11 @@ def template_tag_index(request):
for tag_name, tag_func in library.tags.items():
title, body, metadata = utils.parse_docstring(tag_func.__doc__)
if title:
- title = utils.parse_rst(title, 'tag', 'tag:' + tag_name)
+ title = utils.parse_rst(title, 'tag', _('tag:') + tag_name)
if body:
- body = utils.parse_rst(body, 'tag', 'tag:' + tag_name)
+ body = utils.parse_rst(body, 'tag', _('tag:') + tag_name)
for key in metadata:
- metadata[key] = utils.parse_rst(metadata[key], 'tag', 'tag:' + tag_name)
+ metadata[key] = utils.parse_rst(metadata[key], 'tag', _('tag:') + tag_name)
if library in template.builtins:
tag_library = None
else:
@@ -74,11 +74,11 @@ def template_filter_index(request):
for filter_name, filter_func in library.filters.items():
title, body, metadata = utils.parse_docstring(filter_func.__doc__)
if title:
- title = utils.parse_rst(title, 'filter', 'filter:' + filter_name)
+ title = utils.parse_rst(title, 'filter', _('filter:') + filter_name)
if body:
- body = utils.parse_rst(body, 'filter', 'filter:' + filter_name)
+ body = utils.parse_rst(body, 'filter', _('filter:') + filter_name)
for key in metadata:
- metadata[key] = utils.parse_rst(metadata[key], 'filter', 'filter:' + filter_name)
+ metadata[key] = utils.parse_rst(metadata[key], 'filter', _('filter:') + filter_name)
if library in template.builtins:
tag_library = None
else:
@@ -132,11 +132,11 @@ def view_detail(request, view):
raise Http404
title, body, metadata = utils.parse_docstring(view_func.__doc__)
if title:
- title = utils.parse_rst(title, 'view', 'view:' + view)
+ title = utils.parse_rst(title, 'view', _('view:') + view)
if body:
- body = utils.parse_rst(body, 'view', 'view:' + view)
+ body = utils.parse_rst(body, 'view', _('view:') + view)
for key in metadata:
- metadata[key] = utils.parse_rst(metadata[key], 'model', 'view:' + view)
+ metadata[key] = utils.parse_rst(metadata[key], 'model', _('view:') + view)
return render_to_response('admin_doc/view_detail.html', {
'name': view,
'summary': title,
@@ -161,14 +161,14 @@ def model_detail(request, app_label, model_name):
try:
app_mod = models.get_app(app_label)
except ImproperlyConfigured:
- raise Http404, "App %r not found" % app_label
+ raise Http404, _("App %r not found") % app_label
model = None
for m in models.get_models(app_mod):
if m._meta.object_name.lower() == model_name:
model = m
break
if model is None:
- raise Http404, "Model %r not found in app %r" % (model_name, app_label)
+ raise Http404, _("Model %r not found in app %r") % (model_name, app_label)
opts = model._meta
@@ -180,7 +180,7 @@ def model_detail(request, app_label, model_name):
if isinstance(field, models.ForeignKey):
data_type = related_object_name = field.rel.to.__name__
app_label = field.rel.to._meta.app_label
- verbose = utils.parse_rst(("the related `%s.%s` object" % (app_label, data_type)), 'model', 'model:' + data_type)
+ verbose = utils.parse_rst((_("the related `%s.%s` object") % (app_label, data_type)), 'model', _('model:') + data_type)
else:
data_type = get_readable_field_data_type(field)
verbose = field.verbose_name
@@ -202,7 +202,7 @@ def model_detail(request, app_label, model_name):
continue
verbose = func.__doc__
if verbose:
- verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', 'model:' + opts.module_name)
+ verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', _('model:') + opts.module_name)
fields.append({
'name': func_name,
'data_type': get_return_data_type(func_name),
@@ -211,22 +211,22 @@ def model_detail(request, app_label, model_name):
# Gather related objects
for rel in opts.get_all_related_objects():
- verbose = "related `%s.%s` objects" % (rel.opts.app_label, rel.opts.object_name)
+ verbose = _("related `%s.%s` objects") % (rel.opts.app_label, rel.opts.object_name)
accessor = rel.get_accessor_name()
fields.append({
'name' : "%s.all" % accessor,
'data_type' : 'List',
- 'verbose' : utils.parse_rst("all " + verbose , 'model', 'model:' + opts.module_name),
+ 'verbose' : utils.parse_rst(_("all %s") % verbose , 'model', _('model:') + opts.module_name),
})
fields.append({
'name' : "%s.count" % accessor,
'data_type' : 'Integer',
- 'verbose' : utils.parse_rst("number of " + verbose , 'model', 'model:' + opts.module_name),
+ 'verbose' : utils.parse_rst(_("number of %s") % verbose , 'model', _('model:') + opts.module_name),
})
return render_to_response('admin_doc/model_detail.html', {
'name': '%s.%s' % (opts.app_label, opts.object_name),
- 'summary': "Fields on %s objects" % opts.object_name,
+ 'summary': _("Fields on %s objects") % opts.object_name,
'description': model.__doc__,
'fields': fields,
}, context_instance=RequestContext(request))
@@ -328,15 +328,19 @@ def extract_views_from_urlpatterns(urlpatterns, base=''):
"""
views = []
for p in urlpatterns:
- if hasattr(p, 'get_callback'):
+ if hasattr(p, '_get_callback'):
try:
- views.append((p.get_callback(), base + p.regex.pattern))
+ views.append((p._get_callback(), base + p.regex.pattern))
except ViewDoesNotExist:
continue
elif hasattr(p, '_get_url_patterns'):
- views.extend(extract_views_from_urlpatterns(p.url_patterns, base + p.regex.pattern))
+ try:
+ patterns = p.url_patterns
+ except ImportError:
+ continue
+ views.extend(extract_views_from_urlpatterns(patterns, base + p.regex.pattern))
else:
- raise TypeError, "%s does not appear to be a urlpattern object" % p
+ raise TypeError, _("%s does not appear to be a urlpattern object") % p
return views
named_group_matcher = re.compile(r'\(\?P(<\w+>).+?\)')
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index a7ee08f1c0..324841a669 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -10,9 +10,6 @@ from django.shortcuts import get_object_or_404, render_to_response
from django.db import models
from django.db.models.query import handle_legacy_orderlist, QuerySet
from django.http import Http404, HttpResponse, HttpResponseRedirect
-from django.template import loader
-from django.utils import dateformat
-from django.utils.dates import MONTHS
from django.utils.html import escape
from django.utils.text import capfirst, get_text_list
import operator
@@ -266,6 +263,8 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
post_url_continue += "?_popup=1"
return HttpResponseRedirect(post_url_continue % pk_value)
if request.POST.has_key("_popup"):
+ if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable.
+ pk_value = '"%s"' % pk_value.replace('"', '\\"')
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
(pk_value, str(new_object).replace('"', '\\"')))
elif request.POST.has_key("_addanother"):
@@ -455,7 +454,7 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
if related.opts.admin and has_related_objs:
p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission())
if not user.has_perm(p):
- perms_needed.add(rel_opts_name)
+ perms_needed.add(related.opts.verbose_name)
for related in opts.get_all_related_many_to_many_objects():
if related.opts in opts_seen:
continue
@@ -714,10 +713,22 @@ class ChangeList(object):
qs = qs.order_by((self.order_type == 'desc' and '-' or '') + lookup_order_field)
# Apply keyword searches.
+ def construct_search(field_name):
+ if field_name.startswith('^'):
+ return "%s__istartswith" % field_name[1:]
+ elif field_name.startswith('='):
+ return "%s__iexact" % field_name[1:]
+ elif field_name.startswith('@'):
+ return "%s__search" % field_name[1:]
+ else:
+ return "%s__icontains" % field_name
+
if self.lookup_opts.admin.search_fields and self.query:
for bit in self.query.split():
- or_queries = [models.Q(**{'%s__icontains' % field_name: bit}) for field_name in self.lookup_opts.admin.search_fields]
+ or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.lookup_opts.admin.search_fields]
other_qs = QuerySet(self.model)
+ if qs._select_related:
+ other_qs = other_qs.select_related()
other_qs = other_qs.filter(reduce(operator.or_, or_queries))
qs = qs & other_qs
diff --git a/django/contrib/admin/views/template.py b/django/contrib/admin/views/template.py
index f73b9e4218..1684870842 100644
--- a/django/contrib/admin/views/template.py
+++ b/django/contrib/admin/views/template.py
@@ -22,7 +22,7 @@ def template_validator(request):
new_data = request.POST.copy()
errors = manipulator.get_validation_errors(new_data)
if not errors:
- request.user.add_message('The template is valid.')
+ request.user.message_set.create(message='The template is valid.')
return render_to_response('admin/template_validator.html', {
'title': 'Template validator',
'form': forms.FormWrapper(manipulator, new_data, errors),
@@ -32,7 +32,7 @@ template_validator = staff_member_required(template_validator)
class TemplateValidator(forms.Manipulator):
def __init__(self, settings_modules):
self.settings_modules = settings_modules
- site_list = Site.objects.get_in_bulk(settings_modules.keys()).values()
+ site_list = Site.objects.in_bulk(settings_modules.keys()).values()
self.fields = (
forms.SelectField('site', is_required=True, choices=[(s.id, s.name) for s in site_list]),
forms.LargeTextField('template', is_required=True, rows=25, validator_list=[self.isValidTemplate]),