mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #5873: Use numeric IDs in all object URLs
This commit is contained in:
@ -11,3 +11,4 @@
|
||||
### Other Changes
|
||||
|
||||
* [#1638](https://github.com/netbox-community/netbox/issues/1638) - Migrate all primary keys to 64-bit integers
|
||||
* [#5873](https://github.com/netbox-community/netbox/issues/5873) - Use numeric IDs in all object URLs
|
||||
|
@ -79,7 +79,7 @@ class Provider(PrimaryModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('circuits:provider', args=[self.slug])
|
||||
return reverse('circuits:provider', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -39,7 +39,7 @@ class CircuitTypeTable(BaseTable):
|
||||
circuit_count = tables.Column(
|
||||
verbose_name='Circuits'
|
||||
)
|
||||
actions = ButtonsColumn(CircuitType, pk_field='slug')
|
||||
actions = ButtonsColumn(CircuitType)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = CircuitType
|
||||
@ -56,9 +56,8 @@ class CircuitTable(BaseTable):
|
||||
cid = tables.LinkColumn(
|
||||
verbose_name='ID'
|
||||
)
|
||||
provider = tables.LinkColumn(
|
||||
viewname='circuits:provider',
|
||||
args=[Accessor('provider__slug')]
|
||||
provider = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
status = ChoiceFieldColumn()
|
||||
tenant = tables.TemplateColumn(
|
||||
|
@ -14,19 +14,19 @@ urlpatterns = [
|
||||
path('providers/import/', views.ProviderBulkImportView.as_view(), name='provider_import'),
|
||||
path('providers/edit/', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'),
|
||||
path('providers/delete/', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'),
|
||||
path('providers/<slug:slug>/', views.ProviderView.as_view(), name='provider'),
|
||||
path('providers/<slug:slug>/edit/', views.ProviderEditView.as_view(), name='provider_edit'),
|
||||
path('providers/<slug:slug>/delete/', views.ProviderDeleteView.as_view(), name='provider_delete'),
|
||||
path('providers/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='provider_changelog', kwargs={'model': Provider}),
|
||||
path('providers/<int:pk>/', views.ProviderView.as_view(), name='provider'),
|
||||
path('providers/<int:pk>/edit/', views.ProviderEditView.as_view(), name='provider_edit'),
|
||||
path('providers/<int:pk>/delete/', views.ProviderDeleteView.as_view(), name='provider_delete'),
|
||||
path('providers/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='provider_changelog', kwargs={'model': Provider}),
|
||||
|
||||
# Circuit types
|
||||
path('circuit-types/', views.CircuitTypeListView.as_view(), name='circuittype_list'),
|
||||
path('circuit-types/add/', views.CircuitTypeEditView.as_view(), name='circuittype_add'),
|
||||
path('circuit-types/import/', views.CircuitTypeBulkImportView.as_view(), name='circuittype_import'),
|
||||
path('circuit-types/delete/', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'),
|
||||
path('circuit-types/<slug:slug>/edit/', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
|
||||
path('circuit-types/<slug:slug>/delete/', views.CircuitTypeDeleteView.as_view(), name='circuittype_delete'),
|
||||
path('circuit-types/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='circuittype_changelog', kwargs={'model': CircuitType}),
|
||||
path('circuit-types/<int:pk>/edit/', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
|
||||
path('circuit-types/<int:pk>/delete/', views.CircuitTypeDeleteView.as_view(), name='circuittype_delete'),
|
||||
path('circuit-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='circuittype_changelog', kwargs={'model': CircuitType}),
|
||||
|
||||
# Circuits
|
||||
path('circuits/', views.CircuitListView.as_view(), name='circuit_list'),
|
||||
|
@ -192,7 +192,7 @@ class Site(PrimaryModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('dcim:site', args=[self.slug])
|
||||
return reverse('dcim:site', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -61,7 +61,7 @@ class DeviceRoleTable(BaseTable):
|
||||
)
|
||||
color = ColorColumn()
|
||||
vm_role = BooleanColumn()
|
||||
actions = ButtonsColumn(DeviceRole, pk_field='slug')
|
||||
actions = ButtonsColumn(DeviceRole)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = DeviceRole
|
||||
@ -85,7 +85,7 @@ class PlatformTable(BaseTable):
|
||||
url_params={'platform': 'slug'},
|
||||
verbose_name='VMs'
|
||||
)
|
||||
actions = ButtonsColumn(Platform, pk_field='slug')
|
||||
actions = ButtonsColumn(Platform)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = Platform
|
||||
|
@ -37,7 +37,7 @@ class ManufacturerTable(BaseTable):
|
||||
verbose_name='Platforms'
|
||||
)
|
||||
slug = tables.Column()
|
||||
actions = ButtonsColumn(Manufacturer, pk_field='slug')
|
||||
actions = ButtonsColumn(Manufacturer)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = Manufacturer
|
||||
|
@ -19,9 +19,8 @@ __all__ = (
|
||||
class PowerPanelTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
name = tables.LinkColumn()
|
||||
site = tables.LinkColumn(
|
||||
viewname='dcim:site',
|
||||
args=[Accessor('site__slug')]
|
||||
site = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
powerfeed_count = LinkedCountColumn(
|
||||
viewname='dcim:powerfeed_list',
|
||||
|
@ -29,10 +29,8 @@ class RackGroupTable(BaseTable):
|
||||
orderable=False,
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
site = tables.LinkColumn(
|
||||
viewname='dcim:site',
|
||||
args=[Accessor('site__slug')],
|
||||
verbose_name='Site'
|
||||
site = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
rack_count = tables.Column(
|
||||
verbose_name='Racks'
|
||||
|
@ -27,10 +27,10 @@ urlpatterns = [
|
||||
path('sites/import/', views.SiteBulkImportView.as_view(), name='site_import'),
|
||||
path('sites/edit/', views.SiteBulkEditView.as_view(), name='site_bulk_edit'),
|
||||
path('sites/delete/', views.SiteBulkDeleteView.as_view(), name='site_bulk_delete'),
|
||||
path('sites/<slug:slug>/', views.SiteView.as_view(), name='site'),
|
||||
path('sites/<slug:slug>/edit/', views.SiteEditView.as_view(), name='site_edit'),
|
||||
path('sites/<slug:slug>/delete/', views.SiteDeleteView.as_view(), name='site_delete'),
|
||||
path('sites/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='site_changelog', kwargs={'model': Site}),
|
||||
path('sites/<int:pk>/', views.SiteView.as_view(), name='site'),
|
||||
path('sites/<int:pk>/edit/', views.SiteEditView.as_view(), name='site_edit'),
|
||||
path('sites/<int:pk>/delete/', views.SiteDeleteView.as_view(), name='site_delete'),
|
||||
path('sites/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='site_changelog', kwargs={'model': Site}),
|
||||
path('sites/<int:object_id>/images/add/', ImageAttachmentEditView.as_view(), name='site_add_image', kwargs={'model': Site}),
|
||||
|
||||
# Rack groups
|
||||
@ -80,9 +80,9 @@ urlpatterns = [
|
||||
path('manufacturers/add/', views.ManufacturerEditView.as_view(), name='manufacturer_add'),
|
||||
path('manufacturers/import/', views.ManufacturerBulkImportView.as_view(), name='manufacturer_import'),
|
||||
path('manufacturers/delete/', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'),
|
||||
path('manufacturers/<slug:slug>/edit/', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
|
||||
path('manufacturers/<slug:slug>/delete/', views.ManufacturerDeleteView.as_view(), name='manufacturer_delete'),
|
||||
path('manufacturers/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='manufacturer_changelog', kwargs={'model': Manufacturer}),
|
||||
path('manufacturers/<int:pk>/edit/', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
|
||||
path('manufacturers/<int:pk>/delete/', views.ManufacturerDeleteView.as_view(), name='manufacturer_delete'),
|
||||
path('manufacturers/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='manufacturer_changelog', kwargs={'model': Manufacturer}),
|
||||
|
||||
# Device types
|
||||
path('device-types/', views.DeviceTypeListView.as_view(), name='devicetype_list'),
|
||||
@ -164,18 +164,18 @@ urlpatterns = [
|
||||
path('device-roles/add/', views.DeviceRoleEditView.as_view(), name='devicerole_add'),
|
||||
path('device-roles/import/', views.DeviceRoleBulkImportView.as_view(), name='devicerole_import'),
|
||||
path('device-roles/delete/', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'),
|
||||
path('device-roles/<slug:slug>/edit/', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
|
||||
path('device-roles/<slug:slug>/delete/', views.DeviceRoleDeleteView.as_view(), name='devicerole_delete'),
|
||||
path('device-roles/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='devicerole_changelog', kwargs={'model': DeviceRole}),
|
||||
path('device-roles/<int:pk>/edit/', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
|
||||
path('device-roles/<int:pk>/delete/', views.DeviceRoleDeleteView.as_view(), name='devicerole_delete'),
|
||||
path('device-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='devicerole_changelog', kwargs={'model': DeviceRole}),
|
||||
|
||||
# Platforms
|
||||
path('platforms/', views.PlatformListView.as_view(), name='platform_list'),
|
||||
path('platforms/add/', views.PlatformEditView.as_view(), name='platform_add'),
|
||||
path('platforms/import/', views.PlatformBulkImportView.as_view(), name='platform_import'),
|
||||
path('platforms/delete/', views.PlatformBulkDeleteView.as_view(), name='platform_bulk_delete'),
|
||||
path('platforms/<slug:slug>/edit/', views.PlatformEditView.as_view(), name='platform_edit'),
|
||||
path('platforms/<slug:slug>/delete/', views.PlatformDeleteView.as_view(), name='platform_delete'),
|
||||
path('platforms/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='platform_changelog', kwargs={'model': Platform}),
|
||||
path('platforms/<int:pk>/edit/', views.PlatformEditView.as_view(), name='platform_edit'),
|
||||
path('platforms/<int:pk>/delete/', views.PlatformDeleteView.as_view(), name='platform_delete'),
|
||||
path('platforms/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='platform_changelog', kwargs={'model': Platform}),
|
||||
|
||||
# Devices
|
||||
path('devices/', views.DeviceListView.as_view(), name='device_list'),
|
||||
|
@ -37,7 +37,7 @@ OBJECTCHANGE_REQUEST_ID = """
|
||||
class TagTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
color = ColorColumn()
|
||||
actions = ButtonsColumn(Tag, pk_field='slug')
|
||||
actions = ButtonsColumn(Tag)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = Tag
|
||||
|
@ -13,9 +13,9 @@ urlpatterns = [
|
||||
path('tags/import/', views.TagBulkImportView.as_view(), name='tag_import'),
|
||||
path('tags/edit/', views.TagBulkEditView.as_view(), name='tag_bulk_edit'),
|
||||
path('tags/delete/', views.TagBulkDeleteView.as_view(), name='tag_bulk_delete'),
|
||||
path('tags/<str:slug>/edit/', views.TagEditView.as_view(), name='tag_edit'),
|
||||
path('tags/<str:slug>/delete/', views.TagDeleteView.as_view(), name='tag_delete'),
|
||||
path('tags/<str:slug>/changelog/', views.ObjectChangeLogView.as_view(), name='tag_changelog', kwargs={'model': Tag}),
|
||||
path('tags/<int:pk>/edit/', views.TagEditView.as_view(), name='tag_edit'),
|
||||
path('tags/<int:pk>/delete/', views.TagDeleteView.as_view(), name='tag_delete'),
|
||||
path('tags/<int:pk>/changelog/', views.ObjectChangeLogView.as_view(), name='tag_changelog', kwargs={'model': Tag}),
|
||||
|
||||
# Config contexts
|
||||
path('config-contexts/', views.ConfigContextListView.as_view(), name='configcontext_list'),
|
||||
|
@ -111,9 +111,9 @@ VLAN_MEMBER_TAGGED = """
|
||||
|
||||
TENANT_LINK = """
|
||||
{% if record.tenant %}
|
||||
<a href="{% url 'tenancy:tenant' slug=record.tenant.slug %}" title="{{ record.tenant.description }}">{{ record.tenant }}</a>
|
||||
<a href="{{ record.tenant.get_absolute_url }}" title="{{ record.tenant.description }}">{{ record.tenant }}</a>
|
||||
{% elif record.vrf.tenant %}
|
||||
<a href="{% url 'tenancy:tenant' slug=record.vrf.tenant.slug %}" title="{{ record.vrf.tenant.description }}">{{ record.vrf.tenant }}</a>*
|
||||
<a href="{{ record.vrf.tenant.get_absolute_url }}" title="{{ record.vrf.tenant.description }}">{{ record.vrf.tenant }}</a>*
|
||||
{% else %}
|
||||
—
|
||||
{% endif %}
|
||||
@ -191,7 +191,7 @@ class RIRTable(BaseTable):
|
||||
url_params={'rir': 'slug'},
|
||||
verbose_name='Aggregates'
|
||||
)
|
||||
actions = ButtonsColumn(RIR, pk_field='slug')
|
||||
actions = ButtonsColumn(RIR)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = RIR
|
||||
@ -254,7 +254,7 @@ class RoleTable(BaseTable):
|
||||
url_params={'role': 'slug'},
|
||||
verbose_name='VLANs'
|
||||
)
|
||||
actions = ButtonsColumn(Role, pk_field='slug')
|
||||
actions = ButtonsColumn(Role)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = Role
|
||||
@ -444,9 +444,8 @@ class InterfaceIPAddressTable(BaseTable):
|
||||
class VLANGroupTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
name = tables.Column(linkify=True)
|
||||
site = tables.LinkColumn(
|
||||
viewname='dcim:site',
|
||||
args=[Accessor('site__slug')]
|
||||
site = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
vlan_count = LinkedCountColumn(
|
||||
viewname='ipam:vlan_list',
|
||||
@ -474,9 +473,8 @@ class VLANTable(BaseTable):
|
||||
template_code=VLAN_LINK,
|
||||
verbose_name='ID'
|
||||
)
|
||||
site = tables.LinkColumn(
|
||||
viewname='dcim:site',
|
||||
args=[Accessor('site__slug')]
|
||||
site = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
group = tables.LinkColumn(
|
||||
viewname='ipam:vlangroup_vlans',
|
||||
|
@ -34,9 +34,9 @@ urlpatterns = [
|
||||
path('rirs/add/', views.RIREditView.as_view(), name='rir_add'),
|
||||
path('rirs/import/', views.RIRBulkImportView.as_view(), name='rir_import'),
|
||||
path('rirs/delete/', views.RIRBulkDeleteView.as_view(), name='rir_bulk_delete'),
|
||||
path('rirs/<slug:slug>/edit/', views.RIREditView.as_view(), name='rir_edit'),
|
||||
path('rirs/<slug:slug>/delete/', views.RIRDeleteView.as_view(), name='rir_delete'),
|
||||
path('vrfs/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='rir_changelog', kwargs={'model': RIR}),
|
||||
path('rirs/<int:pk>/edit/', views.RIREditView.as_view(), name='rir_edit'),
|
||||
path('rirs/<int:pk>/delete/', views.RIRDeleteView.as_view(), name='rir_delete'),
|
||||
path('rirs/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rir_changelog', kwargs={'model': RIR}),
|
||||
|
||||
# Aggregates
|
||||
path('aggregates/', views.AggregateListView.as_view(), name='aggregate_list'),
|
||||
@ -54,9 +54,9 @@ urlpatterns = [
|
||||
path('roles/add/', views.RoleEditView.as_view(), name='role_add'),
|
||||
path('roles/import/', views.RoleBulkImportView.as_view(), name='role_import'),
|
||||
path('roles/delete/', views.RoleBulkDeleteView.as_view(), name='role_bulk_delete'),
|
||||
path('roles/<slug:slug>/edit/', views.RoleEditView.as_view(), name='role_edit'),
|
||||
path('roles/<slug:slug>/delete/', views.RoleDeleteView.as_view(), name='role_delete'),
|
||||
path('roles/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='role_changelog', kwargs={'model': Role}),
|
||||
path('roles/<int:pk>/edit/', views.RoleEditView.as_view(), name='role_edit'),
|
||||
path('roles/<int:pk>/delete/', views.RoleDeleteView.as_view(), name='role_delete'),
|
||||
path('roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='role_changelog', kwargs={'model': Role}),
|
||||
|
||||
# Prefixes
|
||||
path('prefixes/', views.PrefixListView.as_view(), name='prefix_list'),
|
||||
|
@ -16,7 +16,7 @@ class SecretRoleTable(BaseTable):
|
||||
url_params={'role': 'slug'},
|
||||
verbose_name='Secrets'
|
||||
)
|
||||
actions = ButtonsColumn(SecretRole, pk_field='slug')
|
||||
actions = ButtonsColumn(SecretRole)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = SecretRole
|
||||
|
@ -12,9 +12,9 @@ urlpatterns = [
|
||||
path('secret-roles/add/', views.SecretRoleEditView.as_view(), name='secretrole_add'),
|
||||
path('secret-roles/import/', views.SecretRoleBulkImportView.as_view(), name='secretrole_import'),
|
||||
path('secret-roles/delete/', views.SecretRoleBulkDeleteView.as_view(), name='secretrole_bulk_delete'),
|
||||
path('secret-roles/<slug:slug>/edit/', views.SecretRoleEditView.as_view(), name='secretrole_edit'),
|
||||
path('secret-roles/<slug:slug>/delete/', views.SecretRoleDeleteView.as_view(), name='secretrole_delete'),
|
||||
path('secret-roles/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='secretrole_changelog', kwargs={'model': SecretRole}),
|
||||
path('secret-roles/<int:pk>/edit/', views.SecretRoleEditView.as_view(), name='secretrole_edit'),
|
||||
path('secret-roles/<int:pk>/delete/', views.SecretRoleDeleteView.as_view(), name='secretrole_delete'),
|
||||
path('secret-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='secretrole_changelog', kwargs={'model': SecretRole}),
|
||||
|
||||
# Secrets
|
||||
path('secrets/', views.SecretListView.as_view(), name='secret_list'),
|
||||
|
@ -74,7 +74,7 @@
|
||||
<tr>
|
||||
<td>Provider</td>
|
||||
<td>
|
||||
<a href="{% url 'circuits:provider' slug=object.provider.slug %}">{{ object.provider }}</a>
|
||||
<a href="{{ object.provider.get_absolute_url }}">{{ object.provider }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -32,7 +32,7 @@
|
||||
{% if termination.site.region %}
|
||||
<a href="{{ termination.site.region.get_absolute_url }}">{{ termination.site.region }}</a> /
|
||||
{% endif %}
|
||||
<a href="{% url 'dcim:site' slug=termination.site.slug %}">{{ termination.site }}</a>
|
||||
<a href="{{ termination.site.get_absolute_url }}">{{ termination.site }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -51,7 +51,7 @@
|
||||
</li>
|
||||
{% if perms.extras.view_objectchange %}
|
||||
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
|
||||
<a href="{% url 'circuits:provider_changelog' slug=object.slug %}">Change Log</a>
|
||||
<a href="{% url 'circuits:provider_changelog' pk=object.pk %}">Change Log</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -23,7 +23,7 @@
|
||||
{% if object.site.region %}
|
||||
<a href="{{ object.site.region.get_absolute_url }}">{{ object.site.region }}</a> /
|
||||
{% endif %}
|
||||
<a href="{% url 'dcim:site' slug=object.site.slug %}">{{ object.site }}</a>
|
||||
<a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -74,7 +74,7 @@
|
||||
<tr>
|
||||
<td>Device Type</td>
|
||||
<td>
|
||||
<span><a href="{% url 'dcim:devicetype' pk=object.device_type.pk %}">{{ object.device_type.display_name }}</a> ({{ object.device_type.u_height }}U)</span>
|
||||
<span><a href="{{ object.device_type.get_absolute_url }}">{{ object.device_type.display_name }}</a> ({{ object.device_type.u_height }}U)</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -55,10 +55,10 @@
|
||||
{% clone_button object %}
|
||||
{% endif %}
|
||||
{% if perms.dcim.change_devicetype %}
|
||||
{% edit_button object use_pk=True %}
|
||||
{% edit_button object %}
|
||||
{% endif %}
|
||||
{% if perms.dcim.delete_devicetype %}
|
||||
{% delete_button object use_pk=True %}
|
||||
{% delete_button object %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<h1>{{ object.manufacturer }} {{ object.model }}</h1>
|
||||
|
@ -85,7 +85,7 @@
|
||||
{% if object.site.region %}
|
||||
<a href="{{ object.site.region.get_absolute_url }}">{{ object.site.region }}</a> /
|
||||
{% endif %}
|
||||
<a href="{% url 'dcim:site' slug=object.site.slug %}">{{ object.site }}</a>
|
||||
<a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -68,7 +68,7 @@
|
||||
{% if rack.site.region %}
|
||||
<a href="{{ rack.site.region.get_absolute_url }}">{{ rack.site.region }}</a> /
|
||||
{% endif %}
|
||||
<a href="{% url 'dcim:site' slug=rack.site.slug %}">{{ rack.site }}</a>
|
||||
<a href="{{ rack.site.get_absolute_url }}">{{ rack.site }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -56,7 +56,7 @@
|
||||
</li>
|
||||
{% if perms.extras.view_objectchange %}
|
||||
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
|
||||
<a href="{% url 'dcim:site_changelog' slug=object.slug %}">Change Log</a>
|
||||
<a href="{% url 'dcim:site_changelog' pk=object.pk %}">Change Log</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -44,7 +44,7 @@
|
||||
</li>
|
||||
{% if perms.extras.view_objectchange %}
|
||||
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
|
||||
<a href="{% url 'extras:tag_changelog' slug=object.slug %}">Change Log</a>
|
||||
<a href="{% url 'extras:tag_changelog' pk=object.pk %}">Change Log</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -129,7 +129,7 @@
|
||||
{% if object.site.region %}
|
||||
<a href="{{ object.site.region.get_absolute_url }}">{{ object.site.region }}</a> /
|
||||
{% endif %}
|
||||
<a href="{% url 'dcim:site' slug=object.site.slug %}">{{ object.site }}</a>
|
||||
<a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a>
|
||||
{% else %}
|
||||
<span class="text-muted">None</span>
|
||||
{% endif %}
|
||||
|
@ -81,7 +81,7 @@
|
||||
{% if object.site.region %}
|
||||
<a href="{{ object.site.region.get_absolute_url }}">{{ object.site.region }}</a> /
|
||||
{% endif %}
|
||||
<a href="{% url 'dcim:site' slug=object.site.slug %}">{{ object.site }}</a>
|
||||
<a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a>
|
||||
{% else %}
|
||||
<span class="text-muted">None</span>
|
||||
{% endif %}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{% url 'ipam:vlangroup_list' %}">VLAN Groups</a></li>
|
||||
{% if object.site %}
|
||||
<li><a href="{% url 'dcim:site' slug=object.site.slug %}">{{ object.site }}</a></li>
|
||||
<li><a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a></li>
|
||||
{% endif %}
|
||||
<li>{{ object }}</li>
|
||||
</ol>
|
||||
|
@ -51,7 +51,7 @@
|
||||
</li>
|
||||
{% if perms.extras.view_objectchange %}
|
||||
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
|
||||
<a href="{% url 'tenancy:tenant_changelog' slug=object.slug %}">Change Log</a>
|
||||
<a href="{% url 'tenancy:tenant_changelog' pk=object.pk %}">Change Log</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -105,7 +105,7 @@ class Tenant(PrimaryModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('tenancy:tenant', args=[self.slug])
|
||||
return reverse('tenancy:tenant', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -12,7 +12,7 @@ MPTT_LINK = """
|
||||
|
||||
COL_TENANT = """
|
||||
{% if record.tenant %}
|
||||
<a href="{% url 'tenancy:tenant' slug=record.tenant.slug %}" title="{{ record.tenant.description }}">{{ record.tenant }}</a>
|
||||
<a href="{{ record.tenant.get_absolute_url }}" title="{{ record.tenant.description }}">{{ record.tenant }}</a>
|
||||
{% else %}
|
||||
—
|
||||
{% endif %}
|
||||
@ -35,7 +35,7 @@ class TenantGroupTable(BaseTable):
|
||||
url_params={'group': 'slug'},
|
||||
verbose_name='Tenants'
|
||||
)
|
||||
actions = ButtonsColumn(TenantGroup, pk_field='slug')
|
||||
actions = ButtonsColumn(TenantGroup)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = TenantGroup
|
||||
|
@ -12,9 +12,9 @@ urlpatterns = [
|
||||
path('tenant-groups/add/', views.TenantGroupEditView.as_view(), name='tenantgroup_add'),
|
||||
path('tenant-groups/import/', views.TenantGroupBulkImportView.as_view(), name='tenantgroup_import'),
|
||||
path('tenant-groups/delete/', views.TenantGroupBulkDeleteView.as_view(), name='tenantgroup_bulk_delete'),
|
||||
path('tenant-groups/<slug:slug>/edit/', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'),
|
||||
path('tenant-groups/<slug:slug>/delete/', views.TenantGroupDeleteView.as_view(), name='tenantgroup_delete'),
|
||||
path('tenant-groups/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='tenantgroup_changelog', kwargs={'model': TenantGroup}),
|
||||
path('tenant-groups/<int:pk>/edit/', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'),
|
||||
path('tenant-groups/<int:pk>/delete/', views.TenantGroupDeleteView.as_view(), name='tenantgroup_delete'),
|
||||
path('tenant-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='tenantgroup_changelog', kwargs={'model': TenantGroup}),
|
||||
|
||||
# Tenants
|
||||
path('tenants/', views.TenantListView.as_view(), name='tenant_list'),
|
||||
@ -22,9 +22,9 @@ urlpatterns = [
|
||||
path('tenants/import/', views.TenantBulkImportView.as_view(), name='tenant_import'),
|
||||
path('tenants/edit/', views.TenantBulkEditView.as_view(), name='tenant_bulk_edit'),
|
||||
path('tenants/delete/', views.TenantBulkDeleteView.as_view(), name='tenant_bulk_delete'),
|
||||
path('tenants/<slug:slug>/', views.TenantView.as_view(), name='tenant'),
|
||||
path('tenants/<slug:slug>/edit/', views.TenantEditView.as_view(), name='tenant_edit'),
|
||||
path('tenants/<slug:slug>/delete/', views.TenantDeleteView.as_view(), name='tenant_delete'),
|
||||
path('tenants/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='tenant_changelog', kwargs={'model': Tenant}),
|
||||
path('tenants/<int:pk>/', views.TenantView.as_view(), name='tenant'),
|
||||
path('tenants/<int:pk>/edit/', views.TenantEditView.as_view(), name='tenant_edit'),
|
||||
path('tenants/<int:pk>/delete/', views.TenantDeleteView.as_view(), name='tenant_delete'),
|
||||
path('tenants/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='tenant_changelog', kwargs={'model': Tenant}),
|
||||
|
||||
]
|
||||
|
@ -147,24 +147,23 @@ class ButtonsColumn(tables.TemplateColumn):
|
||||
# Note that braces are escaped to allow for string formatting prior to template rendering
|
||||
template_code = """
|
||||
{{% if "changelog" in buttons %}}
|
||||
<a href="{{% url '{app_label}:{model_name}_changelog' {pk_field}=record.{pk_field} %}}" class="btn btn-default btn-xs" title="Change log">
|
||||
<a href="{{% url '{app_label}:{model_name}_changelog' pk=record.pk %}}" class="btn btn-default btn-xs" title="Change log">
|
||||
<i class="mdi mdi-history"></i>
|
||||
</a>
|
||||
{{% endif %}}
|
||||
{{% if "edit" in buttons and perms.{app_label}.change_{model_name} %}}
|
||||
<a href="{{% url '{app_label}:{model_name}_edit' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="btn btn-xs btn-warning" title="Edit">
|
||||
<a href="{{% url '{app_label}:{model_name}_edit' pk=record.pk %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="btn btn-xs btn-warning" title="Edit">
|
||||
<i class="mdi mdi-pencil"></i>
|
||||
</a>
|
||||
{{% endif %}}
|
||||
{{% if "delete" in buttons and perms.{app_label}.delete_{model_name} %}}
|
||||
<a href="{{% url '{app_label}:{model_name}_delete' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="btn btn-xs btn-danger" title="Delete">
|
||||
<a href="{{% url '{app_label}:{model_name}_delete' pk=record.pk %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="btn btn-xs btn-danger" title="Delete">
|
||||
<i class="mdi mdi-trash-can-outline"></i>
|
||||
</a>
|
||||
{{% endif %}}
|
||||
"""
|
||||
|
||||
def __init__(self, model, *args, pk_field='pk', buttons=None, prepend_template=None, return_url_extra='',
|
||||
**kwargs):
|
||||
def __init__(self, model, *args, buttons=None, prepend_template=None, return_url_extra='', **kwargs):
|
||||
if prepend_template:
|
||||
prepend_template = prepend_template.replace('{', '{{')
|
||||
prepend_template = prepend_template.replace('}', '}}')
|
||||
@ -173,7 +172,6 @@ class ButtonsColumn(tables.TemplateColumn):
|
||||
template_code = self.template_code.format(
|
||||
app_label=model._meta.app_label,
|
||||
model_name=model._meta.model_name,
|
||||
pk_field=pk_field,
|
||||
buttons=buttons
|
||||
)
|
||||
|
||||
|
@ -40,16 +40,9 @@ def clone_button(instance):
|
||||
|
||||
|
||||
@register.inclusion_tag('buttons/edit.html')
|
||||
def edit_button(instance, use_pk=False):
|
||||
def edit_button(instance):
|
||||
viewname = _get_viewname(instance, 'edit')
|
||||
|
||||
# Assign kwargs
|
||||
if hasattr(instance, 'slug') and not use_pk:
|
||||
kwargs = {'slug': instance.slug}
|
||||
else:
|
||||
kwargs = {'pk': instance.pk}
|
||||
|
||||
url = reverse(viewname, kwargs=kwargs)
|
||||
url = reverse(viewname, kwargs={'pk': instance.pk})
|
||||
|
||||
return {
|
||||
'url': url,
|
||||
@ -57,16 +50,9 @@ def edit_button(instance, use_pk=False):
|
||||
|
||||
|
||||
@register.inclusion_tag('buttons/delete.html')
|
||||
def delete_button(instance, use_pk=False):
|
||||
def delete_button(instance):
|
||||
viewname = _get_viewname(instance, 'delete')
|
||||
|
||||
# Assign kwargs
|
||||
if hasattr(instance, 'slug') and not use_pk:
|
||||
kwargs = {'slug': instance.slug}
|
||||
else:
|
||||
kwargs = {'pk': instance.pk}
|
||||
|
||||
url = reverse(viewname, kwargs=kwargs)
|
||||
url = reverse(viewname, kwargs={'pk': instance.pk})
|
||||
|
||||
return {
|
||||
'url': url,
|
||||
|
@ -5,7 +5,7 @@ from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist
|
||||
from django.db.models import ManyToManyField
|
||||
from django.forms.models import model_to_dict
|
||||
from django.test import Client, TestCase as _TestCase, override_settings
|
||||
from django.urls import reverse, NoReverseMatch
|
||||
from django.urls import reverse
|
||||
from django.utils.text import slugify
|
||||
from netaddr import IPNetwork
|
||||
from taggit.managers import TaggableManager
|
||||
@ -205,14 +205,6 @@ class ModelViewTestCase(ModelTestCase):
|
||||
if instance is None:
|
||||
return reverse(url_format.format(action))
|
||||
|
||||
# Attempt to resolve using slug as the unique identifier if one exists
|
||||
if hasattr(self.model, 'slug'):
|
||||
try:
|
||||
return reverse(url_format.format(action), kwargs={'slug': instance.slug})
|
||||
except NoReverseMatch:
|
||||
pass
|
||||
|
||||
# Default to using the numeric PK to retrieve the URL for an object
|
||||
return reverse(url_format.format(action), kwargs={'pk': instance.pk})
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ class ClusterTypeTable(BaseTable):
|
||||
cluster_count = tables.Column(
|
||||
verbose_name='Clusters'
|
||||
)
|
||||
actions = ButtonsColumn(ClusterType, pk_field='slug')
|
||||
actions = ButtonsColumn(ClusterType)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = ClusterType
|
||||
@ -54,7 +54,7 @@ class ClusterGroupTable(BaseTable):
|
||||
cluster_count = tables.Column(
|
||||
verbose_name='Clusters'
|
||||
)
|
||||
actions = ButtonsColumn(ClusterGroup, pk_field='slug')
|
||||
actions = ButtonsColumn(ClusterGroup)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = ClusterGroup
|
||||
|
@ -13,18 +13,18 @@ urlpatterns = [
|
||||
path('cluster-types/add/', views.ClusterTypeEditView.as_view(), name='clustertype_add'),
|
||||
path('cluster-types/import/', views.ClusterTypeBulkImportView.as_view(), name='clustertype_import'),
|
||||
path('cluster-types/delete/', views.ClusterTypeBulkDeleteView.as_view(), name='clustertype_bulk_delete'),
|
||||
path('cluster-types/<slug:slug>/edit/', views.ClusterTypeEditView.as_view(), name='clustertype_edit'),
|
||||
path('cluster-types/<slug:slug>/delete/', views.ClusterTypeDeleteView.as_view(), name='clustertype_delete'),
|
||||
path('cluster-types/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='clustertype_changelog', kwargs={'model': ClusterType}),
|
||||
path('cluster-types/<int:pk>/edit/', views.ClusterTypeEditView.as_view(), name='clustertype_edit'),
|
||||
path('cluster-types/<int:pk>/delete/', views.ClusterTypeDeleteView.as_view(), name='clustertype_delete'),
|
||||
path('cluster-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='clustertype_changelog', kwargs={'model': ClusterType}),
|
||||
|
||||
# Cluster groups
|
||||
path('cluster-groups/', views.ClusterGroupListView.as_view(), name='clustergroup_list'),
|
||||
path('cluster-groups/add/', views.ClusterGroupEditView.as_view(), name='clustergroup_add'),
|
||||
path('cluster-groups/import/', views.ClusterGroupBulkImportView.as_view(), name='clustergroup_import'),
|
||||
path('cluster-groups/delete/', views.ClusterGroupBulkDeleteView.as_view(), name='clustergroup_bulk_delete'),
|
||||
path('cluster-groups/<slug:slug>/edit/', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'),
|
||||
path('cluster-groups/<slug:slug>/delete/', views.ClusterGroupDeleteView.as_view(), name='clustergroup_delete'),
|
||||
path('cluster-groups/<slug:slug>/changelog/', ObjectChangeLogView.as_view(), name='clustergroup_changelog', kwargs={'model': ClusterGroup}),
|
||||
path('cluster-groups/<int:pk>/edit/', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'),
|
||||
path('cluster-groups/<int:pk>/delete/', views.ClusterGroupDeleteView.as_view(), name='clustergroup_delete'),
|
||||
path('cluster-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='clustergroup_changelog', kwargs={'model': ClusterGroup}),
|
||||
|
||||
# Clusters
|
||||
path('clusters/', views.ClusterListView.as_view(), name='cluster_list'),
|
||||
|
Reference in New Issue
Block a user