Permalink
Browse files

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

Conflicts:
	django/db/backends/postgresql_psycopg2/base.py
  • Loading branch information...
andrewgodwin committed Jul 26, 2012
2 parents 959a3f9 + ab6cd1c commit 4a2e80fff44d0eb1856b593ac5f31ab1492b3e45
Showing 406 changed files with 4,436 additions and 2,781 deletions.
View
@@ -30,6 +30,7 @@ The PRIMARY AUTHORS are (and/or have been):
* Aymeric Augustin
* Claude Paroz
* Anssi Kääriäinen
+ * Florian Apolloner
More information on the main contributors to Django can be found in
docs/internals/committers.txt.
@@ -61,7 +62,6 @@ answer newbie questions, and generally made Django that much better:
andy@jadedplanet.net
Fabrice Aneche <akh@nobugware.com>
ant9000@netwise.it
- Florian Apolloner <florian@apolloner.eu>
arien <regexbot@gmail.com>
David Ascher <http://ascher.ca/>
atlithorn <atlithorn@gmail.com>
View
@@ -15,6 +15,7 @@
from django.core.exceptions import ImproperlyConfigured
from django.utils.functional import LazyObject, empty
from django.utils import importlib
+from django.utils import six
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
@@ -73,7 +74,7 @@ def __setattr__(self, name, value):
elif name == "ADMIN_MEDIA_PREFIX":
warnings.warn("The ADMIN_MEDIA_PREFIX setting has been removed; "
"use STATIC_URL instead.", DeprecationWarning)
- elif name == "ALLOWED_INCLUDE_ROOTS" and isinstance(value, basestring):
+ elif name == "ALLOWED_INCLUDE_ROOTS" and isinstance(value, six.string_types):
raise ValueError("The ALLOWED_INCLUDE_ROOTS setting must be set "
"to a tuple, not a string.")
object.__setattr__(self, name, value)
@@ -102,7 +103,10 @@ def __init__(self, settings_module):
if setting == setting.upper():
setting_value = getattr(mod, setting)
if setting in tuple_settings and \
- isinstance(setting_value, basestring):
+ isinstance(setting_value, six.string_types):
+ warnings.warn("The %s setting must be a tuple. Please fix your "
+ "settings, as auto-correction is now deprecated." % setting,
+ PendingDeprecationWarning)
setting_value = (setting_value,) # In case the user forgot the comma.
setattr(self, setting, setting_value)
@@ -2,6 +2,7 @@
RegexURLResolver, LocaleRegexURLResolver)
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
+from django.utils import six
__all__ = ['handler403', 'handler404', 'handler500', 'include', 'patterns', 'url']
@@ -20,7 +21,7 @@ def include(arg, namespace=None, app_name=None):
# No namespace hint - use manually provided namespace
urlconf_module = arg
- if isinstance(urlconf_module, basestring):
+ if isinstance(urlconf_module, six.string_types):
urlconf_module = import_module(urlconf_module)
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
@@ -52,7 +53,7 @@ def url(regex, view, kwargs=None, name=None, prefix=''):
urlconf_module, app_name, namespace = view
return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
else:
- if isinstance(view, basestring):
+ if isinstance(view, six.string_types):
if not view:
raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex)
if prefix:
@@ -10,8 +10,9 @@
from django.forms.util import flatatt
from django.template.defaultfilters import capfirst
from django.utils.encoding import force_unicode, smart_unicode
-from django.utils.html import escape, conditional_escape
+from django.utils.html import conditional_escape, format_html
from django.utils.safestring import mark_safe
+from django.utils import six
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
@@ -49,7 +50,7 @@ def first_field(self):
try:
fieldset_name, fieldset_options = self.fieldsets[0]
field_name = fieldset_options['fields'][0]
- if not isinstance(field_name, basestring):
+ if not isinstance(field_name, six.string_types):
field_name = field_name[0]
return self.form[field_name]
except (KeyError, IndexError):
@@ -163,11 +164,9 @@ def label_tag(self):
if not self.is_first:
attrs["class"] = "inline"
label = self.field['label']
- contents = capfirst(force_unicode(escape(label))) + ":"
- return mark_safe('<label%(attrs)s>%(contents)s</label>' % {
- "attrs": flatatt(attrs),
- "contents": contents,
- })
+ return format_html('<label{0}>{1}:</label>',
+ flatatt(attrs),
+ capfirst(force_unicode(label)))
def contents(self):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
@@ -190,7 +189,7 @@ def contents(self):
if value is None:
result_repr = EMPTY_CHANGELIST_VALUE
elif isinstance(f.rel, ManyToManyRel):
- result_repr = ", ".join(map(unicode, value.all()))
+ result_repr = ", ".join(map(six.text_type, value.all()))
else:
result_repr = display_for_field(value, f)
return conditional_escape(result_repr)
@@ -6,7 +6,6 @@
from django.contrib.admin.util import quote
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_unicode
-from django.utils.safestring import mark_safe
ADDITION = 1
CHANGE = 2
@@ -66,5 +65,5 @@ def get_admin_url(self):
This is relative to the Django admin index page.
"""
if self.content_type and self.object_id:
- return mark_safe("%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, quote(self.object_id)))
+ return "%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, quote(self.object_id))
return None
@@ -24,6 +24,7 @@
from django.utils.datastructures import SortedDict
from django.utils.html import escape, escapejs
from django.utils.safestring import mark_safe
+from django.utils import six
from django.utils.text import capfirst, get_text_list
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
@@ -57,9 +58,8 @@ class IncorrectLookupParameters(Exception):
csrf_protect_m = method_decorator(csrf_protect)
-class BaseModelAdmin(object):
+class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
"""Functionality common to both ModelAdmin and InlineAdmin."""
- __metaclass__ = forms.MediaDefiningClass
raw_id_fields = ()
fields = None
@@ -745,7 +745,7 @@ def render_change_form(self, request, context, add=False, change=False, form_url
'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
'ordered_objects': ordered_objects,
- 'form_url': mark_safe(form_url),
+ 'form_url': form_url,
'opts': opts,
'content_type_id': ContentType.objects.get_for_model(self.model).id,
'save_as': self.save_as,
@@ -998,7 +998,6 @@ def add_view(self, request, form_url='', extra_context=None):
'title': _('Add %s') % force_unicode(opts.verbose_name),
'adminform': adminForm,
'is_popup': "_popup" in request.REQUEST,
- 'show_delete': False,
'media': media,
'inline_admin_formsets': inline_admin_formsets,
'errors': helpers.AdminErrorList(form, formsets),
@@ -1321,7 +1320,7 @@ def history_view(self, request, object_id, extra_context=None):
opts = model._meta
app_label = opts.app_label
action_list = LogEntry.objects.filter(
- object_id = object_id,
+ object_id = unquote(object_id),
content_type__id__exact = ContentType.objects.get_for_model(model).id
).select_related().order_by('action_time')
# If no history was found, see whether this object even exists.
@@ -231,7 +231,8 @@ def wrapper(*args, **kwargs):
wrap(self.i18n_javascript, cacheable=True),
name='jsi18n'),
url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$',
- wrap(contenttype_views.shortcut)),
+ wrap(contenttype_views.shortcut),
+ name='view_on_site'),
url(r'^(?P<app_label>\w+)/$',
wrap(self.app_index),
name='app_list')
@@ -41,7 +41,8 @@
text-align: left;
}
-.selector .selector-filter label {
+.selector .selector-filter label,
+.inline-group .aligned .selector .selector-filter label {
width: 16px;
padding: 2px;
}
@@ -3,8 +3,7 @@
{% load admin_urls %}
{% block extrahead %}{{ block.super }}
-{% url 'admin:jsi18n' as jsi18nurl %}
-<script type="text/javascript" src="{{ jsi18nurl|default:"../../../../jsi18n/" }}"></script>
+<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
@@ -3,8 +3,7 @@
{% load admin_urls %}
{% block extrahead %}{{ block.super }}
-{% url 'admin:jsi18n' as jsi18nurl %}
-<script type="text/javascript" src="{{ jsi18nurl|default:"../../../jsi18n/" }}"></script>
+<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
@@ -31,7 +30,7 @@
<ul class="object-tools">
{% block object-tools-items %}
<li><a href="history/" class="historylink">{% trans "History" %}</a></li>
- {% if has_absolute_url %}<li><a href="../../../r/{{ content_type_id }}/{{ original.pk }}/" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
+ {% if has_absolute_url %}<li><a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
{% endblock %}
</ul>
{% endif %}{% endif %}
@@ -9,8 +9,7 @@
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
{% endif %}
{% if cl.formset or action_form %}
- {% url 'admin:jsi18n' as jsi18nurl %}
- <script type="text/javascript" src="{{ jsi18nurl|default:'../../jsi18n/' }}"></script>
+ <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{% endif %}
{{ media.css }}
{% if not actions_on_top and not actions_on_bottom %}
@@ -7,7 +7,7 @@
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ app_label|capfirst }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
-&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}{{ object.pk }}">{{ object|truncatewords:"18" }}</a>
+&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
&rsaquo; {% trans 'Delete' %}
</div>
{% endblock %}
@@ -6,7 +6,7 @@ <h2>{{ inline_admin_formset.opts.verbose_name_plural|title }}</h2>
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if forloop.last %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
<h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b>&nbsp;<span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span>
- {% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.pk }}/">{% trans "View on site" %}</a>{% endif %}
+ {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
{% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
</h3>
{% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
@@ -27,7 +27,7 @@ <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
<td class="original">
{% if inline_admin_form.original or inline_admin_form.show_url %}<p>
{% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
- {% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.pk }}/">{% trans "View on site" %}</a>{% endif %}
+ {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
</p>{% endif %}
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
{{ inline_admin_form.fk_field.field }}
@@ -7,7 +7,7 @@
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=app_label %}">{{ app_label|capfirst|escape }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ module_name }}</a>
-&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk %}">{{ object|truncatewords:"18" }}</a>
+&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
&rsaquo; {% trans 'History' %}
</div>
{% endblock %}
@@ -10,7 +10,7 @@
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.utils import formats
-from django.utils.html import escape, conditional_escape
+from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.text import capfirst
from django.utils.translation import ugettext as _
@@ -31,9 +31,12 @@ def paginator_number(cl,i):
if i == DOT:
return '... '
elif i == cl.page_num:
- return mark_safe('<span class="this-page">%d</span> ' % (i+1))
+ return format_html('<span class="this-page">{0}</span> ', i+1)
else:
- return mark_safe('<a href="%s"%s>%d</a> ' % (escape(cl.get_query_string({PAGE_VAR: i})), (i == cl.paginator.num_pages-1 and ' class="end"' or ''), i+1))
+ return format_html('<a href="{0}"{1}>{2}</a> ',
+ cl.get_query_string({PAGE_VAR: i}),
+ mark_safe(' class="end"' if i == cl.paginator.num_pages-1 else ''),
+ i+1)
@register.inclusion_tag('admin/pagination.html')
def pagination(cl):
@@ -159,13 +162,14 @@ def result_headers(cl):
"url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),
"url_remove": cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}),
"url_toggle": cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}),
- "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '')
+ "class_attrib": format_html(' class="{0}"', ' '.join(th_classes))
+ if th_classes else '',
}
def _boolean_icon(field_val):
icon_url = static('admin/img/icon-%s.gif' %
{True: 'yes', False: 'no', None: 'unknown'}[field_val])
- return mark_safe('<img src="%s" alt="%s" />' % (icon_url, field_val))
+ return format_html('<img src="{0}" alt="{1}" />', icon_url, field_val)
def items_for_result(cl, result, form):
"""
@@ -182,31 +186,29 @@ def items_for_result(cl, result, form):
else:
if f is None:
if field_name == 'action_checkbox':
- row_class = ' class="action-checkbox"'
+ row_class = mark_safe(' class="action-checkbox"')
allow_tags = getattr(attr, 'allow_tags', False)
boolean = getattr(attr, 'boolean', False)
if boolean:
allow_tags = True
result_repr = display_for_value(value, boolean)
# Strip HTML tags in the resulting text, except if the
# function has an "allow_tags" attribute set to True.
- if not allow_tags:
- result_repr = escape(result_repr)
- else:
+ if allow_tags:
result_repr = mark_safe(result_repr)
if isinstance(value, (datetime.date, datetime.time)):
- row_class = ' class="nowrap"'
+ row_class = mark_safe(' class="nowrap"')
else:
if isinstance(f.rel, models.ManyToOneRel):
field_val = getattr(result, f.name)
if field_val is None:
result_repr = EMPTY_CHANGELIST_VALUE
else:
- result_repr = escape(field_val)
+ result_repr = field_val
else:
result_repr = display_for_field(value, f)
if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
- row_class = ' class="nowrap"'
+ row_class = mark_safe(' class="nowrap"')
if force_unicode(result_repr) == '':
result_repr = mark_safe('&nbsp;')
# If list_display_links not defined, add the link tag to the first field
@@ -222,8 +224,14 @@ def items_for_result(cl, result, form):
attr = pk
value = result.serializable_value(attr)
result_id = repr(force_unicode(value))[1:]
- yield mark_safe('<%s%s><a href="%s"%s>%s</a></%s>' % \
- (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
+ yield format_html('<{0}{1}><a href="{2}"{3}>{4}</a></{5}>',
+ table_tag,
+ row_class,
+ url,
+ format_html(' onclick="opener.dismissRelatedLookupPopup(window, {0}); return false;"', result_id)
+ if cl.is_popup else '',
+ result_repr,
+ table_tag)
else:
# By default the fields come from ModelAdmin.list_editable, but if we pull
# the fields out of the form instead of list_editable custom admins
@@ -233,11 +241,9 @@ def items_for_result(cl, result, form):
form[cl.model._meta.pk.name].is_hidden)):
bf = form[field_name]
result_repr = mark_safe(force_unicode(bf.errors) + force_unicode(bf))
- else:
- result_repr = conditional_escape(result_repr)
- yield mark_safe('<td%s>%s</td>' % (row_class, result_repr))
+ yield format_html('<td{0}>{1}</td>', row_class, result_repr)
if form and not form[cl.model._meta.pk.name].is_hidden:
- yield mark_safe('<td>%s</td>' % force_unicode(form[cl.model._meta.pk.name]))
+ yield format_html('<td>{0}</td>', force_unicode(form[cl.model._meta.pk.name]))
class ResultList(list):
# Wrapper class used to return items in a list_editable
Oops, something went wrong.

0 comments on commit 4a2e80f

Please sign in to comment.