1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #9313: Remove HTML code from CSV output of many-to-many relationships

This commit is contained in:
jeremystretch
2022-05-06 10:26:02 -04:00
parent 9b4e016fe4
commit 39a9ebaeee
13 changed files with 57 additions and 40 deletions

View File

@ -16,6 +16,7 @@
* [#9267](https://github.com/netbox-community/netbox/issues/9267) - Remove invalid entry in IP address role choices * [#9267](https://github.com/netbox-community/netbox/issues/9267) - Remove invalid entry in IP address role choices
* [#9306](https://github.com/netbox-community/netbox/issues/9306) - Include VC master interfaces when selecting a LAG/bridge for a VC member interface * [#9306](https://github.com/netbox-community/netbox/issues/9306) - Include VC master interfaces when selecting a LAG/bridge for a VC member interface
* [#9311](https://github.com/netbox-community/netbox/issues/9311) - Permit creating contact assignment without a priority via the REST API * [#9311](https://github.com/netbox-community/netbox/issues/9311) - Permit creating contact assignment without a priority via the REST API
* [#9313](https://github.com/netbox-community/netbox/issues/9313) - Remove HTML code from CSV output of many-to-many relationships
--- ---

View File

@ -59,7 +59,7 @@ class CircuitTable(NetBoxTable):
) )
commit_rate = CommitRateColumn() commit_rate = CommitRateColumn()
comments = columns.MarkdownColumn() comments = columns.MarkdownColumn()
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -14,7 +14,7 @@ class ProviderTable(NetBoxTable):
name = tables.Column( name = tables.Column(
linkify=True linkify=True
) )
asns = tables.ManyToManyColumn( asns = columns.ManyToManyColumn(
linkify_item=True, linkify_item=True,
verbose_name='ASNs' verbose_name='ASNs'
) )
@ -31,7 +31,7 @@ class ProviderTable(NetBoxTable):
verbose_name='Circuits' verbose_name='Circuits'
) )
comments = columns.MarkdownColumn() comments = columns.MarkdownColumn()
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -190,7 +190,7 @@ class DeviceTable(NetBoxTable):
verbose_name='VC Priority' verbose_name='VC Priority'
) )
comments = columns.MarkdownColumn() comments = columns.MarkdownColumn()
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -43,7 +43,7 @@ class ManufacturerTable(NetBoxTable):
verbose_name='Platforms' verbose_name='Platforms'
) )
slug = tables.Column() slug = tables.Column()
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -26,7 +26,7 @@ class PowerPanelTable(NetBoxTable):
url_params={'power_panel_id': 'pk'}, url_params={'power_panel_id': 'pk'},
verbose_name='Feeds' verbose_name='Feeds'
) )
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -69,7 +69,7 @@ class RackTable(NetBoxTable):
orderable=False, orderable=False,
verbose_name='Power' verbose_name='Power'
) )
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -26,7 +26,7 @@ class RegionTable(NetBoxTable):
url_params={'region_id': 'pk'}, url_params={'region_id': 'pk'},
verbose_name='Sites' verbose_name='Sites'
) )
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(
@ -55,7 +55,7 @@ class SiteGroupTable(NetBoxTable):
url_params={'group_id': 'pk'}, url_params={'group_id': 'pk'},
verbose_name='Sites' verbose_name='Sites'
) )
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(
@ -86,7 +86,7 @@ class SiteTable(NetBoxTable):
group = tables.Column( group = tables.Column(
linkify=True linkify=True
) )
asns = tables.ManyToManyColumn( asns = columns.ManyToManyColumn(
linkify_item=True, linkify_item=True,
verbose_name='ASNs' verbose_name='ASNs'
) )
@ -98,7 +98,7 @@ class SiteTable(NetBoxTable):
) )
tenant = TenantColumn() tenant = TenantColumn()
comments = columns.MarkdownColumn() comments = columns.MarkdownColumn()
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(
@ -137,7 +137,7 @@ class LocationTable(NetBoxTable):
url_params={'location_id': 'pk'}, url_params={'location_id': 'pk'},
verbose_name='Devices' verbose_name='Devices'
) )
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -118,7 +118,7 @@ class ASNTable(NetBoxTable):
url_params={'asn_id': 'pk'}, url_params={'asn_id': 'pk'},
verbose_name='Provider Count' verbose_name='Provider Count'
) )
sites = tables.ManyToManyColumn( sites = columns.ManyToManyColumn(
linkify_item=True, linkify_item=True,
verbose_name='Sites' verbose_name='Sites'
) )

View File

@ -6,7 +6,7 @@ from django.conf import settings
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.db.models import DateField, DateTimeField from django.db.models import DateField, DateTimeField
from django.template import Context, Template from django.template import Context, Template
from django.urls import NoReverseMatch, reverse from django.urls import reverse
from django.utils.formats import date_format from django.utils.formats import date_format
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django_tables2.columns import library from django_tables2.columns import library
@ -27,6 +27,7 @@ __all__ = (
'CustomLinkColumn', 'CustomLinkColumn',
'LinkedCountColumn', 'LinkedCountColumn',
'MarkdownColumn', 'MarkdownColumn',
'ManyToManyColumn',
'MPTTColumn', 'MPTTColumn',
'TagColumn', 'TagColumn',
'TemplateColumn', 'TemplateColumn',
@ -35,6 +36,10 @@ __all__ = (
) )
#
# Django-tables2 overrides
#
@library.register @library.register
class DateColumn(tables.DateColumn): class DateColumn(tables.DateColumn):
""" """
@ -42,7 +47,6 @@ class DateColumn(tables.DateColumn):
tables and null when exporting data. It is registered in the tables library to use this class instead of the tables and null when exporting data. It is registered in the tables library to use this class instead of the
default, making this behavior consistent in all fields of type DateField. default, making this behavior consistent in all fields of type DateField.
""" """
def value(self, value): def value(self, value):
return value return value
@ -59,7 +63,6 @@ class DateTimeColumn(tables.DateTimeColumn):
tables and null when exporting data. It is registered in the tables library to use this class instead of the tables and null when exporting data. It is registered in the tables library to use this class instead of the
default, making this behavior consistent in all fields of type DateTimeField. default, making this behavior consistent in all fields of type DateTimeField.
""" """
def value(self, value): def value(self, value):
if value: if value:
return date_format(value, format="SHORT_DATETIME_FORMAT") return date_format(value, format="SHORT_DATETIME_FORMAT")
@ -71,6 +74,39 @@ class DateTimeColumn(tables.DateTimeColumn):
return cls(**kwargs) return cls(**kwargs)
class ManyToManyColumn(tables.ManyToManyColumn):
"""
Overrides django-tables2's stock ManyToManyColumn to ensure that value() returns only plaintext data.
"""
def value(self, value):
items = [self.transform(item) for item in self.filter(value)]
return self.separator.join(items)
class TemplateColumn(tables.TemplateColumn):
"""
Overrides django-tables2's stock TemplateColumn class to render a placeholder symbol if the returned value
is an empty string.
"""
PLACEHOLDER = mark_safe('—')
def render(self, *args, **kwargs):
ret = super().render(*args, **kwargs)
if not ret.strip():
return self.PLACEHOLDER
return ret
def value(self, **kwargs):
ret = super().value(**kwargs)
if ret == self.PLACEHOLDER:
return ''
return ret
#
# Custom columns
#
class ToggleColumn(tables.CheckBoxColumn): class ToggleColumn(tables.CheckBoxColumn):
""" """
Extend CheckBoxColumn to add a "toggle all" checkbox in the column header. Extend CheckBoxColumn to add a "toggle all" checkbox in the column header.
@ -112,26 +148,6 @@ class BooleanColumn(tables.Column):
return str(value) return str(value)
class TemplateColumn(tables.TemplateColumn):
"""
Overrides django-tables2's stock TemplateColumn class to render a placeholder symbol if the returned value
is an empty string.
"""
PLACEHOLDER = mark_safe('—')
def render(self, *args, **kwargs):
ret = super().render(*args, **kwargs)
if not ret.strip():
return self.PLACEHOLDER
return ret
def value(self, **kwargs):
ret = super().value(**kwargs)
if ret == self.PLACEHOLDER:
return ''
return ret
@dataclass @dataclass
class ActionsItem: class ActionsItem:
title: str title: str

View File

@ -38,7 +38,7 @@ class TenantTable(NetBoxTable):
linkify=True linkify=True
) )
comments = columns.MarkdownColumn() comments = columns.MarkdownColumn()
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -40,7 +40,7 @@ class ClusterGroupTable(NetBoxTable):
url_params={'group_id': 'pk'}, url_params={'group_id': 'pk'},
verbose_name='Clusters' verbose_name='Clusters'
) )
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(
@ -83,7 +83,7 @@ class ClusterTable(NetBoxTable):
verbose_name='VMs' verbose_name='VMs'
) )
comments = columns.MarkdownColumn() comments = columns.MarkdownColumn()
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -78,7 +78,7 @@ class VMInterfaceTable(BaseInterfaceTable):
vrf = tables.Column( vrf = tables.Column(
linkify=True linkify=True
) )
contacts = tables.ManyToManyColumn( contacts = columns.ManyToManyColumn(
linkify_item=True linkify_item=True
) )
tags = columns.TagColumn( tags = columns.TagColumn(