# Views & Inheritance Views are organized by resource type (e.g., devices, mappings, VMs) in the `views/` directory. The codebase uses a layered approach to views, leveraging inheritance and mixins to maximize code reuse and maintainability. ### View Organization **Resource-specific views:** - Device and VM sync tabs live under `object_sync/` (see `object_sync/devices.py` and `object_sync/vms.py`), while mappings/settings/status views remain as individual modules alongside the package. - The LibreNMS import workflow is grouped under `views/imports/`: `list.py` renders the main table view and `actions.py` contains the HTMX endpoints (preview, validation, bulk execute). All legacy handlers formerly in `librenms_import_views.py` and `device_import_views.py` were folded into this package. **Base views:** - The `base/` subdirectory contains abstract base views (e.g., `BaseLibreNMSSyncView`, `BaseInterfaceTableView`, `BaseCableTableView`, `BaseIPAddressTableView`, `BaseVLANTableView`) that encapsulate shared logic for related resources. **Mixins:** - Shared behaviors (e.g., API access, caching) are factored into mixins in `mixins.py` and combined with base or resource-specific views as needed. ### Inheritance Patterns - Most resource-specific views inherit from a base view in `base/` and one or more mixins. - Base views themselves often inherit from NetBox or Django generic views (e.g., `generic.ObjectListView`, `django.views.View`). - This allows resource-specific views to override or extend only the methods they need, while inheriting default behaviors from base classes and mixins. #### Example: Device Sync View ```python from .base.librenms_sync_view import BaseLibreNMSSyncView from .mixins import LibreNMSAPIMixin class DeviceLibreNMSSyncView(BaseLibreNMSSyncView): # Inherits API access and sync logic from base/mixins # Only device-specific logic needs to be implemented here ... ``` #### Example: Interface Table View ```python from .base.interfaces_view import BaseInterfaceTableView from .mixins import CacheMixin, LibreNMSAPIMixin class DeviceInterfaceTableView(BaseInterfaceTableView): model = Device # Implements get_interfaces and get_redirect_url for devices ... ``` #### Example: VLAN Table View ```python from .base.vlan_table_view import BaseVLANTableView class DeviceVLANTableView(BaseVLANTableView): model = Device # Inherits VLAN comparison, group resolution, and caching from base view # Only the model attribute needs to be set ... ``` `BaseVLANTableView` additionally inherits `VlanAssignmentMixin` for VLAN group scope resolution. It fetches device VLANs from LibreNMS, compares them against NetBox VLAN objects across relevant VLAN groups, and renders a color-coded table with per-VLAN group dropdowns. ### Customizing or Adding Views - To add a new view for a resource, inherit from the relevant base view and mixins, then override or extend methods as needed. - Use the base views as templates for structure and required methods. - Register new views in `urls.py` and add templates if needed. ### Tips - Check the `base/` directory for reusable logic before writing new view code. - Use mixins for cross-cutting concerns (API, caching, permissions). - Keep resource-specific views focused on their unique logic; delegate shared logic to base classes and mixins.