Преглед на файлове

Closes #10698: Omit app label from content type in table columns

jeremystretch преди 3 години
родител
ревизия
0ad7ae2837

+ 1 - 0
docs/release-notes/version-3.4.md

@@ -38,6 +38,7 @@ A new `PluginMenu` class has been introduced, which enables a plugin to inject a
 * [#10348](https://github.com/netbox-community/netbox/issues/10348) - Add decimal custom field type
 * [#10348](https://github.com/netbox-community/netbox/issues/10348) - Add decimal custom field type
 * [#10556](https://github.com/netbox-community/netbox/issues/10556) - Include a `display` field in all GraphQL object types
 * [#10556](https://github.com/netbox-community/netbox/issues/10556) - Include a `display` field in all GraphQL object types
 * [#10595](https://github.com/netbox-community/netbox/issues/10595) - Add GraphQL relationships for additional generic foreign key fields
 * [#10595](https://github.com/netbox-community/netbox/issues/10595) - Add GraphQL relationships for additional generic foreign key fields
+* [#10698](https://github.com/netbox-community/netbox/issues/10698) - Omit app label from content type in table columns
 * [#10761](https://github.com/netbox-community/netbox/issues/10761) - Enable associating an export template with multiple object types
 * [#10761](https://github.com/netbox-community/netbox/issues/10761) - Enable associating an export template with multiple object types
 * [#10781](https://github.com/netbox-community/netbox/issues/10781) - Add support for Python v3.11
 * [#10781](https://github.com/netbox-community/netbox/issues/10781) - Add support for Python v3.11
 
 

+ 2 - 3
netbox/netbox/search/backends.py

@@ -11,7 +11,7 @@ from django.utils.module_loading import import_string
 from extras.models import CachedValue, CustomField
 from extras.models import CachedValue, CustomField
 from netbox.registry import registry
 from netbox.registry import registry
 from utilities.querysets import RestrictedPrefetch
 from utilities.querysets import RestrictedPrefetch
-from utilities.templatetags.builtins.filters import bettertitle
+from utilities.utils import title
 from . import FieldTypes, LookupTypes, get_indexer
 from . import FieldTypes, LookupTypes, get_indexer
 
 
 DEFAULT_LOOKUP_TYPE = LookupTypes.PARTIAL
 DEFAULT_LOOKUP_TYPE = LookupTypes.PARTIAL
@@ -34,8 +34,7 @@ class SearchBackend:
             # Organize choices by category
             # Organize choices by category
             categories = defaultdict(dict)
             categories = defaultdict(dict)
             for label, idx in registry['search'].items():
             for label, idx in registry['search'].items():
-                title = bettertitle(idx.model._meta.verbose_name)
-                categories[idx.get_category()][label] = title
+                categories[idx.get_category()][label] = title(idx.model._meta.verbose_name)
 
 
             # Compile a nested tuple of choices for form rendering
             # Compile a nested tuple of choices for form rendering
             results = (
             results = (

+ 2 - 2
netbox/netbox/tables/columns.py

@@ -300,7 +300,7 @@ class ContentTypeColumn(tables.Column):
     def render(self, value):
     def render(self, value):
         if value is None:
         if value is None:
             return None
             return None
-        return content_type_name(value)
+        return content_type_name(value, include_app=False)
 
 
     def value(self, value):
     def value(self, value):
         if value is None:
         if value is None:
@@ -319,7 +319,7 @@ class ContentTypesColumn(tables.ManyToManyColumn):
         super().__init__(separator=separator, *args, **kwargs)
         super().__init__(separator=separator, *args, **kwargs)
 
 
     def transform(self, obj):
     def transform(self, obj):
-        return content_type_name(obj)
+        return content_type_name(obj, include_app=False)
 
 
     def value(self, value):
     def value(self, value):
         return ','.join([
         return ','.join([

+ 2 - 3
netbox/netbox/tables/tables.py

@@ -12,8 +12,7 @@ from extras.models import CustomField, CustomLink
 from extras.choices import CustomFieldVisibilityChoices
 from extras.choices import CustomFieldVisibilityChoices
 from netbox.tables import columns
 from netbox.tables import columns
 from utilities.paginator import EnhancedPaginator, get_paginate_count
 from utilities.paginator import EnhancedPaginator, get_paginate_count
-from utilities.templatetags.builtins.filters import bettertitle
-from utilities.utils import highlight_string
+from utilities.utils import highlight_string, title
 
 
 __all__ = (
 __all__ = (
     'BaseTable',
     'BaseTable',
@@ -223,7 +222,7 @@ class SearchTable(tables.Table):
 
 
     def render_field(self, value, record):
     def render_field(self, value, record):
         if hasattr(record.object, value):
         if hasattr(record.object, value):
-            return bettertitle(record.object._meta.get_field(value).verbose_name)
+            return title(record.object._meta.get_field(value).verbose_name)
         return value
         return value
 
 
     def render_value(self, value):
     def render_value(self, value):

+ 2 - 2
netbox/utilities/templatetags/builtins/filters.py

@@ -11,7 +11,7 @@ from markdown import markdown
 
 
 from netbox.config import get_config
 from netbox.config import get_config
 from utilities.markdown import StrikethroughExtension
 from utilities.markdown import StrikethroughExtension
-from utilities.utils import clean_html, foreground_color
+from utilities.utils import clean_html, foreground_color, title
 
 
 register = template.Library()
 register = template.Library()
 
 
@@ -46,7 +46,7 @@ def bettertitle(value):
     Alternative to the builtin title(). Ensures that the first letter of each word is uppercase but retains the
     Alternative to the builtin title(). Ensures that the first letter of each word is uppercase but retains the
     original case of all others.
     original case of all others.
     """
     """
-    return ' '.join([w[0].upper() + w[1:] for w in value.split()])
+    return title(value)
 
 
 
 
 @register.filter()
 @register.filter()

+ 13 - 2
netbox/utilities/utils.py

@@ -21,6 +21,13 @@ from netbox.config import get_config
 from utilities.constants import HTTP_REQUEST_META_SAFE_COPY
 from utilities.constants import HTTP_REQUEST_META_SAFE_COPY
 
 
 
 
+def title(value):
+    """
+    Improved implementation of str.title(); retains all existing uppercase letters.
+    """
+    return ' '.join([w[0].upper() + w[1:] for w in str(value).split()])
+
+
 def get_viewname(model, action=None, rest_api=False):
 def get_viewname(model, action=None, rest_api=False):
     """
     """
     Return the view name for the given model and action, if valid.
     Return the view name for the given model and action, if valid.
@@ -393,13 +400,17 @@ def array_to_string(array):
     return ', '.join(ret)
     return ', '.join(ret)
 
 
 
 
-def content_type_name(ct):
+def content_type_name(ct, include_app=True):
     """
     """
     Return a human-friendly ContentType name (e.g. "DCIM > Site").
     Return a human-friendly ContentType name (e.g. "DCIM > Site").
     """
     """
     try:
     try:
         meta = ct.model_class()._meta
         meta = ct.model_class()._meta
-        return f'{meta.app_config.verbose_name} > {meta.verbose_name}'
+        app_label = title(meta.app_config.verbose_name)
+        model_name = title(meta.verbose_name)
+        if include_app:
+            return f'{app_label} > {model_name}'
+        return model_name
     except AttributeError:
     except AttributeError:
         # Model no longer exists
         # Model no longer exists
         return f'{ct.app_label} > {ct.model}'
         return f'{ct.app_label} > {ct.model}'