diff --git a/django/conf/__init__.py b/django/conf/__init__.py index 37982e76ad..ac074d5166 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -34,11 +34,8 @@ class LazySettings(LazyObject): is used the first time we need any settings at all, if the user has not previously configured the settings manually. """ - try: - settings_module = os.environ[ENVIRONMENT_VARIABLE] - if not settings_module: # If it's set but is an empty string. - raise KeyError - except KeyError: + settings_module = os.environ.get(ENVIRONMENT_VARIABLE) + if not settings_module: desc = ("setting %s" % name) if name else "settings" raise ImproperlyConfigured( "Requested %s, but settings are not configured. " diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index 1f8cb5ed61..9e539614a3 100644 --- a/django/contrib/admin/filters.py +++ b/django/contrib/admin/filters.py @@ -179,9 +179,9 @@ class RelatedFieldListFilter(FieldListFilter): self.title = self.lookup_title def has_output(self): - if (isinstance(self.field, models.related.RelatedObject) - and self.field.field.null or hasattr(self.field, 'rel') - and self.field.null): + if (isinstance(self.field, models.related.RelatedObject) and + self.field.field.null or hasattr(self.field, 'rel') and + self.field.null): extra = 1 else: extra = 0 @@ -206,9 +206,9 @@ class RelatedFieldListFilter(FieldListFilter): }, [self.lookup_kwarg_isnull]), 'display': val, } - if (isinstance(self.field, models.related.RelatedObject) - and self.field.field.null or hasattr(self.field, 'rel') - and self.field.null): + if (isinstance(self.field, models.related.RelatedObject) and + self.field.field.null or hasattr(self.field, 'rel') and + self.field.null): yield { 'selected': bool(self.lookup_val_isnull), 'query_string': cl.get_query_string({ diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 012a14ef64..86ab0f263e 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -30,7 +30,7 @@ checkbox = forms.CheckboxInput({'class': 'action-select'}, lambda value: False) class AdminForm(object): def __init__(self, form, fieldsets, prepopulated_fields, readonly_fields=None, model_admin=None): - self.form, self.fieldsets = form, normalize_fieldsets(fieldsets) + self.form, self.fieldsets = form, fieldsets self.prepopulated_fields = [{ 'field': form[field_name], 'dependencies': [form[f] for f in dependencies] @@ -42,7 +42,8 @@ class AdminForm(object): def __iter__(self): for name, options in self.fieldsets: - yield Fieldset(self.form, name, + yield Fieldset( + self.form, name, readonly_fields=self.readonly_fields, model_admin=self.model_admin, **options @@ -328,32 +329,11 @@ class AdminErrorList(forms.utils.ErrorList): Stores all errors for the form/formsets in an add/change stage view. """ def __init__(self, form, inline_formsets): + super(AdminErrorList, self).__init__() + if form.is_bound: self.extend(list(six.itervalues(form.errors))) for inline_formset in inline_formsets: self.extend(inline_formset.non_form_errors()) for errors_in_inline_form in inline_formset.errors: self.extend(list(six.itervalues(errors_in_inline_form))) - - -def normalize_fieldsets(fieldsets): - """ - Make sure the keys in fieldset dictionaries are strings. Returns the - normalized data. - """ - result = [] - for name, options in fieldsets: - result.append((name, normalize_dictionary(options))) - return result - - -def normalize_dictionary(data_dict): - """ - Converts all the keys in "data_dict" to strings. The keys must be - convertible using str(). - """ - for key, value in data_dict.items(): - if not isinstance(key, str): - del data_dict[key] - data_dict[str(key)] = value - return data_dict diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 2f39c6a896..4c5adaf0f8 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -613,7 +613,7 @@ class ModelAdmin(BaseModelAdmin): } defaults.update(kwargs) if (defaults.get('fields') is None - and not modelform_defines_fields(defaults.get('form'))): + and not modelform_defines_fields(defaults.get('form'))): defaults['fields'] = forms.ALL_FIELDS return modelform_factory(self.model, **defaults) @@ -1520,7 +1520,8 @@ class ModelAdmin(BaseModelAdmin): selection_note_all = ungettext('%(total_count)s selected', 'All %(total_count)s selected', cl.result_count) - context = dict(self.admin_site.each_context(), + context = dict( + self.admin_site.each_context(), module_name=force_text(opts.verbose_name_plural), selection_note=_('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)}, selection_note_all=selection_note_all % {'total_count': cl.result_count}, @@ -1587,7 +1588,8 @@ class ModelAdmin(BaseModelAdmin): else: title = _("Are you sure?") - context = dict(self.admin_site.each_context(), + context = dict( + self.admin_site.each_context(), title=title, object_name=object_name, object=obj, diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 2dac947fbc..7b633bef89 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -169,7 +169,7 @@ class AdminSite(object): raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in " "your INSTALLED_APPS setting in order to use the admin application.") if not ('django.contrib.auth.context_processors.auth' in settings.TEMPLATE_CONTEXT_PROCESSORS or - 'django.core.context_processors.auth' in settings.TEMPLATE_CONTEXT_PROCESSORS): + 'django.core.context_processors.auth' in settings.TEMPLATE_CONTEXT_PROCESSORS): raise ImproperlyConfigured("Put 'django.contrib.auth.context_processors.auth' " "in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") @@ -398,7 +398,8 @@ class AdminSite(object): for app in app_list: app['models'].sort(key=lambda x: x['name']) - context = dict(self.each_context(), + context = dict( + self.each_context(), title=self.index_title, app_list=app_list, ) diff --git a/django/contrib/admin/templates/admin/app_index.html b/django/contrib/admin/templates/admin/app_index.html index 7aff935126..5eff1248c1 100644 --- a/django/contrib/admin/templates/admin/app_index.html +++ b/django/contrib/admin/templates/admin/app_index.html @@ -9,7 +9,7 @@ {% trans 'Home' %} › {% for app in app_list %} -{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %} +{{ app.name }} {% endfor %} {% endblock %} diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html index 961e4823e0..7b4c1e1221 100644 --- a/django/contrib/admin/templates/admin/index.html +++ b/django/contrib/admin/templates/admin/index.html @@ -17,9 +17,7 @@
{% for model in app.models %} diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index 777bfbac81..0181f665ad 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -95,7 +95,8 @@ def result_headers(cl): """ ordering_field_columns = cl.get_ordering_field_columns() for i, field_name in enumerate(cl.list_display): - text, attr = label_for_field(field_name, cl.model, + text, attr = label_for_field( + field_name, cl.model, model_admin=cl.model_admin, return_attr=True ) diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py index c4ce53fec0..4a6f5c3192 100644 --- a/django/contrib/admin/templatetags/admin_modify.py +++ b/django/contrib/admin/templatetags/admin_modify.py @@ -32,8 +32,7 @@ def submit_row(context): save_as = context['save_as'] ctx = { 'opts': opts, - 'show_delete_link': (not is_popup and context['has_delete_permission'] - and change and context.get('show_delete', True)), + 'show_delete_link': not is_popup and context['has_delete_permission'] and change and context.get('show_delete', True), 'show_save_as_new': not is_popup and change and save_as, 'show_save_and_add_another': context['has_add_permission'] and not is_popup and (not save_as or context['add']), 'show_save_and_continue': not is_popup and context['has_change_permission'], diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py index b2cb0b4181..a15967e024 100644 --- a/django/contrib/admin/validation.py +++ b/django/contrib/admin/validation.py @@ -1,3 +1,4 @@ +from django.core.apps import app_cache from django.core.exceptions import ImproperlyConfigured from django.db import models from django.db.models.fields import FieldDoesNotExist @@ -15,9 +16,9 @@ __all__ = ['BaseValidator', 'InlineValidator'] class BaseValidator(object): def __init__(self): - # Before we can introspect models, they need to be fully loaded so that - # inter-relations are set up correctly. We force that here. - models.get_apps() + # Before we can introspect models, they need the app cache to be fully + # loaded so that inter-relations are set up correctly. + app_cache.populate() def validate(self, cls, model): for m in dir(self): @@ -155,7 +156,7 @@ class BaseValidator(object): for field, val in cls.prepopulated_fields.items(): f = get_field(cls, model, 'prepopulated_fields', field) if isinstance(f, (models.DateTimeField, models.ForeignKey, - models.ManyToManyField)): + models.ManyToManyField)): raise ImproperlyConfigured("'%s.prepopulated_fields['%s']' " "is either a DateTimeField, ForeignKey or " "ManyToManyField. This isn't allowed." diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 4b0da928a2..dccab55de4 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -9,7 +9,7 @@ from django.db import models from django.db.models.fields import FieldDoesNotExist from django.utils import six from django.utils.deprecation import RenameMethodsBase -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.translation import ugettext, ugettext_lazy from django.utils.http import urlencode @@ -142,14 +142,7 @@ class ChangeList(six.with_metaclass(RenameChangeListMethods)): lookup_params = self.get_filters_params() use_distinct = False - # Normalize the types of keys for key, value in lookup_params.items(): - if not isinstance(key, str): - # 'key' will be used as a keyword argument later, so Python - # requires it to be a string. - del lookup_params[key] - lookup_params[force_str(key)] = value - if not self.model_admin.lookup_allowed(key, value): raise DisallowedModelAdminLookup("Filtering by %s not allowed" % key) @@ -224,7 +217,7 @@ class ChangeList(six.with_metaclass(RenameChangeListMethods)): # Perform a slight optimization: # full_result_count is equal to paginator.count if no filters # were applied - if self.get_filters_params(): + if self.get_filters_params() or self.params.get(SEARCH_VAR): full_result_count = self.root_queryset.count() else: full_result_count = result_count diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index a17f875f40..f527d72f3f 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -153,10 +153,13 @@ class ForeignKeyRawIdWidget(forms.TextInput): extra = [] if rel_to in self.admin_site._registry: # The related object is registered with the same AdminSite - related_url = reverse('admin:%s_%s_changelist' % - (rel_to._meta.app_label, - rel_to._meta.model_name), - current_app=self.admin_site.name) + related_url = reverse( + 'admin:%s_%s_changelist' % ( + rel_to._meta.app_label, + rel_to._meta.model_name, + ), + current_app=self.admin_site.name, + ) params = self.url_parameters() if params: @@ -167,10 +170,10 @@ class ForeignKeyRawIdWidget(forms.TextInput): attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript code looks for this hook. # TODO: "lookup_id_" is hard-coded here. This should instead use # the correct API to determine the ID dynamically. - extra.append(' ' - % (related_url, url, name)) - extra.append('%s' - % (static('admin/img/selector-search.gif'), _('Lookup'))) + extra.append(' ' % + (related_url, url, name)) + extra.append('%s' % + (static('admin/img/selector-search.gif'), _('Lookup'))) output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] + extra if value: output.append(self.label_for_value(value)) diff --git a/django/contrib/admindocs/models.py b/django/contrib/admindocs/models.py deleted file mode 100644 index a9f813a4cb..0000000000 --- a/django/contrib/admindocs/models.py +++ /dev/null @@ -1 +0,0 @@ -# Empty models.py to allow for specifying admindocs as a test label. diff --git a/django/contrib/admindocs/templates/admin_doc/template_detail.html b/django/contrib/admindocs/templates/admin_doc/template_detail.html index 9535724c24..a747af5ac2 100644 --- a/django/contrib/admindocs/templates/admin_doc/template_detail.html +++ b/django/contrib/admindocs/templates/admin_doc/template_detail.html @@ -15,15 +15,12 @@ {% block content %}

{% blocktrans %}Template: "{{ name }}"{% endblocktrans %}

-{% regroup templates|dictsort:"site_id" by site as templates_by_site %} -{% for group in templates_by_site %} -

{% blocktrans with group.grouper as grouper %}Search path for template "{{ name }}" on {{ grouper }}:{% endblocktrans %}

-
    - {% for template in group.list|dictsort:"order" %} -
  1. {{ template.file }}{% if not template.exists %} {% trans '(does not exist)' %}{% endif %}
  2. - {% endfor %} -
+

{% blocktrans %}Search path for template "{{ name }}":{% endblocktrans %}

+
    +{% for template in templates|dictsort:"order" %} +
  1. {{ template.file }}{% if not template.exists %} {% trans '(does not exist)' %}{% endif %}
  2. {% endfor %} +

‹ {% trans 'Back to Documentation' %}

{% endblock %} diff --git a/django/contrib/admindocs/templates/admin_doc/view_index.html b/django/contrib/admindocs/templates/admin_doc/view_index.html index 891eee7eec..16e48ca8dc 100644 --- a/django/contrib/admindocs/templates/admin_doc/view_index.html +++ b/django/contrib/admindocs/templates/admin_doc/view_index.html @@ -15,29 +15,40 @@

{% trans 'View documentation' %}

-{% regroup views|dictsort:"site_id" by site as views_by_site %} +{% regroup views|dictsort:'namespace' by namespace as views_by_ns %}
-{% for site_views in views_by_site %} +{% for ns_views in views_by_ns %}
-

{% blocktrans with site_views.grouper.name as name %}Views by URL on {{ name }}{% endblocktrans %}

+

+{% if ns_views.grouper %} + {% blocktrans with ns_views.grouper as name %}Views by namespace {{ name }}{% endblocktrans %} +{% else %} + {% blocktrans %}Views by empty namespace{% endblocktrans %} +{% endif %} +

-{% for view in site_views.list|dictsort:"url" %} +{% for view in ns_views.list|dictsort:"url" %} {% ifchanged %}

{{ view.url }}

-

{% blocktrans with view.full_name as name %}View function: {{ name }}{% endblocktrans %}

+

{% blocktrans with view.full_name as full_name and view.url_name as url_name %} + View function: {{ full_name }}. Name: {{ url_name }}. +{% endblocktrans %}

{{ view.title }}


{% endifchanged %} diff --git a/django/contrib/admindocs/tests/test_fields.py b/django/contrib/admindocs/tests/test_fields.py index dd465111a1..3f4efedb9c 100644 --- a/django/contrib/admindocs/tests/test_fields.py +++ b/django/contrib/admindocs/tests/test_fields.py @@ -21,7 +21,8 @@ class TestFieldType(unittest.TestCase): pass def test_field_name(self): - self.assertRaises(AttributeError, + self.assertRaises( + AttributeError, views.get_readable_field_data_type, "NotAField" ) diff --git a/django/contrib/admindocs/urls.py b/django/contrib/admindocs/urls.py index 8aa4dcf946..3dc55657df 100644 --- a/django/contrib/admindocs/urls.py +++ b/django/contrib/admindocs/urls.py @@ -4,38 +4,29 @@ from django.contrib.admindocs import views urlpatterns = patterns('', url('^$', views.BaseAdminDocsView.as_view(template_name='admin_doc/index.html'), - name='django-admindocs-docroot' - ), + name='django-admindocs-docroot'), url('^bookmarklets/$', views.BookmarkletsView.as_view(), - name='django-admindocs-bookmarklets' - ), + name='django-admindocs-bookmarklets'), url('^tags/$', views.TemplateTagIndexView.as_view(), - name='django-admindocs-tags' - ), + name='django-admindocs-tags'), url('^filters/$', views.TemplateFilterIndexView.as_view(), - name='django-admindocs-filters' - ), + name='django-admindocs-filters'), url('^views/$', views.ViewIndexView.as_view(), - name='django-admindocs-views-index' - ), + name='django-admindocs-views-index'), url('^views/(?P[^/]+)/$', views.ViewDetailView.as_view(), - name='django-admindocs-views-detail' - ), + name='django-admindocs-views-detail'), url('^models/$', views.ModelIndexView.as_view(), - name='django-admindocs-models-index' - ), + name='django-admindocs-models-index'), url('^models/(?P[^\.]+)\.(?P[^/]+)/$', views.ModelDetailView.as_view(), - name='django-admindocs-models-detail' - ), + name='django-admindocs-models-detail'), url('^templates/(?P
- - {% blocktrans with name=app.name %}{{ name }}{% endblocktrans %} - + {{ app.name }}