summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2015-04-08 20:39:59 -0400
committerTim Graham <timograham@gmail.com>2015-04-08 20:39:59 -0400
commit1273a7a0e808a43ce7a344bbf36d55b9436ecf41 (patch)
treea4d4e30eed1b16c3a4b2951713f368c040c438d8
parent72f769f494822981db6df9524b92a2d86f8e69fe (diff)
downloaddjango-1273a7a0e808a43ce7a344bbf36d55b9436ecf41.tar.gz
Revert "Fixed #24474 -- Allowed configuring the admin's empty change list value."
This reverts commit 72f769f494822981db6df9524b92a2d86f8e69fe. There are several test failures that need to be fixed.
-rw-r--r--django/contrib/admin/filters.py8
-rw-r--r--django/contrib/admin/helpers.py7
-rw-r--r--django/contrib/admin/options.py9
-rw-r--r--django/contrib/admin/sites.py10
-rw-r--r--django/contrib/admin/templatetags/admin_list.py14
-rw-r--r--django/contrib/admin/utils.py12
-rw-r--r--django/contrib/admin/views/main.py3
-rw-r--r--docs/ref/contrib/admin/index.txt65
-rw-r--r--docs/releases/1.9.txt7
-rw-r--r--tests/admin_changelist/admin.py9
-rw-r--r--tests/admin_changelist/tests.py74
11 files changed, 33 insertions, 185 deletions
diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py
index 053db03561..80ba2eebc6 100644
--- a/django/contrib/admin/filters.py
+++ b/django/contrib/admin/filters.py
@@ -174,7 +174,6 @@ class RelatedFieldListFilter(FieldListFilter):
else:
self.lookup_title = other_model._meta.verbose_name
self.title = self.lookup_title
- self.empty_value_display = model_admin.get_empty_value_display()
def has_output(self):
if self.field.null:
@@ -190,6 +189,7 @@ class RelatedFieldListFilter(FieldListFilter):
return field.get_choices(include_blank=False)
def choices(self, cl):
+ from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
yield {
'selected': self.lookup_val is None and not self.lookup_val_isnull,
'query_string': cl.get_query_string({},
@@ -210,7 +210,7 @@ class RelatedFieldListFilter(FieldListFilter):
'query_string': cl.get_query_string({
self.lookup_kwarg_isnull: 'True',
}, [self.lookup_kwarg]),
- 'display': self.empty_value_display,
+ 'display': EMPTY_CHANGELIST_VALUE,
}
FieldListFilter.register(lambda f: f.remote_field, RelatedFieldListFilter)
@@ -353,7 +353,6 @@ class AllValuesFieldListFilter(FieldListFilter):
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull,
None)
- self.empty_value_display = model_admin.get_empty_value_display()
parent_model, reverse_path = reverse_field_path(model, field_path)
# Obey parent ModelAdmin queryset when deciding which options to show
if model == parent_model:
@@ -371,6 +370,7 @@ class AllValuesFieldListFilter(FieldListFilter):
return [self.lookup_kwarg, self.lookup_kwarg_isnull]
def choices(self, cl):
+ from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
yield {
'selected': (self.lookup_val is None
and self.lookup_val_isnull is None),
@@ -397,7 +397,7 @@ class AllValuesFieldListFilter(FieldListFilter):
'query_string': cl.get_query_string({
self.lookup_kwarg_isnull: 'True',
}, [self.lookup_kwarg]),
- 'display': self.empty_value_display,
+ 'display': EMPTY_CHANGELIST_VALUE,
}
FieldListFilter.register(lambda f: True, AllValuesFieldListFilter)
diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
index 6854859b11..a841a5e6a8 100644
--- a/django/contrib/admin/helpers.py
+++ b/django/contrib/admin/helpers.py
@@ -174,7 +174,6 @@ class AdminReadonlyField(object):
self.is_first = is_first
self.is_checkbox = False
self.is_readonly = True
- self.empty_value_display = model_admin.get_empty_value_display()
def label_tag(self):
attrs = {}
@@ -187,11 +186,12 @@ class AdminReadonlyField(object):
def contents(self):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
+ from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
field, obj, model_admin = self.field['field'], self.form.instance, self.model_admin
try:
f, attr, value = lookup_field(field, obj, model_admin)
except (AttributeError, ValueError, ObjectDoesNotExist):
- result_repr = self.empty_value_display
+ result_repr = EMPTY_CHANGELIST_VALUE
else:
if f is None:
boolean = getattr(attr, "boolean", False)
@@ -207,8 +207,7 @@ class AdminReadonlyField(object):
if isinstance(f.remote_field, ManyToManyRel) and value is not None:
result_repr = ", ".join(map(six.text_type, value.all()))
else:
- empty_value_display = self.model_admin.get_empty_value_display()
- result_repr = display_for_field(value, f, empty_value_display)
+ result_repr = display_for_field(value, f)
return conditional_escape(result_repr)
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 7ddca30e8f..50e7227cd0 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -814,15 +814,6 @@ class ModelAdmin(BaseModelAdmin):
description = capfirst(action.replace('_', ' '))
return func, action, description
- def get_empty_value_display(self):
- """
- Return the empty_value_display set on ModelAdmin or AdminSite.
- """
- try:
- return mark_safe(self.empty_value_display)
- except AttributeError:
- return mark_safe(self.admin_site.empty_value_display)
-
def get_list_display(self, request):
"""
Return a sequence containing the fields to be displayed on the
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index e9f7e23765..4b5ee57746 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -48,8 +48,6 @@ class AdminSite(object):
# URL for the "View site" link at the top of each admin page.
site_url = '/'
- _empty_value_display = '-'
-
login_form = None
index_template = None
app_index_template = None
@@ -156,14 +154,6 @@ class AdminSite(object):
"""
return six.iteritems(self._actions)
- @property
- def empty_value_display(self):
- return self._empty_value_display
-
- @empty_value_display.setter
- def empty_value_display(self, empty_value_display):
- self._empty_value_display = empty_value_display
-
def has_permission(self, request):
"""
Returns True if the given HttpRequest has permission to view
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index 889fe4f79c..affd595800 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -8,7 +8,7 @@ from django.contrib.admin.utils import (
display_for_field, display_for_value, label_for_field, lookup_field,
)
from django.contrib.admin.views.main import (
- ALL_VAR, ORDER_VAR, PAGE_VAR, SEARCH_VAR,
+ ALL_VAR, EMPTY_CHANGELIST_VALUE, ORDER_VAR, PAGE_VAR, SEARCH_VAR,
)
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import NoReverseMatch
@@ -194,22 +194,20 @@ def items_for_result(cl, result, form):
first = True
pk = cl.lookup_opts.pk.attname
for field_name in cl.list_display:
- empty_value_display = cl.model_admin.get_empty_value_display()
row_classes = ['field-%s' % field_name]
try:
f, attr, value = lookup_field(field_name, result, cl.model_admin)
except ObjectDoesNotExist:
- result_repr = empty_value_display
+ result_repr = EMPTY_CHANGELIST_VALUE
else:
- empty_value_display = getattr(attr, 'empty_value_display', empty_value_display)
if f is None:
if field_name == 'action_checkbox':
row_classes = ['action-checkbox']
allow_tags = getattr(attr, 'allow_tags', False)
boolean = getattr(attr, 'boolean', False)
- if boolean or not value:
+ if boolean:
allow_tags = True
- result_repr = display_for_value(value, empty_value_display, boolean)
+ 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 allow_tags:
@@ -220,11 +218,11 @@ def items_for_result(cl, result, form):
if isinstance(f.remote_field, models.ManyToOneRel):
field_val = getattr(result, f.name)
if field_val is None:
- result_repr = empty_value_display
+ result_repr = EMPTY_CHANGELIST_VALUE
else:
result_repr = field_val
else:
- result_repr = display_for_field(value, f, empty_value_display)
+ result_repr = display_for_field(value, f)
if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
row_classes.append('nowrap')
if force_text(result_repr) == '':
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
index ac165d2693..69465fa927 100644
--- a/django/contrib/admin/utils.py
+++ b/django/contrib/admin/utils.py
@@ -367,17 +367,18 @@ def help_text_for_field(name, model):
return smart_text(help_text)
-def display_for_field(value, field, empty_value_display):
+def display_for_field(value, field):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
+ from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
if field.flatchoices:
- return dict(field.flatchoices).get(value, empty_value_display)
+ return dict(field.flatchoices).get(value, EMPTY_CHANGELIST_VALUE)
# NullBooleanField needs special-case null-handling, so it comes
# before the general null test.
elif isinstance(field, models.BooleanField) or isinstance(field, models.NullBooleanField):
return _boolean_icon(value)
elif value is None:
- return empty_value_display
+ return EMPTY_CHANGELIST_VALUE
elif isinstance(field, models.DateTimeField):
return formats.localize(timezone.template_localtime(value))
elif isinstance(field, (models.DateField, models.TimeField)):
@@ -392,13 +393,14 @@ def display_for_field(value, field, empty_value_display):
return smart_text(value)
-def display_for_value(value, empty_value_display, boolean=False):
+def display_for_value(value, boolean=False):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
+ from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
if boolean:
return _boolean_icon(value)
elif value is None:
- return empty_value_display
+ return EMPTY_CHANGELIST_VALUE
elif isinstance(value, datetime.datetime):
return formats.localize(timezone.template_localtime(value))
elif isinstance(value, (datetime.date, datetime.time)):
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 5da031db9d..0b38f7b027 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -33,6 +33,9 @@ ERROR_FLAG = 'e'
IGNORED_PARAMS = (
ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, TO_FIELD_VAR)
+# Text to display within change-list table cells if the value is blank.
+EMPTY_CHANGELIST_VALUE = '-'
+
class ChangeList(object):
def __init__(self, request, model, list_display, list_display_links,
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index 17577377d3..4b11fed58a 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -205,33 +205,6 @@ subclass::
to its documentation for some caveats when time zone support is
enabled (:setting:`USE_TZ = True <USE_TZ>`).
-.. attribute:: ModelAdmin.empty_value_display
-
- .. versionadded:: 1.9
-
- This attribute overrides the default display value for record's fields that
- are empty (``None``, empty string, etc.). The default value is ``-`` (a
- dash). For example::
-
- from django.contrib import admin
-
- class AuthorAdmin(admin.ModelAdmin):
- empty_value_display = '-empty-'
-
- You can also override ``empty_value_display`` for all admin pages with
- :attr:`AdminSite.empty_value_display`, or for specific fields like this::
-
- from django.contrib import admin
-
- class AuthorAdmin(admin.ModelAdmin):
- fields = ('name', 'title', 'view_birth_date')
-
- def view_birth_date(self, obj):
- return obj.birth_date
-
- view_birth_date.short_name = 'birth_date'
- view_birth_date.empty_value_display = '???'
-
.. attribute:: ModelAdmin.exclude
This attribute, if given, should be a list of field names to exclude from
@@ -610,33 +583,6 @@ subclass::
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'colored_name')
- * If the value of a field is ``None``, an empty string, or an iterable
- without elements, Django will display ``-`` (a dash). You can override
- this with :attr:`AdminSite.empty_value_display`::
-
- from django.contrib import admin
-
- admin.site.empty_value_display = '(None)'
-
- You can also use :attr:`AdminSite.empty_value_display`::
-
- class PersonAdmin(admin.ModelAdmin):
- empty_value_display = 'unknown'
-
- Or on a field level::
-
- class PersonAdmin(admin.ModelAdmin):
- list_display = ('name', 'birth_date_view')
-
- def birth_date_view(self, obj):
- return obj.birth_date
-
- birth_date_view.empty_value_display = 'unknown'
-
- .. versionadded:: 1.9
-
- The ability to customize ``empty_value_display`` was added.
-
* If the string given is a method of the model, ``ModelAdmin`` or a
callable that returns True or False Django will display a pretty
"on" or "off" icon if you give the method a ``boolean`` attribute
@@ -658,6 +604,7 @@ subclass::
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'born_in_fifties')
+
* The ``__str__()`` (``__unicode__()`` on Python 2) method is just
as valid in ``list_display`` as any other model method, so it's
perfectly OK to do this::
@@ -2521,16 +2468,6 @@ Templates can override or extend base admin templates as described in
Path to a custom template that will be used by the admin site app index view.
-.. attribute:: AdminSite.empty_value_display
-
- .. versionadded:: 1.9
-
- The string to use for displaying empty values in the admin site's change
- list. Defaults to a dash. The value can also be overridden on a per
- ``ModelAdmin`` basis and on a custom field within a ``ModelAdmin`` by
- setting an ``empty_value_display`` attribute on the field. See
- :attr:`ModelAdmin.empty_value_display` for examples.
-
.. attribute:: AdminSite.login_template
Path to a custom template that will be used by the admin site login view.
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index 6b78af4c18..cd124bf602 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -48,13 +48,6 @@ Minor features
changing the ``select_related()`` values used in the admin's changelist query
based on the request.
-* :attr:`AdminSite.empty_value_display
- <django.contrib.admin.AdminSite.empty_value_display>` and
- :attr:`ModelAdmin.empty_value_display
- <django.contrib.admin.ModelAdmin.empty_value_display>` were added to override
- the display of empty values in admin change list. You can also customize the
- value for each field.
-
:mod:`django.contrib.auth`
^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/admin_changelist/admin.py b/tests/admin_changelist/admin.py
index cdc4625098..926a45d518 100644
--- a/tests/admin_changelist/admin.py
+++ b/tests/admin_changelist/admin.py
@@ -125,12 +125,3 @@ class DynamicSearchFieldsChildAdmin(admin.ModelAdmin):
search_fields = super(DynamicSearchFieldsChildAdmin, self).get_search_fields(request)
search_fields += ('age',)
return search_fields
-
-
-class EmptyValueChildAdmin(admin.ModelAdmin):
- empty_value_display = '-empty-'
- list_display = ('name', 'age_display', 'age')
-
- def age_display(self, obj):
- return obj.age
- age_display.empty_value_display = '&dagger;'
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index a6993586fb..7342e45830 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -20,9 +20,9 @@ from .admin import (
BandAdmin, ChildAdmin, ChordsBandAdmin, CustomPaginationAdmin,
CustomPaginator, DynamicListDisplayChildAdmin,
DynamicListDisplayLinksChildAdmin, DynamicListFilterChildAdmin,
- DynamicSearchFieldsChildAdmin, EmptyValueChildAdmin, FilteredChildAdmin,
- GroupAdmin, InvitationAdmin, NoListDisplayLinksParentAdmin, ParentAdmin,
- QuartetAdmin, SwallowAdmin, site as custom_site,
+ DynamicSearchFieldsChildAdmin, FilteredChildAdmin, GroupAdmin,
+ InvitationAdmin, NoListDisplayLinksParentAdmin, ParentAdmin, QuartetAdmin,
+ SwallowAdmin, site as custom_site,
)
from .models import (
Band, Child, ChordsBand, ChordsMusician, CustomIdUser, Event, Genre, Group,
@@ -109,67 +109,14 @@ class ChangeListTests(TestCase):
list_display = m.get_list_display(request)
list_display_links = m.get_list_display_links(request, list_display)
cl = ChangeList(request, Child, list_display, list_display_links,
- m.list_filter, m.date_hierarchy, m.search_fields,
- m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
- cl.formset = None
- template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
- context = Context({'cl': cl})
- table_output = template.render(context)
- link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
- row_html = (
- '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th>'
- '<td class="field-parent nowrap">-</td></tr></tbody>' % link
- )
- self.assertNotEqual(table_output.find(row_html), -1,
- 'Failed to find expected row element: %s' % table_output)
-
- def test_result_list_set_empty_value_display_on_admin_site(self):
- """
- Test that empty value display can be set on AdminSite
- """
- new_child = Child.objects.create(name='name', parent=None)
- request = self.factory.get('/child/')
- # Set a new empty display value on AdminSite.
- admin.site.empty_value_display = '???'
- m = ChildAdmin(Child, admin.site)
- list_display = m.get_list_display(request)
- list_display_links = m.get_list_display_links(request, list_display)
- cl = ChangeList(request, Child, list_display, list_display_links,
- m.list_filter, m.date_hierarchy, m.search_fields,
- m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
- cl.formset = None
- template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
- context = Context({'cl': cl})
- table_output = template.render(context)
- link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
- row_html = (
- '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th>'
- '<td class="field-parent nowrap">???</td></tr></tbody>' % link
- )
- self.assertNotEqual(table_output.find(row_html), -1,
- 'Failed to find expected row element: %s' % table_output)
-
- def test_result_list_set_empty_value_display_in_model_admin(self):
- """
- Test that empty value display can be set in ModelAdmin or individual fields.
- """
- new_child = Child.objects.create(name='name', parent=None)
- request = self.factory.get('/child/')
- m = EmptyValueChildAdmin(Child, admin.site)
- list_display = m.get_list_display(request)
- list_display_links = m.get_list_display_links(request, list_display)
- cl = ChangeList(request, Child, list_display, list_display_links,
- m.list_filter, m.date_hierarchy, m.search_fields,
- m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
+ m.list_filter, m.date_hierarchy, m.search_fields,
+ m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
cl.formset = None
template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
context = Context({'cl': cl})
table_output = template.render(context)
link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
- row_html = (
- '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th>'
- '<td class="field-age_display">&dagger;</td><td class="field-age">-empty-</td></tr></tbody>' % link
- )
+ row_html = '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th><td class="field-parent nowrap">-</td></tr></tbody>' % link
self.assertNotEqual(table_output.find(row_html), -1,
'Failed to find expected row element: %s' % table_output)
@@ -185,17 +132,14 @@ class ChangeListTests(TestCase):
list_display = m.get_list_display(request)
list_display_links = m.get_list_display_links(request, list_display)
cl = ChangeList(request, Child, list_display, list_display_links,
- m.list_filter, m.date_hierarchy, m.search_fields,
- m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
+ m.list_filter, m.date_hierarchy, m.search_fields,
+ m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
cl.formset = None
template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
context = Context({'cl': cl})
table_output = template.render(context)
link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
- row_html = (
- '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th>'
- '<td class="field-parent nowrap">Parent object</td></tr></tbody>' % link
- )
+ row_html = '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th><td class="field-parent nowrap">Parent object</td></tr></tbody>' % link
self.assertNotEqual(table_output.find(row_html), -1,
'Failed to find expected row element: %s' % table_output)