Loading django/contrib/admin/filters.py +4 −4 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ 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: Loading @@ -189,7 +190,6 @@ 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({}, Loading @@ -210,7 +210,7 @@ class RelatedFieldListFilter(FieldListFilter): 'query_string': cl.get_query_string({ self.lookup_kwarg_isnull: 'True', }, [self.lookup_kwarg]), 'display': EMPTY_CHANGELIST_VALUE, 'display': self.empty_value_display, } FieldListFilter.register(lambda f: f.remote_field, RelatedFieldListFilter) Loading Loading @@ -353,6 +353,7 @@ 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: Loading @@ -370,7 +371,6 @@ 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), Loading @@ -397,7 +397,7 @@ class AllValuesFieldListFilter(FieldListFilter): 'query_string': cl.get_query_string({ self.lookup_kwarg_isnull: 'True', }, [self.lookup_kwarg]), 'display': EMPTY_CHANGELIST_VALUE, 'display': self.empty_value_display, } FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) Loading django/contrib/admin/helpers.py +4 −3 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ 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 = {} Loading @@ -186,12 +187,11 @@ 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 = EMPTY_CHANGELIST_VALUE result_repr = self.empty_value_display else: if f is None: boolean = getattr(attr, "boolean", False) Loading @@ -207,7 +207,8 @@ class AdminReadonlyField(object): if isinstance(f.remote_field, ManyToManyRel) and value is not None: result_repr = ", ".join(map(six.text_type, value.all())) else: result_repr = display_for_field(value, f) empty_value_display = self.model_admin.get_empty_value_display() result_repr = display_for_field(value, f, empty_value_display) return conditional_escape(result_repr) Loading django/contrib/admin/options.py +9 −0 Original line number Diff line number Diff line Loading @@ -814,6 +814,15 @@ 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 Loading django/contrib/admin/sites.py +10 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ 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 Loading Loading @@ -154,6 +156,14 @@ 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 Loading django/contrib/admin/templatetags/admin_list.py +8 −6 Original line number Diff line number Diff line Loading @@ -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, EMPTY_CHANGELIST_VALUE, ORDER_VAR, PAGE_VAR, SEARCH_VAR, ALL_VAR, ORDER_VAR, PAGE_VAR, SEARCH_VAR, ) from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import NoReverseMatch Loading Loading @@ -194,20 +194,22 @@ 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_CHANGELIST_VALUE result_repr = empty_value_display 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: if boolean or not value: allow_tags = True result_repr = display_for_value(value, boolean) result_repr = display_for_value(value, empty_value_display, boolean) # Strip HTML tags in the resulting text, except if the # function has an "allow_tags" attribute set to True. if allow_tags: Loading @@ -218,11 +220,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_CHANGELIST_VALUE result_repr = empty_value_display else: result_repr = field_val else: result_repr = display_for_field(value, f) result_repr = display_for_field(value, f, empty_value_display) if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): row_classes.append('nowrap') if force_text(result_repr) == '': Loading Loading
django/contrib/admin/filters.py +4 −4 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ 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: Loading @@ -189,7 +190,6 @@ 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({}, Loading @@ -210,7 +210,7 @@ class RelatedFieldListFilter(FieldListFilter): 'query_string': cl.get_query_string({ self.lookup_kwarg_isnull: 'True', }, [self.lookup_kwarg]), 'display': EMPTY_CHANGELIST_VALUE, 'display': self.empty_value_display, } FieldListFilter.register(lambda f: f.remote_field, RelatedFieldListFilter) Loading Loading @@ -353,6 +353,7 @@ 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: Loading @@ -370,7 +371,6 @@ 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), Loading @@ -397,7 +397,7 @@ class AllValuesFieldListFilter(FieldListFilter): 'query_string': cl.get_query_string({ self.lookup_kwarg_isnull: 'True', }, [self.lookup_kwarg]), 'display': EMPTY_CHANGELIST_VALUE, 'display': self.empty_value_display, } FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) Loading
django/contrib/admin/helpers.py +4 −3 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ 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 = {} Loading @@ -186,12 +187,11 @@ 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 = EMPTY_CHANGELIST_VALUE result_repr = self.empty_value_display else: if f is None: boolean = getattr(attr, "boolean", False) Loading @@ -207,7 +207,8 @@ class AdminReadonlyField(object): if isinstance(f.remote_field, ManyToManyRel) and value is not None: result_repr = ", ".join(map(six.text_type, value.all())) else: result_repr = display_for_field(value, f) empty_value_display = self.model_admin.get_empty_value_display() result_repr = display_for_field(value, f, empty_value_display) return conditional_escape(result_repr) Loading
django/contrib/admin/options.py +9 −0 Original line number Diff line number Diff line Loading @@ -814,6 +814,15 @@ 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 Loading
django/contrib/admin/sites.py +10 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ 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 Loading Loading @@ -154,6 +156,14 @@ 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 Loading
django/contrib/admin/templatetags/admin_list.py +8 −6 Original line number Diff line number Diff line Loading @@ -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, EMPTY_CHANGELIST_VALUE, ORDER_VAR, PAGE_VAR, SEARCH_VAR, ALL_VAR, ORDER_VAR, PAGE_VAR, SEARCH_VAR, ) from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import NoReverseMatch Loading Loading @@ -194,20 +194,22 @@ 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_CHANGELIST_VALUE result_repr = empty_value_display 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: if boolean or not value: allow_tags = True result_repr = display_for_value(value, boolean) result_repr = display_for_value(value, empty_value_display, boolean) # Strip HTML tags in the resulting text, except if the # function has an "allow_tags" attribute set to True. if allow_tags: Loading @@ -218,11 +220,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_CHANGELIST_VALUE result_repr = empty_value_display else: result_repr = field_val else: result_repr = display_for_field(value, f) result_repr = display_for_field(value, f, empty_value_display) if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): row_classes.append('nowrap') if force_text(result_repr) == '': Loading