Loading django/contrib/admin/templatetags/admin_list.py +6 −7 Original line number Diff line number Diff line import datetime from django.contrib.admin.util import lookup_field, display_for_field, label_for_field from django.contrib.admin.util import (lookup_field, display_for_field, display_for_value, label_for_field) from django.contrib.admin.views.main import (ALL_VAR, EMPTY_CHANGELIST_VALUE, ORDER_VAR, PAGE_VAR, SEARCH_VAR) from django.contrib.admin.templatetags.admin_static import static Loading Loading @@ -184,15 +185,15 @@ def items_for_result(cl, result, form): boolean = getattr(attr, 'boolean', False) if boolean: allow_tags = True result_repr = _boolean_icon(value) else: result_repr = smart_unicode(value) 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: result_repr = mark_safe(result_repr) if isinstance(value, (datetime.date, datetime.time)): row_class = ' class="nowrap"' else: if isinstance(f.rel, models.ManyToOneRel): field_val = getattr(result, f.name) Loading @@ -202,9 +203,7 @@ def items_for_result(cl, result, form): result_repr = escape(field_val) else: result_repr = display_for_field(value, f) if isinstance(f, models.DateField)\ or isinstance(f, models.TimeField)\ or isinstance(f, models.ForeignKey): if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): row_class = ' class="nowrap"' if force_unicode(result_repr) == '': result_repr = mark_safe(' ') Loading django/contrib/admin/util.py +22 −1 Original line number Diff line number Diff line import datetime import decimal from django.db import models from django.db.models.sql.constants import LOOKUP_SEP from django.db.models.deletion import Collector Loading Loading @@ -323,7 +326,7 @@ def display_for_field(value, field): return EMPTY_CHANGELIST_VALUE elif isinstance(field, models.DateTimeField): return formats.localize(timezone.localtime(value)) elif isinstance(field, models.DateField) or isinstance(field, models.TimeField): elif isinstance(field, (models.DateField, models.TimeField)): return formats.localize(value) elif isinstance(field, models.DecimalField): return formats.number_format(value, field.decimal_places) Loading @@ -333,6 +336,24 @@ def display_for_field(value, field): return smart_unicode(value) 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_CHANGELIST_VALUE elif isinstance(value, datetime.datetime): return formats.localize(timezone.localtime(value)) elif isinstance(value, (datetime.date, datetime.time)): return formats.localize(value) elif isinstance(value, (decimal.Decimal, float, int, long)): return formats.number_format(value) else: return smart_unicode(value) class NotRelationField(Exception): pass Loading tests/regressiontests/admin_changelist/admin.py +11 −2 Original line number Diff line number Diff line Loading @@ -3,8 +3,8 @@ from __future__ import absolute_import from django.contrib import admin from django.core.paginator import Paginator from .models import (Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow) from .models import (Event, Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow) site = admin.AdminSite(name="admin") Loading @@ -15,6 +15,15 @@ class CustomPaginator(Paginator): allow_empty_first_page=allow_empty_first_page) class EventAdmin(admin.ModelAdmin): list_display = ['event_date_func'] def event_date_func(self, event): return event.date site.register(Event, EventAdmin) class ParentAdmin(admin.ModelAdmin): list_filter = ['child__name'] search_fields = ['child__name'] Loading tests/regressiontests/admin_changelist/models.py +2 −0 Original line number Diff line number Diff line from django.db import models class Event(models.Model): date = models.DateField() class Parent(models.Model): name = models.CharField(max_length=128) Loading tests/regressiontests/admin_changelist/tests.py +19 −3 Original line number Diff line number Diff line from __future__ import absolute_import import datetime from django.contrib import admin from django.contrib.admin.options import IncorrectLookupParameters from django.contrib.admin.views.main import ChangeList, SEARCH_VAR, ALL_VAR Loading @@ -7,14 +9,15 @@ from django.contrib.auth.models import User from django.template import Context, Template from django.test import TestCase from django.test.client import RequestFactory from django.utils import formats from .admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin, GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin, DynamicListDisplayLinksChildAdmin, CustomPaginationAdmin, FilteredChildAdmin, CustomPaginator, site as custom_site, SwallowAdmin) from .models import (Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow, from .models import (Event, Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow, UnorderedObject, OrderedObject) Loading Loading @@ -325,6 +328,19 @@ class ChangeListTests(TestCase): self.assertEqual(cl.paginator.count, 30) self.assertEqual(cl.paginator.page_range, [1, 2, 3]) def test_computed_list_display_localization(self): """ Regression test for #13196: output of functions should be localized in the changelist. """ User.objects.create_superuser( username='super', email='super@localhost', password='secret') self.client.login(username='super', password='secret') event = Event.objects.create(date=datetime.date.today()) response = self.client.get('/admin/admin_changelist/event/') self.assertContains(response, formats.localize(event.date)) self.assertNotContains(response, unicode(event.date)) def test_dynamic_list_display(self): """ Regression tests for #14206: dynamic list_display support. Loading Loading
django/contrib/admin/templatetags/admin_list.py +6 −7 Original line number Diff line number Diff line import datetime from django.contrib.admin.util import lookup_field, display_for_field, label_for_field from django.contrib.admin.util import (lookup_field, display_for_field, display_for_value, label_for_field) from django.contrib.admin.views.main import (ALL_VAR, EMPTY_CHANGELIST_VALUE, ORDER_VAR, PAGE_VAR, SEARCH_VAR) from django.contrib.admin.templatetags.admin_static import static Loading Loading @@ -184,15 +185,15 @@ def items_for_result(cl, result, form): boolean = getattr(attr, 'boolean', False) if boolean: allow_tags = True result_repr = _boolean_icon(value) else: result_repr = smart_unicode(value) 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: result_repr = mark_safe(result_repr) if isinstance(value, (datetime.date, datetime.time)): row_class = ' class="nowrap"' else: if isinstance(f.rel, models.ManyToOneRel): field_val = getattr(result, f.name) Loading @@ -202,9 +203,7 @@ def items_for_result(cl, result, form): result_repr = escape(field_val) else: result_repr = display_for_field(value, f) if isinstance(f, models.DateField)\ or isinstance(f, models.TimeField)\ or isinstance(f, models.ForeignKey): if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): row_class = ' class="nowrap"' if force_unicode(result_repr) == '': result_repr = mark_safe(' ') Loading
django/contrib/admin/util.py +22 −1 Original line number Diff line number Diff line import datetime import decimal from django.db import models from django.db.models.sql.constants import LOOKUP_SEP from django.db.models.deletion import Collector Loading Loading @@ -323,7 +326,7 @@ def display_for_field(value, field): return EMPTY_CHANGELIST_VALUE elif isinstance(field, models.DateTimeField): return formats.localize(timezone.localtime(value)) elif isinstance(field, models.DateField) or isinstance(field, models.TimeField): elif isinstance(field, (models.DateField, models.TimeField)): return formats.localize(value) elif isinstance(field, models.DecimalField): return formats.number_format(value, field.decimal_places) Loading @@ -333,6 +336,24 @@ def display_for_field(value, field): return smart_unicode(value) 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_CHANGELIST_VALUE elif isinstance(value, datetime.datetime): return formats.localize(timezone.localtime(value)) elif isinstance(value, (datetime.date, datetime.time)): return formats.localize(value) elif isinstance(value, (decimal.Decimal, float, int, long)): return formats.number_format(value) else: return smart_unicode(value) class NotRelationField(Exception): pass Loading
tests/regressiontests/admin_changelist/admin.py +11 −2 Original line number Diff line number Diff line Loading @@ -3,8 +3,8 @@ from __future__ import absolute_import from django.contrib import admin from django.core.paginator import Paginator from .models import (Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow) from .models import (Event, Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow) site = admin.AdminSite(name="admin") Loading @@ -15,6 +15,15 @@ class CustomPaginator(Paginator): allow_empty_first_page=allow_empty_first_page) class EventAdmin(admin.ModelAdmin): list_display = ['event_date_func'] def event_date_func(self, event): return event.date site.register(Event, EventAdmin) class ParentAdmin(admin.ModelAdmin): list_filter = ['child__name'] search_fields = ['child__name'] Loading
tests/regressiontests/admin_changelist/models.py +2 −0 Original line number Diff line number Diff line from django.db import models class Event(models.Model): date = models.DateField() class Parent(models.Model): name = models.CharField(max_length=128) Loading
tests/regressiontests/admin_changelist/tests.py +19 −3 Original line number Diff line number Diff line from __future__ import absolute_import import datetime from django.contrib import admin from django.contrib.admin.options import IncorrectLookupParameters from django.contrib.admin.views.main import ChangeList, SEARCH_VAR, ALL_VAR Loading @@ -7,14 +9,15 @@ from django.contrib.auth.models import User from django.template import Context, Template from django.test import TestCase from django.test.client import RequestFactory from django.utils import formats from .admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin, GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin, DynamicListDisplayLinksChildAdmin, CustomPaginationAdmin, FilteredChildAdmin, CustomPaginator, site as custom_site, SwallowAdmin) from .models import (Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow, from .models import (Event, Child, Parent, Genre, Band, Musician, Group, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow, UnorderedObject, OrderedObject) Loading Loading @@ -325,6 +328,19 @@ class ChangeListTests(TestCase): self.assertEqual(cl.paginator.count, 30) self.assertEqual(cl.paginator.page_range, [1, 2, 3]) def test_computed_list_display_localization(self): """ Regression test for #13196: output of functions should be localized in the changelist. """ User.objects.create_superuser( username='super', email='super@localhost', password='secret') self.client.login(username='super', password='secret') event = Event.objects.create(date=datetime.date.today()) response = self.client.get('/admin/admin_changelist/event/') self.assertContains(response, formats.localize(event.date)) self.assertNotContains(response, unicode(event.date)) def test_dynamic_list_display(self): """ Regression tests for #14206: dynamic list_display support. Loading