nautobot 2.4.18__py3-none-any.whl → 2.4.19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/apps/ui.py +6 -0
- nautobot/circuits/tables.py +1 -1
- nautobot/circuits/templates/circuits/circuit_create.html +7 -7
- nautobot/circuits/templates/circuits/circuit_retrieve.html +1 -5
- nautobot/circuits/templates/circuits/circuittermination_create.html +26 -26
- nautobot/circuits/templates/circuits/inc/circuit_termination.html +20 -20
- nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +3 -3
- nautobot/circuits/templates/circuits/inc/circuit_termination_speed_fragment.html +7 -7
- nautobot/circuits/templates/circuits/providernetwork_retrieve.html +1 -3
- nautobot/circuits/views.py +26 -9
- nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +1 -4
- nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +1 -7
- nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +1 -3
- nautobot/cloud/templates/cloud/cloudservice_retrieve.html +1 -5
- nautobot/cloud/views.py +45 -0
- nautobot/core/graphql/generators.py +5 -2
- nautobot/core/jobs/bulk_actions.py +48 -85
- nautobot/core/models/querysets.py +2 -1
- nautobot/core/templates/40x.html +15 -15
- nautobot/core/templates/500.html +21 -21
- nautobot/core/templates/admin/app_index.html +8 -8
- nautobot/core/templates/admin/base.html +104 -104
- nautobot/core/templates/admin/change_form.html +65 -65
- nautobot/core/templates/admin/change_list.html +60 -60
- nautobot/core/templates/admin/change_list_results.html +39 -39
- nautobot/core/templates/admin/config/config.html +47 -47
- nautobot/core/templates/admin/delete_confirmation.html +47 -47
- nautobot/core/templates/admin/edit_inline/stacked.html +124 -124
- nautobot/core/templates/admin/edit_inline/tabular.html +60 -60
- nautobot/core/templates/admin/includes/fieldset.html +4 -4
- nautobot/core/templates/admin/index.html +60 -60
- nautobot/core/templates/admin/prepopulated_fields_js.html +18 -18
- nautobot/core/templates/admin/submit_line.html +4 -4
- nautobot/core/templates/base_django.html +46 -46
- nautobot/core/templates/buttons/consolidated_bulk_action_buttons.html +8 -8
- nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +8 -8
- nautobot/core/templates/buttons/export.html +3 -3
- nautobot/core/templates/components/breadcrumbs.html +5 -5
- nautobot/core/templates/components/button/default.html +3 -3
- nautobot/core/templates/components/button/dropdown.html +7 -7
- nautobot/core/templates/components/button/formbutton.html +4 -4
- nautobot/core/templates/components/panel/body_content_data_table.html +1 -1
- nautobot/core/templates/components/panel/body_wrapper_generic_table.html +3 -0
- nautobot/core/templates/components/panel/footer_content_table.html +3 -1
- nautobot/core/templates/components/panel/header_extra_content_table.html +10 -1
- nautobot/core/templates/components/tab/content_wrapper.html +1 -1
- nautobot/core/templates/components/tab/label_wrapper.html +1 -1
- nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +10 -3
- nautobot/core/templates/generic/object_bulk_add_component.html +40 -40
- nautobot/core/templates/generic/object_bulk_create.html +3 -3
- nautobot/core/templates/generic/object_bulk_destroy.html +6 -6
- nautobot/core/templates/generic/object_bulk_update.html +52 -52
- nautobot/core/templates/generic/object_import.html +33 -33
- nautobot/core/templates/generic/object_list.html +267 -267
- nautobot/core/templates/generic/object_retrieve.html +261 -261
- nautobot/core/templates/graphene/graphiql.html +127 -127
- nautobot/core/templates/home.html +62 -62
- nautobot/core/templates/inc/computed_fields/panel_data.html +13 -13
- nautobot/core/templates/inc/created_updated.html +8 -8
- nautobot/core/templates/inc/custom_fields/panel_data.html +13 -13
- nautobot/core/templates/inc/dynamic_groups_panel.html +11 -11
- nautobot/core/templates/inc/footer.html +19 -19
- nautobot/core/templates/inc/javascript.html +1 -1
- nautobot/core/templates/inc/media.html +46 -46
- nautobot/core/templates/inc/nav_menu.html +1 -1
- nautobot/core/templates/inc/relationships_table_rows.html +22 -22
- nautobot/core/templates/inc/tenant_table_row.html +1 -1
- nautobot/core/templates/login.html +77 -77
- nautobot/core/templates/media_failure.html +38 -38
- nautobot/core/templates/panel_table.html +1 -1
- nautobot/core/templates/rest_framework/api.html +3 -3
- nautobot/core/templates/search.html +1 -1
- nautobot/core/templates/swagger_ui.html +9 -9
- nautobot/core/templates/utilities/confirmation_form.html +18 -18
- nautobot/core/templates/utilities/render_field.html +1 -1
- nautobot/core/templates/utilities/render_jinja2.html +43 -43
- nautobot/core/templates/utilities/templatetags/filter_form_modal.html +56 -56
- nautobot/core/templates/utilities/templatetags/utilization_graph.html +1 -1
- nautobot/core/templates/utilities/theme_preview.html +799 -799
- nautobot/core/templates/utilities/worker_status.html +122 -122
- nautobot/core/templates/widgets/clearable_file.html +3 -3
- nautobot/core/templates/widgets/sluginput.html +1 -1
- nautobot/core/templatetags/buttons.py +8 -2
- nautobot/core/templatetags/helpers.py +1 -1
- nautobot/core/testing/integration.py +7 -4
- nautobot/core/testing/views.py +24 -5
- nautobot/core/tests/test_breadcrumbs.py +78 -4
- nautobot/core/tests/test_commands.py +7 -4
- nautobot/core/tests/test_graphql.py +20 -5
- nautobot/core/tests/test_jobs.py +34 -21
- nautobot/core/tests/test_ui.py +175 -1
- nautobot/core/tests/test_utils.py +35 -0
- nautobot/core/tests/test_views_generic.py +43 -0
- nautobot/core/tests/test_views_utils.py +239 -5
- nautobot/core/ui/breadcrumbs.py +208 -21
- nautobot/core/ui/bulk_buttons.py +8 -0
- nautobot/core/ui/object_detail.py +138 -55
- nautobot/core/ui/titles.py +1 -0
- nautobot/core/utils/requests.py +27 -2
- nautobot/core/views/generic.py +41 -31
- nautobot/core/views/mixins.py +80 -110
- nautobot/core/views/utils.py +153 -1
- nautobot/dcim/api/serializers.py +8 -2
- nautobot/dcim/constants.py +1 -0
- nautobot/dcim/factory.py +4 -3
- nautobot/dcim/filters/mixins.py +1 -2
- nautobot/dcim/forms.py +5 -1
- nautobot/dcim/migrations/0074_alter_rack_u_height.py +21 -0
- nautobot/dcim/models/devices.py +26 -1
- nautobot/dcim/models/racks.py +2 -2
- nautobot/dcim/templates/dcim/cable.html +53 -53
- nautobot/dcim/templates/dcim/cable_connect.html +182 -182
- nautobot/dcim/templates/dcim/cable_trace.html +1 -1
- nautobot/dcim/templates/dcim/console_port_connection_list.html +5 -5
- nautobot/dcim/templates/dcim/consoleport.html +86 -86
- nautobot/dcim/templates/dcim/consoleserverport.html +86 -86
- nautobot/dcim/templates/dcim/controller_create.html +34 -34
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +68 -68
- nautobot/dcim/templates/dcim/device/base.html +1 -104
- nautobot/dcim/templates/dcim/device/config.html +17 -17
- nautobot/dcim/templates/dcim/device/consoleports.html +1 -52
- nautobot/dcim/templates/dcim/device/consoleserverports.html +1 -52
- nautobot/dcim/templates/dcim/device/devicebays.html +1 -48
- nautobot/dcim/templates/dcim/device/frontports.html +1 -52
- nautobot/dcim/templates/dcim/device/interfaces.html +1 -56
- nautobot/dcim/templates/dcim/device/inventory.html +1 -48
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +64 -64
- nautobot/dcim/templates/dcim/device/modulebays.html +1 -48
- nautobot/dcim/templates/dcim/device/poweroutlets.html +1 -52
- nautobot/dcim/templates/dcim/device/powerports.html +1 -52
- nautobot/dcim/templates/dcim/device/rearports.html +1 -52
- nautobot/dcim/templates/dcim/device/status.html +66 -66
- nautobot/dcim/templates/dcim/device/wireless.html +1 -72
- nautobot/dcim/templates/dcim/device.html +4 -422
- nautobot/dcim/templates/dcim/device_component_add.html +25 -25
- nautobot/dcim/templates/dcim/device_create.html +229 -0
- nautobot/dcim/templates/dcim/device_edit.html +2 -227
- nautobot/dcim/templates/dcim/devicebay.html +41 -41
- nautobot/dcim/templates/dcim/devicebay_populate.html +32 -32
- nautobot/dcim/templates/dcim/devicetype_component_add.html +28 -28
- nautobot/dcim/templates/dcim/devicetype_retrieve.html +1 -3
- nautobot/dcim/templates/dcim/frontport.html +84 -84
- nautobot/dcim/templates/dcim/inc/cable_toggle_buttons.html +1 -1
- nautobot/dcim/templates/dcim/inc/device_interface_filter.html +8 -0
- nautobot/dcim/templates/dcim/inc/device_napalm_tabs.html +1 -15
- nautobot/dcim/templates/dcim/inc/location_hierarchy.html +22 -22
- nautobot/dcim/templates/dcim/interface.html +206 -206
- nautobot/dcim/templates/dcim/interface_connection_list.html +5 -5
- nautobot/dcim/templates/dcim/interfaceredundancygroupassociation_create.html +6 -6
- nautobot/dcim/templates/dcim/inventoryitem.html +44 -44
- nautobot/dcim/templates/dcim/inventoryitem_add.html +32 -32
- nautobot/dcim/templates/dcim/inventoryitem_edit.html +22 -22
- nautobot/dcim/templates/dcim/location_migrate_data_to_contact.html +46 -46
- nautobot/dcim/templates/dcim/location_retrieve.html +1 -7
- nautobot/dcim/templates/dcim/locationtype.html +1 -6
- nautobot/dcim/templates/dcim/locationtype_retrieve.html +1 -7
- nautobot/dcim/templates/dcim/module/base.html +85 -85
- nautobot/dcim/templates/dcim/module_interfaces.html +1 -1
- nautobot/dcim/templates/dcim/module_modulebays.html +1 -1
- nautobot/dcim/templates/dcim/module_retrieve.html +52 -52
- nautobot/dcim/templates/dcim/module_update.html +61 -61
- nautobot/dcim/templates/dcim/modulebay_destroy.html +1 -1
- nautobot/dcim/templates/dcim/modulebay_retrieve.html +85 -85
- nautobot/dcim/templates/dcim/modulebay_update.html +33 -33
- nautobot/dcim/templates/dcim/modulefamily_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +140 -144
- nautobot/dcim/templates/dcim/platform_create.html +38 -38
- nautobot/dcim/templates/dcim/power_port_connection_list.html +5 -5
- nautobot/dcim/templates/dcim/powerfeed_retrieve.html +1 -8
- nautobot/dcim/templates/dcim/poweroutlet.html +85 -85
- nautobot/dcim/templates/dcim/powerpanel_retrieve.html +1 -8
- nautobot/dcim/templates/dcim/powerport.html +91 -91
- nautobot/dcim/templates/dcim/rack_elevation_list.html +18 -18
- nautobot/dcim/templates/dcim/rack_retrieve.html +264 -274
- nautobot/dcim/templates/dcim/rackreservation_retrieve.html +0 -3
- nautobot/dcim/templates/dcim/rearport.html +78 -78
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -5
- nautobot/dcim/tests/integration/test_device_bulk_operations.py +3 -2
- nautobot/dcim/tests/integration/test_location_bulk_operations.py +6 -2
- nautobot/dcim/tests/test_api.py +33 -1
- nautobot/dcim/tests/test_views.py +148 -4
- nautobot/dcim/ui.py +29 -0
- nautobot/dcim/urls.py +1 -109
- nautobot/dcim/utils.py +30 -0
- nautobot/dcim/views.py +1009 -531
- nautobot/extras/tables.py +20 -0
- nautobot/extras/templates/extras/computedfield_edit.html +4 -4
- nautobot/extras/templates/extras/configcontext_update.html +1 -1
- nautobot/extras/templates/extras/configcontextschema_retrieve.html +32 -32
- nautobot/extras/templates/extras/customfield_update.html +23 -23
- nautobot/extras/templates/extras/dynamicgroup_retrieve.html +38 -38
- nautobot/extras/templates/extras/dynamicgroup_update.html +62 -62
- nautobot/extras/templates/extras/gitrepository_list.html +10 -10
- nautobot/extras/templates/extras/gitrepository_retrieve.html +68 -68
- nautobot/extras/templates/extras/graphqlquery_retrieve.html +73 -73
- nautobot/extras/templates/extras/inc/configcontext_format.html +2 -2
- nautobot/extras/templates/extras/inc/job_table.html +10 -10
- nautobot/extras/templates/extras/inc/jobresult.html +21 -21
- nautobot/extras/templates/extras/inc/jobresult_js.html +6 -6
- nautobot/extras/templates/extras/inc/tags_panel.html +10 -10
- nautobot/extras/templates/extras/job.html +64 -64
- nautobot/extras/templates/extras/job_approval_request.html +9 -9
- nautobot/extras/templates/extras/job_bulk_edit.html +13 -13
- nautobot/extras/templates/extras/job_edit.html +45 -45
- nautobot/extras/templates/extras/job_list.html +4 -4
- nautobot/extras/templates/extras/jobresult_retrieve.html +0 -25
- nautobot/extras/templates/extras/marketplace.html +101 -101
- nautobot/extras/templates/extras/metadatatype_create.html +20 -20
- nautobot/extras/templates/extras/object_assign_contact_or_team.html +18 -18
- nautobot/extras/templates/extras/object_configcontext.html +1 -3
- nautobot/extras/templates/extras/objectchange.html +2 -165
- nautobot/extras/templates/extras/objectchange_retrieve.html +165 -0
- nautobot/extras/templates/extras/plugin_detail.html +41 -41
- nautobot/extras/templates/extras/plugins_list.html +9 -9
- nautobot/extras/templates/extras/plugins_tiles.html +26 -26
- nautobot/extras/templates/extras/relationship_edit.html +4 -4
- nautobot/extras/templates/extras/role_retrieve.html +13 -13
- nautobot/extras/templates/extras/scheduled_jobs_approval_queue_list.html +21 -21
- nautobot/extras/templates/extras/scheduledjob.html +128 -128
- nautobot/extras/templates/extras/secret_create.html +53 -53
- nautobot/extras/templates/extras/secretsgroup_update.html +13 -13
- nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +3 -3
- nautobot/extras/templates/extras/webhook.html +79 -79
- nautobot/extras/tests/integration/test_relationships.py +6 -6
- nautobot/extras/tests/test_filters.py +1 -1
- nautobot/extras/tests/test_jobs.py +2 -0
- nautobot/extras/tests/test_views.py +3 -3
- nautobot/extras/urls.py +1 -3
- nautobot/extras/views.py +101 -27
- nautobot/ipam/filters.py +2 -2
- nautobot/ipam/migrations/0053_alter_vrfdeviceassignment_options_and_more.py +20 -0
- nautobot/ipam/models.py +34 -0
- nautobot/ipam/tables.py +3 -1
- nautobot/ipam/templates/ipam/inc/prefix_header_extra_content_table.html +4 -0
- nautobot/ipam/templates/ipam/inc/toggle_available.html +8 -8
- nautobot/ipam/templates/ipam/inc/vlangroup_header.html +4 -4
- nautobot/ipam/templates/ipam/ipaddress.html +119 -123
- nautobot/ipam/templates/ipam/ipaddress_assign.html +10 -10
- nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -1
- nautobot/ipam/templates/ipam/ipaddress_merge.html +180 -180
- nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +48 -48
- nautobot/ipam/templates/ipam/prefix.html +2 -107
- nautobot/ipam/templates/ipam/prefix_create.html +34 -0
- nautobot/ipam/templates/ipam/prefix_edit.html +1 -34
- nautobot/ipam/templates/ipam/prefix_retrieve.html +3 -0
- nautobot/ipam/templates/ipam/service_retrieve.html +1 -6
- nautobot/ipam/templates/ipam/vlan_retrieve.html +1 -7
- nautobot/ipam/templates/ipam/vrf_edit.html +1 -1
- nautobot/ipam/tests/test_views.py +34 -0
- nautobot/ipam/ui.py +145 -0
- nautobot/ipam/urls.py +1 -46
- nautobot/ipam/utils/__init__.py +26 -0
- nautobot/ipam/views.py +219 -106
- nautobot/project-static/docs/404.html +11 -11
- nautobot/project-static/docs/apps/index.html +11 -11
- nautobot/project-static/docs/apps/nautobot-apps.html +11 -11
- nautobot/project-static/docs/assets/javascripts/{bundle.92b07e13.min.js → bundle.f55a23d4.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.92b07e13.min.js.map → bundle.f55a23d4.min.js.map} +2 -2
- nautobot/project-static/docs/assets/stylesheets/{main.7e37652d.min.css → main.e53b48f4.min.css} +1 -1
- nautobot/project-static/docs/assets/stylesheets/{main.7e37652d.min.css.map → main.e53b48f4.min.css.map} +1 -1
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2174 -1226
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +11 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +12 -12
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +72 -27
- nautobot/project-static/docs/development/apps/api/configuration-view.html +11 -11
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +11 -11
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +11 -11
- nautobot/project-static/docs/development/apps/api/models/global-search.html +11 -11
- nautobot/project-static/docs/development/apps/api/models/graphql.html +11 -11
- nautobot/project-static/docs/development/apps/api/models/index.html +11 -11
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/prepopulating-data.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +11 -11
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +11 -11
- nautobot/project-static/docs/development/apps/api/prometheus.html +11 -11
- nautobot/project-static/docs/development/apps/api/setup.html +11 -11
- nautobot/project-static/docs/development/apps/api/testing.html +11 -11
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +11 -11
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +11 -11
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +11 -11
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +11 -11
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/base-template.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/index.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/notes.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +11 -11
- nautobot/project-static/docs/development/apps/api/views/urls.html +11 -11
- nautobot/project-static/docs/development/apps/index.html +11 -11
- nautobot/project-static/docs/development/apps/migration/code-updates.html +11 -11
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +11 -11
- nautobot/project-static/docs/development/apps/migration/from-v1.html +11 -11
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +11 -11
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +11 -11
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +11 -11
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +11 -11
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +11 -11
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/breadcrumbs-titles.html +11 -11
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +11 -11
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +11 -11
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +11 -11
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +11 -11
- nautobot/project-static/docs/development/core/application-registry.html +11 -11
- nautobot/project-static/docs/development/core/best-practices.html +11 -11
- nautobot/project-static/docs/development/core/bootstrap-ui.html +11 -11
- nautobot/project-static/docs/development/core/caching.html +11 -11
- nautobot/project-static/docs/development/core/controllers.html +11 -11
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +11 -11
- nautobot/project-static/docs/development/core/generic-views.html +11 -11
- nautobot/project-static/docs/development/core/getting-started.html +50 -48
- nautobot/project-static/docs/development/core/homepage.html +11 -11
- nautobot/project-static/docs/development/core/index.html +11 -11
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +11 -11
- nautobot/project-static/docs/development/core/model-checklist.html +11 -11
- nautobot/project-static/docs/development/core/model-features.html +11 -11
- nautobot/project-static/docs/development/core/natural-keys.html +11 -11
- nautobot/project-static/docs/development/core/navigation-menu.html +11 -11
- nautobot/project-static/docs/development/core/release-checklist.html +11 -11
- nautobot/project-static/docs/development/core/role-internals.html +11 -11
- nautobot/project-static/docs/development/core/settings.html +11 -11
- nautobot/project-static/docs/development/core/style-guide.html +15 -11
- nautobot/project-static/docs/development/core/templates.html +11 -11
- nautobot/project-static/docs/development/core/testing.html +11 -11
- nautobot/project-static/docs/development/core/ui-component-framework.html +11 -11
- nautobot/project-static/docs/development/core/user-preferences.html +11 -11
- nautobot/project-static/docs/development/index.html +11 -11
- nautobot/project-static/docs/development/jobs/getting-started.html +11 -11
- nautobot/project-static/docs/development/jobs/index.html +11 -11
- nautobot/project-static/docs/development/jobs/installation.html +11 -11
- nautobot/project-static/docs/development/jobs/job-extensions.html +11 -11
- nautobot/project-static/docs/development/jobs/job-logging.html +11 -11
- nautobot/project-static/docs/development/jobs/job-patterns.html +11 -11
- nautobot/project-static/docs/development/jobs/job-structure.html +11 -11
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +11 -11
- nautobot/project-static/docs/development/jobs/testing.html +11 -11
- nautobot/project-static/docs/index.html +11 -11
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +11 -11
- nautobot/project-static/docs/overview/design_philosophy.html +11 -11
- nautobot/project-static/docs/release-notes/index.html +11 -11
- nautobot/project-static/docs/release-notes/version-1.0.html +11 -11
- nautobot/project-static/docs/release-notes/version-1.1.html +11 -11
- nautobot/project-static/docs/release-notes/version-1.2.html +11 -11
- nautobot/project-static/docs/release-notes/version-1.3.html +11 -11
- nautobot/project-static/docs/release-notes/version-1.4.html +11 -11
- nautobot/project-static/docs/release-notes/version-1.5.html +11 -11
- nautobot/project-static/docs/release-notes/version-1.6.html +11 -11
- nautobot/project-static/docs/release-notes/version-2.0.html +11 -11
- nautobot/project-static/docs/release-notes/version-2.1.html +11 -11
- nautobot/project-static/docs/release-notes/version-2.2.html +11 -11
- nautobot/project-static/docs/release-notes/version-2.3.html +11 -11
- nautobot/project-static/docs/release-notes/version-2.4.html +196 -11
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +300 -300
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +11 -11
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +11 -11
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +11 -11
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +11 -11
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +11 -11
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +11 -11
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +89 -14
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +11 -11
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +11 -11
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +11 -11
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +11 -11
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +11 -11
- nautobot/project-static/docs/user-guide/administration/installation/index.html +11 -11
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +11 -11
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +11 -11
- nautobot/project-static/docs/user-guide/administration/installation/services.html +11 -11
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +11 -11
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +11 -11
- nautobot/project-static/docs/user-guide/administration/security/index.html +11 -11
- nautobot/project-static/docs/user-guide/administration/security/notices.html +11 -11
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +11 -11
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +11 -11
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +11 -11
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +11 -11
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +11 -11
- nautobot/project-static/docs/user-guide/index.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +11 -11
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +11 -11
- nautobot/tenancy/templates/tenancy/tenant.html +1 -7
- nautobot/tenancy/views.py +13 -0
- nautobot/users/templates/users/api_tokens.html +4 -4
- nautobot/users/templates/users/base.html +28 -28
- nautobot/virtualization/templates/virtualization/cluster.html +64 -64
- nautobot/virtualization/templates/virtualization/inc/virtualmachine_vminterface_filter.html +8 -0
- nautobot/virtualization/templates/virtualization/virtualmachine_component_add.html +25 -25
- nautobot/virtualization/templates/virtualization/virtualmachine_retrieve.html +1 -251
- nautobot/virtualization/templates/virtualization/vminterface.html +70 -70
- nautobot/virtualization/urls.py +0 -12
- nautobot/virtualization/views.py +158 -54
- nautobot/wireless/templates/wireless/wirelessnetwork_create.html +13 -13
- nautobot/wireless/tests/integration/test_radio_profile.py +1 -1
- {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/METADATA +1 -1
- {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/RECORD +581 -570
- nautobot/ipam/templates/ipam/prefix_ipaddresses.html +0 -11
- nautobot/ipam/templates/ipam/prefix_prefixes.html +0 -11
- {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/NOTICE +0 -0
- {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/WHEEL +0 -0
- {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/entry_points.txt +0 -0
nautobot/apps/ui.py
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
from nautobot.core.choices import ButtonColorChoices
|
|
4
4
|
from nautobot.core.ui.base import PermissionsMixin
|
|
5
5
|
from nautobot.core.ui.breadcrumbs import (
|
|
6
|
+
AncestorsBreadcrumbs,
|
|
6
7
|
BaseBreadcrumbItem,
|
|
7
8
|
Breadcrumbs,
|
|
9
|
+
context_object_attr,
|
|
8
10
|
InstanceBreadcrumbItem,
|
|
11
|
+
InstanceParentBreadcrumbItem,
|
|
9
12
|
ModelBreadcrumbItem,
|
|
10
13
|
ViewNameBreadcrumbItem,
|
|
11
14
|
)
|
|
@@ -49,6 +52,7 @@ from nautobot.extras.choices import BannerClassChoices
|
|
|
49
52
|
from nautobot.extras.plugins import Banner, TemplateExtension
|
|
50
53
|
|
|
51
54
|
__all__ = (
|
|
55
|
+
"AncestorsBreadcrumbs",
|
|
52
56
|
"Banner",
|
|
53
57
|
"BannerClassChoices",
|
|
54
58
|
"BaseBreadcrumbItem",
|
|
@@ -66,6 +70,7 @@ __all__ = (
|
|
|
66
70
|
"HomePageItem",
|
|
67
71
|
"HomePagePanel",
|
|
68
72
|
"InstanceBreadcrumbItem",
|
|
73
|
+
"InstanceParentBreadcrumbItem",
|
|
69
74
|
"KeyValueTablePanel",
|
|
70
75
|
"LayoutChoices",
|
|
71
76
|
"ModelBreadcrumbItem",
|
|
@@ -89,5 +94,6 @@ __all__ = (
|
|
|
89
94
|
"TextPanel",
|
|
90
95
|
"Titles",
|
|
91
96
|
"ViewNameBreadcrumbItem",
|
|
97
|
+
"context_object_attr",
|
|
92
98
|
"render_component_template",
|
|
93
99
|
)
|
nautobot/circuits/tables.py
CHANGED
|
@@ -18,7 +18,7 @@ CIRCUIT_TERMINATION_PARENT = """
|
|
|
18
18
|
{% if value.provider_network %}
|
|
19
19
|
{{ value.provider_network|hyperlinked_object }}
|
|
20
20
|
{% elif value.location %}
|
|
21
|
-
{{ value.location|hyperlinked_object }}
|
|
21
|
+
{{ value.location|hyperlinked_object:"name" }}
|
|
22
22
|
{% elif value.cloud_network %}
|
|
23
23
|
{{ value.cloud_network|hyperlinked_object }}
|
|
24
24
|
{% else %}
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
{% endblock %}
|
|
35
35
|
|
|
36
36
|
{% block javascript %}
|
|
37
|
-
{{ block.super }}
|
|
38
|
-
<script type="text/javascript">
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</script>
|
|
37
|
+
{{ block.super }}
|
|
38
|
+
<script type="text/javascript">
|
|
39
|
+
$("a.set_speed").click(function(e) {
|
|
40
|
+
e.preventDefault();
|
|
41
|
+
$("#id_" + $(this).attr("target")).val($(this).attr("data"));
|
|
42
|
+
});
|
|
43
|
+
</script>
|
|
44
44
|
{% endblock %}
|
|
@@ -1,6 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% block extra_breadcrumbs %}
|
|
5
|
-
<li><a href="{% url 'circuits:circuit_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
|
|
6
|
-
{% endblock extra_breadcrumbs %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -25,28 +25,28 @@
|
|
|
25
25
|
<p class="form-control-static">{{ form.term_side.value }}</p>
|
|
26
26
|
</div>
|
|
27
27
|
</div>
|
|
28
|
-
|
|
28
|
+
{% with location_tab_active=form.initial.location %}
|
|
29
29
|
{% with providernetwork_tab_active=form.initial.provider_network %}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
{% with cloudnetwork_tab_active=form.initial.cloud_network %}
|
|
31
|
+
<ul class="nav nav-tabs" role="tablist">
|
|
32
|
+
<li role="presentation"{% if location_tab_active or not providernetwork_tab_active and not cloudnetwork_tab_active %} class="active"{% endif %}><a href="#location" role="tab" data-toggle="tab">Location</a></li>
|
|
33
|
+
<li role="presentation"{% if providernetwork_tab_active %} class="active"{% endif %}><a href="#providernetwork" role="tab" data-toggle="tab">Provider Network</a></li>
|
|
34
|
+
<li role="presentation"{% if cloudnetwork_tab_active %} class="active"{% endif %}><a href="#cloudnetwork" role="tab" data-toggle="tab">Cloud Network</a></li>
|
|
35
|
+
</ul>
|
|
36
|
+
<div class="tab-content">
|
|
37
|
+
<div class="tab-pane{% if location_tab_active or not providernetwork_tab_active and not cloudnetwork_tab_active %} active{% endif %}" id="location">
|
|
38
|
+
{% render_field form.location %}
|
|
39
|
+
</div>
|
|
40
|
+
<div class="tab-pane{% if providernetwork_tab_active %} active{% endif %}" id="providernetwork">
|
|
41
|
+
{% render_field form.provider_network %}
|
|
42
|
+
</div>
|
|
43
|
+
<div class="tab-pane{% if cloudnetwork_tab_active %} active{% endif %}" id="cloudnetwork">
|
|
44
|
+
{% render_field form.cloud_network %}
|
|
45
|
+
</div>
|
|
39
46
|
</div>
|
|
40
|
-
|
|
41
|
-
{% render_field form.provider_network %}
|
|
42
|
-
</div>
|
|
43
|
-
<div class="tab-pane{% if cloudnetwork_tab_active %} active{% endif %}" id="cloudnetwork">
|
|
44
|
-
{% render_field form.cloud_network %}
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
{% endwith %}
|
|
48
|
-
{% endwith %}
|
|
47
|
+
{% endwith %}
|
|
49
48
|
{% endwith %}
|
|
49
|
+
{% endwith %}
|
|
50
50
|
</div>
|
|
51
51
|
</div>
|
|
52
52
|
<div class="panel panel-default">
|
|
@@ -81,11 +81,11 @@
|
|
|
81
81
|
{% endblock %}
|
|
82
82
|
|
|
83
83
|
{% block javascript %}
|
|
84
|
-
{{ block.super }}
|
|
85
|
-
<script type="text/javascript">
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
</script>
|
|
84
|
+
{{ block.super }}
|
|
85
|
+
<script type="text/javascript">
|
|
86
|
+
$("a.set_speed").click(function(e) {
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
$("#id_" + $(this).attr("target")).val($(this).attr("data"));
|
|
89
|
+
});
|
|
90
|
+
</script>
|
|
91
91
|
{% endblock %}
|
|
@@ -12,28 +12,28 @@ In a future release, we should delete this file.
|
|
|
12
12
|
{% if termination %}
|
|
13
13
|
<table class="table table-hover panel-body attr-table">
|
|
14
14
|
{% if termination.location %}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
<tr>
|
|
16
|
+
<td>Location</td>
|
|
17
|
+
<td>
|
|
18
|
+
{% include 'dcim/inc/location_hierarchy.html' with location=termination.location %}
|
|
19
|
+
</td>
|
|
20
|
+
</tr>
|
|
21
|
+
<tr>
|
|
22
|
+
<td>Cable</td>
|
|
23
|
+
<td>
|
|
24
|
+
{% include 'circuits/inc/circuit_termination_cable_fragment.html' %}
|
|
25
|
+
</td>
|
|
26
|
+
</tr>
|
|
27
27
|
{% elif termination.provider_network %}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
<tr>
|
|
29
|
+
<td>Provider Network</td>
|
|
30
|
+
<td>{{ termination.provider_network|hyperlinked_object }}</td>
|
|
31
|
+
</tr>
|
|
32
32
|
{% else %}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
<tr>
|
|
34
|
+
<td>Cloud Network</td>
|
|
35
|
+
<td>{{ termination.cloud_network|hyperlinked_object }}</td>
|
|
36
|
+
</tr>
|
|
37
37
|
{% endif %}
|
|
38
38
|
<tr>
|
|
39
39
|
<td>Speed</td>
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
</a>
|
|
20
20
|
{% endif %}
|
|
21
21
|
{% if termination %}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
<a href="{% url 'circuits:circuittermination' pk=termination.pk %}" class="btn btn-xs btn-default">
|
|
23
|
+
<span class="mdi mdi-information-outline" aria-hidden="true"></span> Detail
|
|
24
|
+
</a>
|
|
25
25
|
{% endif %}
|
|
26
26
|
</div>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{% spaceless %}
|
|
2
|
-
{% load helpers %}
|
|
3
|
-
{% if termination.port_speed and termination.upstream_speed %}
|
|
4
|
-
<i class="mdi mdi-arrow-down-bold" title="Downstream"></i>{{ termination.port_speed|humanize_speed }}
|
|
5
|
-
<i class="mdi mdi-arrow-up-bold" title="Upstream"></i>{{ termination.upstream_speed|humanize_speed }}
|
|
6
|
-
{% else %}
|
|
7
|
-
{{ termination.port_speed|humanize_speed|placeholder }}
|
|
8
|
-
{% endif %}
|
|
2
|
+
{% load helpers %}
|
|
3
|
+
{% if termination.port_speed and termination.upstream_speed %}
|
|
4
|
+
<i class="mdi mdi-arrow-down-bold" title="Downstream"></i>{{ termination.port_speed|humanize_speed }}
|
|
5
|
+
<i class="mdi mdi-arrow-up-bold" title="Upstream"></i>{{ termination.upstream_speed|humanize_speed }}
|
|
6
|
+
{% else %}
|
|
7
|
+
{{ termination.port_speed|humanize_speed|placeholder }}
|
|
8
|
+
{% endif %}
|
|
9
9
|
{% endspaceless %}
|
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
<li><a href="{% url 'circuits:providernetwork_list' %}?provider={{ object.provider_id }}">{{ object.provider }}</a></li>
|
|
4
|
-
{% endblock extra_breadcrumbs %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
nautobot/circuits/views.py
CHANGED
|
@@ -5,7 +5,13 @@ from django.utils.html import format_html, format_html_join
|
|
|
5
5
|
|
|
6
6
|
from nautobot.core.forms import ConfirmationForm
|
|
7
7
|
from nautobot.core.templatetags import helpers
|
|
8
|
-
from nautobot.core.ui.breadcrumbs import
|
|
8
|
+
from nautobot.core.ui.breadcrumbs import (
|
|
9
|
+
Breadcrumbs,
|
|
10
|
+
context_object_attr,
|
|
11
|
+
InstanceBreadcrumbItem,
|
|
12
|
+
InstanceParentBreadcrumbItem,
|
|
13
|
+
ModelBreadcrumbItem,
|
|
14
|
+
)
|
|
9
15
|
from nautobot.core.ui.choices import SectionChoices
|
|
10
16
|
from nautobot.core.ui.object_detail import (
|
|
11
17
|
ObjectDetailContent,
|
|
@@ -101,17 +107,12 @@ class CircuitTerminationUIViewSet(NautobotUIViewSet):
|
|
|
101
107
|
queryset = CircuitTermination.objects.all()
|
|
102
108
|
serializer_class = serializers.CircuitTerminationSerializer
|
|
103
109
|
table_class = tables.CircuitTerminationTable
|
|
104
|
-
|
|
105
110
|
breadcrumbs = Breadcrumbs(
|
|
106
111
|
items={
|
|
107
112
|
"detail": [
|
|
108
|
-
ModelBreadcrumbItem(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
label=lambda c: c["object"].circuit.provider,
|
|
112
|
-
reverse_query_params=lambda c: {"provider": c["object"].circuit.provider.pk},
|
|
113
|
-
),
|
|
114
|
-
InstanceBreadcrumbItem(instance=lambda c: c["object"].circuit),
|
|
113
|
+
ModelBreadcrumbItem(),
|
|
114
|
+
InstanceParentBreadcrumbItem(instance=context_object_attr("circuit"), parent_key="provider"),
|
|
115
|
+
InstanceBreadcrumbItem(instance=context_object_attr("circuit")),
|
|
115
116
|
]
|
|
116
117
|
}
|
|
117
118
|
)
|
|
@@ -191,6 +192,14 @@ class CircuitUIViewSet(NautobotUIViewSet):
|
|
|
191
192
|
queryset = Circuit.objects.all()
|
|
192
193
|
serializer_class = serializers.CircuitSerializer
|
|
193
194
|
table_class = tables.CircuitTable
|
|
195
|
+
breadcrumbs = Breadcrumbs(
|
|
196
|
+
items={
|
|
197
|
+
"detail": [
|
|
198
|
+
ModelBreadcrumbItem(),
|
|
199
|
+
InstanceParentBreadcrumbItem(parent_key="provider"),
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
)
|
|
194
203
|
|
|
195
204
|
class CircuitTerminationPanel(ObjectFieldsPanel):
|
|
196
205
|
def __init__(self, **kwargs):
|
|
@@ -364,6 +373,14 @@ class ProviderNetworkUIViewSet(NautobotUIViewSet):
|
|
|
364
373
|
queryset = ProviderNetwork.objects.all()
|
|
365
374
|
serializer_class = serializers.ProviderNetworkSerializer
|
|
366
375
|
table_class = tables.ProviderNetworkTable
|
|
376
|
+
breadcrumbs = Breadcrumbs(
|
|
377
|
+
items={
|
|
378
|
+
"detail": [
|
|
379
|
+
ModelBreadcrumbItem(),
|
|
380
|
+
InstanceParentBreadcrumbItem(parent_key="provider"),
|
|
381
|
+
]
|
|
382
|
+
}
|
|
383
|
+
)
|
|
367
384
|
|
|
368
385
|
object_detail_content = ObjectDetailContent(
|
|
369
386
|
panels=(
|
|
@@ -1,5 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
<li><a href="{% url 'cloud:cloudaccount_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
|
|
4
|
-
{% endblock extra_breadcrumbs %}
|
|
5
|
-
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -1,8 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% block extra_breadcrumbs %}
|
|
5
|
-
{% if object.parent %}
|
|
6
|
-
<li>{{ object.parent|hyperlinked_object:"name" }}</li>
|
|
7
|
-
{% endif %}
|
|
8
|
-
{% endblock extra_breadcrumbs %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
<li><a href="{% url 'cloud:cloudresourcetype_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
|
|
4
|
-
{% endblock extra_breadcrumbs %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -1,6 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% block extra_breadcrumbs %}
|
|
5
|
-
<li><a href="{% url 'cloud:cloudresourcetype' pk=object.cloud_resource_type.pk %}">{{ object.cloud_resource_type }}</a></li>
|
|
6
|
-
{% endblock extra_breadcrumbs %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
nautobot/cloud/views.py
CHANGED
|
@@ -31,6 +31,13 @@ from nautobot.cloud.forms import (
|
|
|
31
31
|
from nautobot.cloud.models import CloudAccount, CloudNetwork, CloudResourceType, CloudService
|
|
32
32
|
from nautobot.cloud.tables import CloudAccountTable, CloudNetworkTable, CloudResourceTypeTable, CloudServiceTable
|
|
33
33
|
from nautobot.core.ui import object_detail
|
|
34
|
+
from nautobot.core.ui.breadcrumbs import (
|
|
35
|
+
Breadcrumbs,
|
|
36
|
+
context_object_attr,
|
|
37
|
+
InstanceBreadcrumbItem,
|
|
38
|
+
InstanceParentBreadcrumbItem,
|
|
39
|
+
ModelBreadcrumbItem,
|
|
40
|
+
)
|
|
34
41
|
from nautobot.core.ui.choices import SectionChoices
|
|
35
42
|
from nautobot.core.views.viewsets import NautobotUIViewSet
|
|
36
43
|
from nautobot.ipam.tables import PrefixTable
|
|
@@ -44,6 +51,16 @@ class CloudAccountUIViewSet(NautobotUIViewSet):
|
|
|
44
51
|
serializer_class = CloudAccountSerializer
|
|
45
52
|
table_class = CloudAccountTable
|
|
46
53
|
form_class = CloudAccountForm
|
|
54
|
+
breadcrumbs = Breadcrumbs(
|
|
55
|
+
items={
|
|
56
|
+
"detail": [
|
|
57
|
+
ModelBreadcrumbItem(),
|
|
58
|
+
InstanceParentBreadcrumbItem(
|
|
59
|
+
parent_key="provider",
|
|
60
|
+
),
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
)
|
|
47
64
|
|
|
48
65
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
49
66
|
panels=(
|
|
@@ -64,6 +81,17 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
|
|
|
64
81
|
table_class = CloudNetworkTable
|
|
65
82
|
form_class = CloudNetworkForm
|
|
66
83
|
bulk_update_form_class = CloudNetworkBulkEditForm
|
|
84
|
+
breadcrumbs = Breadcrumbs(
|
|
85
|
+
items={
|
|
86
|
+
"detail": [
|
|
87
|
+
ModelBreadcrumbItem(model_key="object"),
|
|
88
|
+
InstanceBreadcrumbItem(
|
|
89
|
+
instance=context_object_attr("parent"), should_render=context_object_attr("parent")
|
|
90
|
+
),
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
|
|
67
95
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
68
96
|
panels=(
|
|
69
97
|
object_detail.ObjectFieldsPanel(
|
|
@@ -197,6 +225,15 @@ class CloudResourceTypeUIViewSet(NautobotUIViewSet):
|
|
|
197
225
|
table_class = CloudResourceTypeTable
|
|
198
226
|
form_class = CloudResourceTypeForm
|
|
199
227
|
bulk_update_form_class = CloudResourceTypeBulkEditForm
|
|
228
|
+
breadcrumbs = Breadcrumbs(
|
|
229
|
+
items={
|
|
230
|
+
"detail": [
|
|
231
|
+
ModelBreadcrumbItem(),
|
|
232
|
+
InstanceParentBreadcrumbItem(parent_key="provider"),
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
|
|
200
237
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
201
238
|
panels=(
|
|
202
239
|
object_detail.ObjectFieldsPanel(
|
|
@@ -277,6 +314,14 @@ class CloudServiceUIViewSet(NautobotUIViewSet):
|
|
|
277
314
|
table_class = CloudServiceTable
|
|
278
315
|
form_class = CloudServiceForm
|
|
279
316
|
bulk_update_form_class = CloudServiceBulkEditForm
|
|
317
|
+
breadcrumbs = Breadcrumbs(
|
|
318
|
+
items={
|
|
319
|
+
"detail": [
|
|
320
|
+
ModelBreadcrumbItem(),
|
|
321
|
+
InstanceBreadcrumbItem(instance=context_object_attr("cloud_resource_type")),
|
|
322
|
+
]
|
|
323
|
+
}
|
|
324
|
+
)
|
|
280
325
|
|
|
281
326
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
282
327
|
panels=(
|
|
@@ -67,15 +67,18 @@ def generate_filter_resolver(schema_type, resolver_name, field_name):
|
|
|
67
67
|
"""
|
|
68
68
|
filterset_class = schema_type._meta.filterset_class
|
|
69
69
|
|
|
70
|
+
@gql_optimizer.resolver_hints(model_field=field_name)
|
|
70
71
|
def resolve_filter(self, info, **kwargs):
|
|
72
|
+
field = getattr(self, field_name)
|
|
73
|
+
|
|
71
74
|
if not filterset_class or not kwargs:
|
|
72
|
-
return
|
|
75
|
+
return field.all()
|
|
73
76
|
|
|
74
77
|
# Inverse of substitution logic from get_filtering_args_from_filterset() - transform "_type" back to "type"
|
|
75
78
|
if "_type" in kwargs:
|
|
76
79
|
kwargs["type"] = kwargs.pop("_type")
|
|
77
80
|
|
|
78
|
-
resolved_obj = filterset_class(kwargs,
|
|
81
|
+
resolved_obj = filterset_class(kwargs, field.all())
|
|
79
82
|
|
|
80
83
|
# Check result filter for errors.
|
|
81
84
|
if not resolved_obj.errors:
|
|
@@ -7,10 +7,9 @@ from django.core.exceptions import (
|
|
|
7
7
|
)
|
|
8
8
|
from django.db.models import ManyToManyField, ProtectedError
|
|
9
9
|
|
|
10
|
-
from nautobot.core import exceptions
|
|
11
10
|
from nautobot.core.forms.utils import restrict_form_fields
|
|
12
|
-
from nautobot.core.utils.
|
|
13
|
-
from nautobot.core.utils
|
|
11
|
+
from nautobot.core.utils.lookup import get_form_for_model
|
|
12
|
+
from nautobot.core.views.utils import get_bulk_queryset_from_view
|
|
14
13
|
from nautobot.extras.context_managers import deferred_change_logging_for_bulk_operation
|
|
15
14
|
from nautobot.extras.jobs import (
|
|
16
15
|
BooleanVar,
|
|
@@ -19,6 +18,7 @@ from nautobot.extras.jobs import (
|
|
|
19
18
|
ObjectVar,
|
|
20
19
|
RunJobTaskFailed,
|
|
21
20
|
)
|
|
21
|
+
from nautobot.extras.models import SavedView
|
|
22
22
|
from nautobot.extras.utils import bulk_delete_with_bulk_change_logging, remove_prefix_from_cf_key
|
|
23
23
|
|
|
24
24
|
name = "System Jobs"
|
|
@@ -32,8 +32,10 @@ class BulkEditObjects(Job):
|
|
|
32
32
|
description="Type of objects to update",
|
|
33
33
|
)
|
|
34
34
|
form_data = JSONVar(description="BulkEditForm data")
|
|
35
|
+
pk_list = JSONVar(description="List of objects pks to edit", required=False)
|
|
35
36
|
edit_all = BooleanVar(description="Bulk Edit all object / all filtered objects", required=False)
|
|
36
37
|
filter_query_params = JSONVar(label="Filter Query Params", required=False)
|
|
38
|
+
saved_view = ObjectVar(model=SavedView, required=False)
|
|
37
39
|
|
|
38
40
|
class Meta:
|
|
39
41
|
name = "Bulk Edit Objects"
|
|
@@ -41,42 +43,14 @@ class BulkEditObjects(Job):
|
|
|
41
43
|
has_sensitive_variables = False
|
|
42
44
|
soft_time_limit = 1800
|
|
43
45
|
time_limit = 2000
|
|
46
|
+
hidden = True
|
|
47
|
+
|
|
48
|
+
def _update_objects(self, model, form, filter_query_params, pk_list, edit_all, nullified_fields, saved_view_id):
|
|
49
|
+
base_queryset = model.objects.restrict(self.user, "change")
|
|
50
|
+
queryset = get_bulk_queryset_from_view(user=self.user, action="change", log=self.logger, **self.key_params)
|
|
44
51
|
|
|
45
|
-
def _update_objects(self, model, form, filter_query_params, edit_all, nullified_fields):
|
|
46
52
|
with deferred_change_logging_for_bulk_operation():
|
|
47
|
-
base_queryset = model.objects.restrict(self.user, "change")
|
|
48
53
|
updated_objects_pk = []
|
|
49
|
-
filterset_cls = get_filterset_for_model(model)
|
|
50
|
-
|
|
51
|
-
if filter_query_params:
|
|
52
|
-
if not filterset_cls:
|
|
53
|
-
self.logger.error(f"Filterset not found for {model._meta.verbose_name}")
|
|
54
|
-
raise RunJobTaskFailed(
|
|
55
|
-
f"Filter query provided but {model._meta.verbose_name} does not have a filterset."
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
# Discarding non-filter query params
|
|
59
|
-
new_filter_query_params = {}
|
|
60
|
-
|
|
61
|
-
for key, value in filter_query_params.items():
|
|
62
|
-
try:
|
|
63
|
-
get_filterset_field(filterset_cls(), key)
|
|
64
|
-
new_filter_query_params[key] = value
|
|
65
|
-
except exceptions.FilterSetFieldNotFound:
|
|
66
|
-
self.logger.debug(
|
|
67
|
-
f"Query parameter `{key}` not found in filterset for `{filterset_cls}`, discarding it"
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
filter_query_params = new_filter_query_params
|
|
71
|
-
|
|
72
|
-
if edit_all:
|
|
73
|
-
if filter_query_params:
|
|
74
|
-
queryset = filterset_cls(filter_query_params).qs.restrict(self.user, "change")
|
|
75
|
-
else:
|
|
76
|
-
queryset = model.objects.restrict(self.user, "change")
|
|
77
|
-
else:
|
|
78
|
-
queryset = model.objects.restrict(self.user, "change").filter(pk__in=form.cleaned_data["pk"])
|
|
79
|
-
|
|
80
54
|
form_custom_fields = getattr(form, "custom_fields", [])
|
|
81
55
|
form_relationships = getattr(form, "relationships", [])
|
|
82
56
|
standard_fields = [
|
|
@@ -130,14 +104,18 @@ class BulkEditObjects(Job):
|
|
|
130
104
|
if hasattr(form, "save_note") and callable(form.save_note):
|
|
131
105
|
form.save_note(instance=obj, user=self.user)
|
|
132
106
|
total_updated_objs = len(updated_objects_pk)
|
|
133
|
-
# Enforce object-level permissions
|
|
107
|
+
# Enforce object-level permissions. This works because we used .restrict() above and if the user
|
|
108
|
+
# doesn't have permission to change one of the objects after the change, it won't be in base_queryset
|
|
109
|
+
# filtered to the pks of the objects we just changed.
|
|
134
110
|
if base_queryset.filter(pk__in=updated_objects_pk).count() != total_updated_objs:
|
|
135
111
|
raise ObjectDoesNotExist
|
|
136
112
|
return total_updated_objs
|
|
137
113
|
|
|
138
|
-
def _process_valid_form(self, model, form, filter_query_params, edit_all, nullified_fields):
|
|
114
|
+
def _process_valid_form(self, model, form, filter_query_params, pk_list, edit_all, nullified_fields, saved_view_id):
|
|
139
115
|
try:
|
|
140
|
-
total_updated_objs = self._update_objects(
|
|
116
|
+
total_updated_objs = self._update_objects(
|
|
117
|
+
model, form, filter_query_params, pk_list, edit_all, nullified_fields, saved_view_id
|
|
118
|
+
)
|
|
141
119
|
msg = f"Updated {total_updated_objs} {model._meta.verbose_name_plural}"
|
|
142
120
|
self.logger.info(msg)
|
|
143
121
|
return msg
|
|
@@ -149,12 +127,24 @@ class BulkEditObjects(Job):
|
|
|
149
127
|
raise RunJobTaskFailed("Bulk Edit not fully successful, see logs")
|
|
150
128
|
|
|
151
129
|
def run( # pylint: disable=arguments-differ
|
|
152
|
-
self, *, content_type, form_data, edit_all=False, filter_query_params=None
|
|
130
|
+
self, *, content_type, form_data, pk_list=None, edit_all=False, filter_query_params=None, saved_view=None
|
|
153
131
|
):
|
|
132
|
+
saved_view_id = saved_view.pk if saved_view is not None else None
|
|
133
|
+
if not filter_query_params:
|
|
134
|
+
filter_query_params = {}
|
|
135
|
+
|
|
154
136
|
if not self.user.has_perm(f"{content_type.app_label}.change_{content_type.model}"):
|
|
155
137
|
self.logger.error('User "%s" does not have permission to update %s objects', self.user, content_type.model)
|
|
156
138
|
raise PermissionDenied("User does not have change permissions on the requested content-type")
|
|
157
139
|
|
|
140
|
+
self.key_params = {
|
|
141
|
+
"content_type": content_type,
|
|
142
|
+
"edit_all": edit_all,
|
|
143
|
+
"filter_query_params": filter_query_params,
|
|
144
|
+
"pk_list": pk_list,
|
|
145
|
+
"saved_view_id": saved_view_id,
|
|
146
|
+
}
|
|
147
|
+
|
|
158
148
|
model = content_type.model_class()
|
|
159
149
|
if model is None:
|
|
160
150
|
self.logger.error(
|
|
@@ -178,7 +168,9 @@ class BulkEditObjects(Job):
|
|
|
178
168
|
if form.is_valid():
|
|
179
169
|
self.logger.debug("Form validation was successful")
|
|
180
170
|
nullified_fields = form_data.get("_nullify")
|
|
181
|
-
return self._process_valid_form(
|
|
171
|
+
return self._process_valid_form(
|
|
172
|
+
model, form, filter_query_params, pk_list, edit_all, nullified_fields, saved_view_id
|
|
173
|
+
)
|
|
182
174
|
else:
|
|
183
175
|
self.logger.error(f"Form validation unsuccessful: {form.errors.as_json()}")
|
|
184
176
|
|
|
@@ -197,6 +189,7 @@ class BulkDeleteObjects(Job):
|
|
|
197
189
|
pk_list = JSONVar(description="List of objects pks to delete", required=False)
|
|
198
190
|
delete_all = BooleanVar(description="Delete all (filtered) objects instead of a list of PKs", required=False)
|
|
199
191
|
filter_query_params = JSONVar(label="Filter Query Params", required=False)
|
|
192
|
+
saved_view = ObjectVar(model=SavedView, required=False)
|
|
200
193
|
|
|
201
194
|
class Meta:
|
|
202
195
|
name = "Bulk Delete Objects"
|
|
@@ -204,14 +197,26 @@ class BulkDeleteObjects(Job):
|
|
|
204
197
|
has_sensitive_variables = False
|
|
205
198
|
soft_time_limit = 1800
|
|
206
199
|
time_limit = 2000
|
|
200
|
+
hidden = True
|
|
207
201
|
|
|
208
202
|
def run( # pylint: disable=arguments-differ
|
|
209
|
-
self, *, content_type, pk_list=None, delete_all=False, filter_query_params=None
|
|
203
|
+
self, *, content_type, pk_list=None, delete_all=False, filter_query_params=None, saved_view=None
|
|
210
204
|
):
|
|
205
|
+
saved_view_id = saved_view.pk if saved_view is not None else None
|
|
206
|
+
if not filter_query_params:
|
|
207
|
+
filter_query_params = {}
|
|
211
208
|
if not self.user.has_perm(f"{content_type.app_label}.delete_{content_type.model}"):
|
|
212
209
|
self.logger.error('User "%s" does not have permission to delete %s objects', self.user, content_type.model)
|
|
213
210
|
raise PermissionDenied("User does not have delete permissions on the requested content-type")
|
|
214
211
|
|
|
212
|
+
key_params = {
|
|
213
|
+
"content_type": content_type,
|
|
214
|
+
"delete_all": delete_all,
|
|
215
|
+
"filter_query_params": filter_query_params,
|
|
216
|
+
"pk_list": pk_list,
|
|
217
|
+
"saved_view_id": saved_view_id,
|
|
218
|
+
}
|
|
219
|
+
|
|
215
220
|
model = content_type.model_class()
|
|
216
221
|
if model is None:
|
|
217
222
|
self.logger.error(
|
|
@@ -221,49 +226,7 @@ class BulkDeleteObjects(Job):
|
|
|
221
226
|
)
|
|
222
227
|
raise RunJobTaskFailed("Model not found")
|
|
223
228
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if filter_query_params:
|
|
227
|
-
if not filterset_cls:
|
|
228
|
-
self.logger.error(f"Filterset not found for {model._meta.verbose_name}")
|
|
229
|
-
raise RunJobTaskFailed(
|
|
230
|
-
f"Filter query provided but {model._meta.verbose_name} does not have a filterset."
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
# Discarding non-filter query params
|
|
234
|
-
new_filter_query_params = {}
|
|
235
|
-
|
|
236
|
-
for key, value in filter_query_params.items():
|
|
237
|
-
try:
|
|
238
|
-
get_filterset_field(filterset_cls(), key)
|
|
239
|
-
new_filter_query_params[key] = value
|
|
240
|
-
except exceptions.FilterSetFieldNotFound:
|
|
241
|
-
self.logger.debug(f"Query parameter `{key}` not found in `{filterset_cls}`, discarding it")
|
|
242
|
-
|
|
243
|
-
filter_query_params = new_filter_query_params
|
|
244
|
-
|
|
245
|
-
if delete_all:
|
|
246
|
-
# Case for selecting all objects (or all filtered objects) to delete
|
|
247
|
-
if filter_query_params:
|
|
248
|
-
# If there is filter query params, we need to apply it to the queryset
|
|
249
|
-
queryset = filterset_cls(filter_query_params).qs.restrict(self.user, "delete")
|
|
250
|
-
# We take this approach because filterset.qs has already applied .distinct(),
|
|
251
|
-
# and performing a .delete directly on a queryset with .distinct applied is not allowed.
|
|
252
|
-
queryset = model.objects.filter(pk__in=queryset)
|
|
253
|
-
else:
|
|
254
|
-
# If there is not, we can just restrict the queryset to the user's permissions
|
|
255
|
-
queryset = model.objects.restrict(self.user, "delete")
|
|
256
|
-
elif pk_list:
|
|
257
|
-
# Case for selecting specific objects to delete, delete_all overrides this option
|
|
258
|
-
queryset = model.objects.restrict(self.user, "delete").filter(pk__in=pk_list)
|
|
259
|
-
if queryset.count() < len(pk_list):
|
|
260
|
-
# We do not check ObjectPermission error for `delete_all` case because user is trying to
|
|
261
|
-
# delete all objs they have permission to which would not raise any issue.
|
|
262
|
-
self.logger.error("You do not have permissions to delete some of the objects provided in `pk_list`.")
|
|
263
|
-
raise RunJobTaskFailed("Caught ObjectPermission error while attempting to delete objects")
|
|
264
|
-
elif not pk_list and not delete_all:
|
|
265
|
-
self.logger.error("You must select at least one object instance to delete.")
|
|
266
|
-
raise RunJobTaskFailed("Either `pk_list` or `delete_all` is required.")
|
|
229
|
+
queryset = get_bulk_queryset_from_view(user=self.user, action="delete", log=self.logger, **key_params)
|
|
267
230
|
|
|
268
231
|
verbose_name_plural = model._meta.verbose_name_plural
|
|
269
232
|
|