summaryrefslogtreecommitdiff
path: root/django/contrib/admin
diff options
context:
space:
mode:
authorArthur Koziel <arthur@arthurkoziel.com>2010-09-13 00:04:27 +0000
committerArthur Koziel <arthur@arthurkoziel.com>2010-09-13 00:04:27 +0000
commitdd49269c7db008b2567f50cb03c4d3d9b321daa1 (patch)
tree326dd25bb045ac016cda7966b43cbdfe1f67d699 /django/contrib/admin
parentc9b188c4ec939abbe48dae5a371276742e64b6b8 (diff)
downloaddjango-soc2010/app-loading.tar.gz
[soc2010/app-loading] merged trunkarchive/soc2010/app-loadingsoc2010/app-loading
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/app-loading@13818 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/contrib/admin')
-rw-r--r--django/contrib/admin/media/css/base.css13
-rw-r--r--django/contrib/admin/media/css/changelists.css4
-rw-r--r--django/contrib/admin/media/js/dateparse.js20
-rw-r--r--django/contrib/admin/options.py12
-rw-r--r--django/contrib/admin/sites.py6
-rw-r--r--django/contrib/admin/templates/admin/auth/user/add_form.html5
-rw-r--r--django/contrib/admin/templates/admin/base.html4
-rw-r--r--django/contrib/admin/templates/admin/change_list_results.html7
-rw-r--r--django/contrib/admin/templatetags/admin_list.py9
-rw-r--r--django/contrib/admin/widgets.py15
10 files changed, 73 insertions, 22 deletions
diff --git a/django/contrib/admin/media/css/base.css b/django/contrib/admin/media/css/base.css
index da502f357a..9c1f71f810 100644
--- a/django/contrib/admin/media/css/base.css
+++ b/django/contrib/admin/media/css/base.css
@@ -445,6 +445,14 @@ ul.messagelist li {
background: #ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat;
}
+ul.messagelist li.warning{
+ background-image: url(../img/admin/icon_alert.gif);
+}
+
+ul.messagelist li.error{
+ background-image: url(../img/admin/icon_error.gif);
+}
+
.errornote {
font-size: 12px !important;
display: block;
@@ -470,6 +478,11 @@ ul.errorlist {
background: red url(../img/admin/icon_alert.gif) 5px .3em no-repeat;
}
+.errorlist li a {
+ color: white;
+ text-decoration: underline;
+}
+
td ul.errorlist {
margin: 0 !important;
padding: 0 !important;
diff --git a/django/contrib/admin/media/css/changelists.css b/django/contrib/admin/media/css/changelists.css
index 99ff8bc0cf..282833c440 100644
--- a/django/contrib/admin/media/css/changelists.css
+++ b/django/contrib/admin/media/css/changelists.css
@@ -9,6 +9,8 @@
width: 100%;
}
+.change-list .hiddenfields { display:none; }
+
.change-list .filtered table {
border-right: 1px solid #ddd;
}
@@ -21,7 +23,7 @@
background: white url(../img/admin/changelist-bg.gif) top right repeat-y !important;
}
-.change-list .filtered table, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
+.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
margin-right: 160px !important;
width: auto !important;
}
diff --git a/django/contrib/admin/media/js/dateparse.js b/django/contrib/admin/media/js/dateparse.js
index e1c870e146..3cb82dea13 100644
--- a/django/contrib/admin/media/js/dateparse.js
+++ b/django/contrib/admin/media/js/dateparse.js
@@ -100,8 +100,9 @@ var dateParsePatterns = [
{ re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i,
handler: function(bits) {
var d = new Date();
- d.setDate(parseInt(bits[1], 10));
+ d.setDate(1);
d.setMonth(parseMonth(bits[2]));
+ d.setDate(parseInt(bits[1], 10));
return d;
}
},
@@ -109,9 +110,10 @@ var dateParsePatterns = [
{ re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i,
handler: function(bits) {
var d = new Date();
- d.setDate(parseInt(bits[1], 10));
- d.setMonth(parseMonth(bits[2]));
+ d.setDate(1);
d.setYear(bits[3]);
+ d.setMonth(parseMonth(bits[2]));
+ d.setDate(parseInt(bits[1], 10));
return d;
}
},
@@ -119,8 +121,9 @@ var dateParsePatterns = [
{ re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i,
handler: function(bits) {
var d = new Date();
- d.setDate(parseInt(bits[2], 10));
+ d.setDate(1);
d.setMonth(parseMonth(bits[1]));
+ d.setDate(parseInt(bits[2], 10));
return d;
}
},
@@ -128,9 +131,10 @@ var dateParsePatterns = [
{ re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i,
handler: function(bits) {
var d = new Date();
- d.setDate(parseInt(bits[2], 10));
- d.setMonth(parseMonth(bits[1]));
+ d.setDate(1);
d.setYear(bits[3]);
+ d.setMonth(parseMonth(bits[1]));
+ d.setDate(parseInt(bits[2], 10));
return d;
}
},
@@ -158,9 +162,10 @@ var dateParsePatterns = [
{ re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/,
handler: function(bits) {
var d = new Date();
+ d.setDate(1);
d.setYear(bits[3]);
- d.setDate(parseInt(bits[2], 10));
d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
+ d.setDate(parseInt(bits[2], 10));
return d;
}
},
@@ -168,6 +173,7 @@ var dateParsePatterns = [
{ re: /(\d{4})-(\d{1,2})-(\d{1,2})/,
handler: function(bits) {
var d = new Date();
+ d.setDate(1);
d.setYear(parseInt(bits[1]));
d.setMonth(parseInt(bits[2], 10) - 1);
d.setDate(parseInt(bits[3], 10));
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index abbe14c948..ffa3a533e9 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -108,7 +108,13 @@ class BaseModelAdmin(object):
# rendered output. formfield can be None if it came from a
# OneToOneField with parent_link=True or a M2M intermediary.
if formfield and db_field.name not in self.raw_id_fields:
- formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site)
+ related_modeladmin = self.admin_site._registry.get(
+ db_field.rel.to)
+ can_add_related = bool(related_modeladmin and
+ related_modeladmin.has_add_permission(request))
+ formfield.widget = widgets.RelatedFieldWidgetWrapper(
+ formfield.widget, db_field.rel, self.admin_site,
+ can_add_related=can_add_related)
return formfield
@@ -502,7 +508,7 @@ class ModelAdmin(BaseModelAdmin):
# Convert the actions into a SortedDict keyed by name
# and sorted by description.
- actions.sort(lambda a,b: cmp(a[2].lower(), b[2].lower()))
+ actions.sort(key=lambda k: k[2].lower())
actions = SortedDict([
(name, (func, name, desc))
for func, name, desc in actions
@@ -755,7 +761,7 @@ class ModelAdmin(BaseModelAdmin):
if isinstance(response, HttpResponse):
return response
else:
- return HttpResponseRedirect(".")
+ return HttpResponseRedirect(request.get_full_path())
else:
msg = _("No action selected.")
self.message_user(request, msg)
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index f4b6953347..ddc4f8c84b 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -380,11 +380,11 @@ class AdminSite(object):
# Sort the apps alphabetically.
app_list = app_dict.values()
- app_list.sort(lambda x, y: cmp(x['name'], y['name']))
+ app_list.sort(key=lambda x: x['name'])
# Sort the models alphabetically within each app.
for app in app_list:
- app['models'].sort(lambda x, y: cmp(x['name'], y['name']))
+ app['models'].sort(key=lambda x: x['name'])
context = {
'title': _('Site administration'),
@@ -445,7 +445,7 @@ class AdminSite(object):
if not app_dict:
raise http.Http404('The requested admin page does not exist.')
# Sort the models alphabetically within each app.
- app_dict['models'].sort(lambda x, y: cmp(x['name'], y['name']))
+ app_dict['models'].sort(key=lambda x: x['name'])
context = {
'title': _('%s administration') % app_instance.verbose_name,
'app_list': [app_dict],
diff --git a/django/contrib/admin/templates/admin/auth/user/add_form.html b/django/contrib/admin/templates/admin/auth/user/add_form.html
index b57f59b82e..c8889eb069 100644
--- a/django/contrib/admin/templates/admin/auth/user/add_form.html
+++ b/django/contrib/admin/templates/admin/auth/user/add_form.html
@@ -2,8 +2,11 @@
{% load i18n %}
{% block form_top %}
+ {% if not is_popup %}
<p>{% trans "First, enter a username and password. Then, you'll be able to edit more user options." %}</p>
- <input type="hidden" name="_continue" value="1" />
+ {% else %}
+ <p>{% trans "Enter a username and password." %}</p>
+ {% endif %}
{% endblock %}
{% block after_field_sets %}
diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html
index 3fd9eb3770..4221e2d1a7 100644
--- a/django/contrib/admin/templates/admin/base.html
+++ b/django/contrib/admin/templates/admin/base.html
@@ -56,7 +56,9 @@
{% endif %}
{% if messages %}
- <ul class="messagelist">{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul>
+ <ul class="messagelist">{% for message in messages %}
+ <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
+ {% endfor %}</ul>
{% endif %}
<!-- Content -->
diff --git a/django/contrib/admin/templates/admin/change_list_results.html b/django/contrib/admin/templates/admin/change_list_results.html
index 0efcc9b24a..6d4de2df0e 100644
--- a/django/contrib/admin/templates/admin/change_list_results.html
+++ b/django/contrib/admin/templates/admin/change_list_results.html
@@ -1,4 +1,10 @@
+{% if result_hidden_fields %}
+<div class="hiddenfields"> {# DIV for HTML validation #}
+{% for item in result_hidden_fields %}{{ item }}{% endfor %}
+</div>
+{% endif %}
{% if results %}
+<div class="results">
<table cellspacing="0" id="result_list">
<thead>
<tr>
@@ -14,4 +20,5 @@
{% endfor %}
</tbody>
</table>
+</div>
{% endif %}
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index 565db32251..c05af0b7fe 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -189,7 +189,7 @@ def items_for_result(cl, result, form):
else:
result_repr = conditional_escape(result_repr)
yield mark_safe(u'<td%s>%s</td>' % (row_class, result_repr))
- if form:
+ if form and not form[cl.model._meta.pk.name].is_hidden:
yield mark_safe(u'<td>%s</td>' % force_unicode(form[cl.model._meta.pk.name]))
def results(cl):
@@ -200,11 +200,18 @@ def results(cl):
for res in cl.result_list:
yield list(items_for_result(cl, res, None))
+def result_hidden_fields(cl):
+ if cl.formset:
+ for res, form in zip(cl.result_list, cl.formset.forms):
+ if form[cl.model._meta.pk.name].is_hidden:
+ yield mark_safe(force_unicode(form[cl.model._meta.pk.name]))
+
def result_list(cl):
"""
Displays the headers and data list together
"""
return {'cl': cl,
+ 'result_hidden_fields': list(result_hidden_fields(cl)),
'result_headers': list(result_headers(cl)),
'results': list(results(cl))}
result_list = register.inclusion_tag("admin/change_list_results.html")(result_list)
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index 1d321d0620..2c7ac5c794 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -154,9 +154,9 @@ class ForeignKeyRawIdWidget(forms.TextInput):
key = self.rel.get_related_field().name
try:
obj = self.rel.to._default_manager.using(self.db).get(**{key: value})
- except self.rel.to.DoesNotExist:
+ return '&nbsp;<strong>%s</strong>' % escape(truncate_words(obj, 14))
+ except (ValueError, self.rel.to.DoesNotExist):
return ''
- return '&nbsp;<strong>%s</strong>' % escape(truncate_words(obj, 14))
class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
"""
@@ -169,7 +169,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
def render(self, name, value, attrs=None):
attrs['class'] = 'vManyToManyRawIdAdminField'
if value:
- value = ','.join([str(v) for v in value])
+ value = ','.join([force_unicode(v) for v in value])
else:
value = ''
return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
@@ -205,13 +205,18 @@ class RelatedFieldWidgetWrapper(forms.Widget):
This class is a wrapper to a given widget to add the add icon for the
admin interface.
"""
- def __init__(self, widget, rel, admin_site):
+ def __init__(self, widget, rel, admin_site, can_add_related=None):
self.is_hidden = widget.is_hidden
self.needs_multipart_form = widget.needs_multipart_form
self.attrs = widget.attrs
self.choices = widget.choices
self.widget = widget
self.rel = rel
+ # Backwards compatible check for whether a user can add related
+ # objects.
+ if can_add_related is None:
+ can_add_related = rel_to in self.admin_site._registry
+ self.can_add_related = can_add_related
# so we can check if the related object is registered with this AdminSite
self.admin_site = admin_site
@@ -236,7 +241,7 @@ class RelatedFieldWidgetWrapper(forms.Widget):
related_url = '%s%s/%s/add/' % info
self.widget.choices = self.choices
output = [self.widget.render(name, value, *args, **kwargs)]
- if rel_to in self.admin_site._registry: # If the related object has an admin interface:
+ if self.can_add_related:
# TODO: "id_" is hard-coded here. This should instead use the correct
# API to determine the ID dynamically.
output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \