filters.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. from __future__ import unicode_literals
  2. import django_filters
  3. from django.contrib.auth.models import User
  4. from django.db.models import Q
  5. from netaddr import EUI
  6. from netaddr.core import AddrFormatError
  7. from extras.filters import CustomFieldFilterSet
  8. from tenancy.models import Tenant
  9. from utilities.filters import NullableCharFieldFilter, NumericInFilter
  10. from virtualization.models import Cluster
  11. from .constants import (
  12. DEVICE_STATUS_CHOICES, IFACE_FF_LAG, NONCONNECTABLE_IFACE_TYPES, SITE_STATUS_CHOICES, VIRTUAL_IFACE_TYPES,
  13. WIRELESS_IFACE_TYPES,
  14. )
  15. from .models import (
  16. ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
  17. DeviceBayTemplate, DeviceRole, DeviceType, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer,
  18. InventoryItem, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup,
  19. RackReservation, RackRole, Region, Site, VirtualChassis,
  20. )
  21. class RegionFilter(django_filters.FilterSet):
  22. q = django_filters.CharFilter(
  23. method='search',
  24. label='Search',
  25. )
  26. parent_id = django_filters.ModelMultipleChoiceFilter(
  27. queryset=Region.objects.all(),
  28. label='Parent region (ID)',
  29. )
  30. parent = django_filters.ModelMultipleChoiceFilter(
  31. name='parent__slug',
  32. queryset=Region.objects.all(),
  33. to_field_name='slug',
  34. label='Parent region (slug)',
  35. )
  36. class Meta:
  37. model = Region
  38. fields = ['name', 'slug']
  39. def search(self, queryset, name, value):
  40. if not value.strip():
  41. return queryset
  42. qs_filter = (
  43. Q(name__icontains=value) |
  44. Q(slug__icontains=value)
  45. )
  46. return queryset.filter(qs_filter)
  47. class SiteFilter(CustomFieldFilterSet, django_filters.FilterSet):
  48. id__in = NumericInFilter(name='id', lookup_expr='in')
  49. q = django_filters.CharFilter(
  50. method='search',
  51. label='Search',
  52. )
  53. status = django_filters.MultipleChoiceFilter(
  54. choices=SITE_STATUS_CHOICES,
  55. null_value=None
  56. )
  57. region_id = django_filters.ModelMultipleChoiceFilter(
  58. queryset=Region.objects.all(),
  59. label='Region (ID)',
  60. )
  61. region = django_filters.ModelMultipleChoiceFilter(
  62. name='region__slug',
  63. queryset=Region.objects.all(),
  64. to_field_name='slug',
  65. label='Region (slug)',
  66. )
  67. tenant_id = django_filters.ModelMultipleChoiceFilter(
  68. queryset=Tenant.objects.all(),
  69. label='Tenant (ID)',
  70. )
  71. tenant = django_filters.ModelMultipleChoiceFilter(
  72. name='tenant__slug',
  73. queryset=Tenant.objects.all(),
  74. to_field_name='slug',
  75. label='Tenant (slug)',
  76. )
  77. tag = django_filters.CharFilter(
  78. name='tags__slug',
  79. )
  80. class Meta:
  81. model = Site
  82. fields = ['q', 'name', 'slug', 'facility', 'asn', 'contact_name', 'contact_phone', 'contact_email']
  83. def search(self, queryset, name, value):
  84. if not value.strip():
  85. return queryset
  86. qs_filter = (
  87. Q(name__icontains=value) |
  88. Q(facility__icontains=value) |
  89. Q(description__icontains=value) |
  90. Q(physical_address__icontains=value) |
  91. Q(shipping_address__icontains=value) |
  92. Q(contact_name__icontains=value) |
  93. Q(contact_phone__icontains=value) |
  94. Q(contact_email__icontains=value) |
  95. Q(comments__icontains=value)
  96. )
  97. try:
  98. qs_filter |= Q(asn=int(value.strip()))
  99. except ValueError:
  100. pass
  101. return queryset.filter(qs_filter)
  102. class RackGroupFilter(django_filters.FilterSet):
  103. site_id = django_filters.ModelMultipleChoiceFilter(
  104. queryset=Site.objects.all(),
  105. label='Site (ID)',
  106. )
  107. site = django_filters.ModelMultipleChoiceFilter(
  108. name='site__slug',
  109. queryset=Site.objects.all(),
  110. to_field_name='slug',
  111. label='Site (slug)',
  112. )
  113. class Meta:
  114. model = RackGroup
  115. fields = ['site_id', 'name', 'slug']
  116. class RackRoleFilter(django_filters.FilterSet):
  117. class Meta:
  118. model = RackRole
  119. fields = ['name', 'slug', 'color']
  120. class RackFilter(CustomFieldFilterSet, django_filters.FilterSet):
  121. id__in = NumericInFilter(name='id', lookup_expr='in')
  122. q = django_filters.CharFilter(
  123. method='search',
  124. label='Search',
  125. )
  126. facility_id = NullableCharFieldFilter()
  127. site_id = django_filters.ModelMultipleChoiceFilter(
  128. queryset=Site.objects.all(),
  129. label='Site (ID)',
  130. )
  131. site = django_filters.ModelMultipleChoiceFilter(
  132. name='site__slug',
  133. queryset=Site.objects.all(),
  134. to_field_name='slug',
  135. label='Site (slug)',
  136. )
  137. group_id = django_filters.ModelMultipleChoiceFilter(
  138. queryset=RackGroup.objects.all(),
  139. label='Group (ID)',
  140. )
  141. group = django_filters.ModelMultipleChoiceFilter(
  142. name='group__slug',
  143. queryset=RackGroup.objects.all(),
  144. to_field_name='slug',
  145. label='Group',
  146. )
  147. tenant_id = django_filters.ModelMultipleChoiceFilter(
  148. queryset=Tenant.objects.all(),
  149. label='Tenant (ID)',
  150. )
  151. tenant = django_filters.ModelMultipleChoiceFilter(
  152. name='tenant__slug',
  153. queryset=Tenant.objects.all(),
  154. to_field_name='slug',
  155. label='Tenant (slug)',
  156. )
  157. role_id = django_filters.ModelMultipleChoiceFilter(
  158. queryset=RackRole.objects.all(),
  159. label='Role (ID)',
  160. )
  161. role = django_filters.ModelMultipleChoiceFilter(
  162. name='role__slug',
  163. queryset=RackRole.objects.all(),
  164. to_field_name='slug',
  165. label='Role (slug)',
  166. )
  167. tag = django_filters.CharFilter(
  168. name='tags__slug',
  169. )
  170. class Meta:
  171. model = Rack
  172. fields = ['name', 'serial', 'type', 'width', 'u_height', 'desc_units']
  173. def search(self, queryset, name, value):
  174. if not value.strip():
  175. return queryset
  176. return queryset.filter(
  177. Q(name__icontains=value) |
  178. Q(facility_id__icontains=value) |
  179. Q(serial__icontains=value.strip()) |
  180. Q(comments__icontains=value)
  181. )
  182. class RackReservationFilter(django_filters.FilterSet):
  183. id__in = NumericInFilter(name='id', lookup_expr='in')
  184. q = django_filters.CharFilter(
  185. method='search',
  186. label='Search',
  187. )
  188. rack_id = django_filters.ModelMultipleChoiceFilter(
  189. queryset=Rack.objects.all(),
  190. label='Rack (ID)',
  191. )
  192. site_id = django_filters.ModelMultipleChoiceFilter(
  193. name='rack__site',
  194. queryset=Site.objects.all(),
  195. label='Site (ID)',
  196. )
  197. site = django_filters.ModelMultipleChoiceFilter(
  198. name='rack__site__slug',
  199. queryset=Site.objects.all(),
  200. to_field_name='slug',
  201. label='Site (slug)',
  202. )
  203. group_id = django_filters.ModelMultipleChoiceFilter(
  204. name='rack__group',
  205. queryset=RackGroup.objects.all(),
  206. label='Group (ID)',
  207. )
  208. group = django_filters.ModelMultipleChoiceFilter(
  209. name='rack__group__slug',
  210. queryset=RackGroup.objects.all(),
  211. to_field_name='slug',
  212. label='Group',
  213. )
  214. tenant_id = django_filters.ModelMultipleChoiceFilter(
  215. queryset=Tenant.objects.all(),
  216. label='Tenant (ID)',
  217. )
  218. tenant = django_filters.ModelMultipleChoiceFilter(
  219. name='tenant__slug',
  220. queryset=Tenant.objects.all(),
  221. to_field_name='slug',
  222. label='Tenant (slug)',
  223. )
  224. user_id = django_filters.ModelMultipleChoiceFilter(
  225. queryset=User.objects.all(),
  226. label='User (ID)',
  227. )
  228. user = django_filters.ModelMultipleChoiceFilter(
  229. name='user',
  230. queryset=User.objects.all(),
  231. to_field_name='username',
  232. label='User (name)',
  233. )
  234. class Meta:
  235. model = RackReservation
  236. fields = ['created']
  237. def search(self, queryset, name, value):
  238. if not value.strip():
  239. return queryset
  240. return queryset.filter(
  241. Q(rack__name__icontains=value) |
  242. Q(rack__facility_id__icontains=value) |
  243. Q(user__username__icontains=value) |
  244. Q(description__icontains=value)
  245. )
  246. class ManufacturerFilter(django_filters.FilterSet):
  247. class Meta:
  248. model = Manufacturer
  249. fields = ['name', 'slug']
  250. class DeviceTypeFilter(CustomFieldFilterSet, django_filters.FilterSet):
  251. id__in = NumericInFilter(name='id', lookup_expr='in')
  252. q = django_filters.CharFilter(
  253. method='search',
  254. label='Search',
  255. )
  256. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  257. queryset=Manufacturer.objects.all(),
  258. label='Manufacturer (ID)',
  259. )
  260. manufacturer = django_filters.ModelMultipleChoiceFilter(
  261. name='manufacturer__slug',
  262. queryset=Manufacturer.objects.all(),
  263. to_field_name='slug',
  264. label='Manufacturer (slug)',
  265. )
  266. tag = django_filters.CharFilter(
  267. name='tags__slug',
  268. )
  269. class Meta:
  270. model = DeviceType
  271. fields = [
  272. 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'is_console_server', 'is_pdu',
  273. 'is_network_device', 'subdevice_role',
  274. ]
  275. def search(self, queryset, name, value):
  276. if not value.strip():
  277. return queryset
  278. return queryset.filter(
  279. Q(manufacturer__name__icontains=value) |
  280. Q(model__icontains=value) |
  281. Q(part_number__icontains=value) |
  282. Q(comments__icontains=value)
  283. )
  284. class DeviceTypeComponentFilterSet(django_filters.FilterSet):
  285. devicetype_id = django_filters.ModelMultipleChoiceFilter(
  286. queryset=DeviceType.objects.all(),
  287. name='device_type_id',
  288. label='Device type (ID)',
  289. )
  290. class ConsolePortTemplateFilter(DeviceTypeComponentFilterSet):
  291. class Meta:
  292. model = ConsolePortTemplate
  293. fields = ['name']
  294. class ConsoleServerPortTemplateFilter(DeviceTypeComponentFilterSet):
  295. class Meta:
  296. model = ConsoleServerPortTemplate
  297. fields = ['name']
  298. class PowerPortTemplateFilter(DeviceTypeComponentFilterSet):
  299. class Meta:
  300. model = PowerPortTemplate
  301. fields = ['name']
  302. class PowerOutletTemplateFilter(DeviceTypeComponentFilterSet):
  303. class Meta:
  304. model = PowerOutletTemplate
  305. fields = ['name']
  306. class InterfaceTemplateFilter(DeviceTypeComponentFilterSet):
  307. class Meta:
  308. model = InterfaceTemplate
  309. fields = ['name', 'form_factor', 'mgmt_only']
  310. class DeviceBayTemplateFilter(DeviceTypeComponentFilterSet):
  311. class Meta:
  312. model = DeviceBayTemplate
  313. fields = ['name']
  314. class DeviceRoleFilter(django_filters.FilterSet):
  315. class Meta:
  316. model = DeviceRole
  317. fields = ['name', 'slug', 'color', 'vm_role']
  318. class PlatformFilter(django_filters.FilterSet):
  319. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  320. name='manufacturer',
  321. queryset=Manufacturer.objects.all(),
  322. label='Manufacturer (ID)',
  323. )
  324. manufacturer = django_filters.ModelMultipleChoiceFilter(
  325. name='manufacturer__slug',
  326. queryset=Manufacturer.objects.all(),
  327. to_field_name='slug',
  328. label='Manufacturer (slug)',
  329. )
  330. class Meta:
  331. model = Platform
  332. fields = ['name', 'slug']
  333. class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet):
  334. id__in = NumericInFilter(name='id', lookup_expr='in')
  335. q = django_filters.CharFilter(
  336. method='search',
  337. label='Search',
  338. )
  339. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  340. name='device_type__manufacturer',
  341. queryset=Manufacturer.objects.all(),
  342. label='Manufacturer (ID)',
  343. )
  344. manufacturer = django_filters.ModelMultipleChoiceFilter(
  345. name='device_type__manufacturer__slug',
  346. queryset=Manufacturer.objects.all(),
  347. to_field_name='slug',
  348. label='Manufacturer (slug)',
  349. )
  350. device_type_id = django_filters.ModelMultipleChoiceFilter(
  351. queryset=DeviceType.objects.all(),
  352. label='Device type (ID)',
  353. )
  354. role_id = django_filters.ModelMultipleChoiceFilter(
  355. name='device_role_id',
  356. queryset=DeviceRole.objects.all(),
  357. label='Role (ID)',
  358. )
  359. role = django_filters.ModelMultipleChoiceFilter(
  360. name='device_role__slug',
  361. queryset=DeviceRole.objects.all(),
  362. to_field_name='slug',
  363. label='Role (slug)',
  364. )
  365. tenant_id = django_filters.ModelMultipleChoiceFilter(
  366. queryset=Tenant.objects.all(),
  367. label='Tenant (ID)',
  368. )
  369. tenant = django_filters.ModelMultipleChoiceFilter(
  370. name='tenant__slug',
  371. queryset=Tenant.objects.all(),
  372. to_field_name='slug',
  373. label='Tenant (slug)',
  374. )
  375. platform_id = django_filters.ModelMultipleChoiceFilter(
  376. queryset=Platform.objects.all(),
  377. label='Platform (ID)',
  378. )
  379. platform = django_filters.ModelMultipleChoiceFilter(
  380. name='platform__slug',
  381. queryset=Platform.objects.all(),
  382. to_field_name='slug',
  383. label='Platform (slug)',
  384. )
  385. name = NullableCharFieldFilter()
  386. asset_tag = NullableCharFieldFilter()
  387. site_id = django_filters.ModelMultipleChoiceFilter(
  388. queryset=Site.objects.all(),
  389. label='Site (ID)',
  390. )
  391. site = django_filters.ModelMultipleChoiceFilter(
  392. name='site__slug',
  393. queryset=Site.objects.all(),
  394. to_field_name='slug',
  395. label='Site name (slug)',
  396. )
  397. rack_group_id = django_filters.ModelMultipleChoiceFilter(
  398. name='rack__group',
  399. queryset=RackGroup.objects.all(),
  400. label='Rack group (ID)',
  401. )
  402. rack_id = django_filters.ModelMultipleChoiceFilter(
  403. name='rack',
  404. queryset=Rack.objects.all(),
  405. label='Rack (ID)',
  406. )
  407. cluster_id = django_filters.ModelMultipleChoiceFilter(
  408. queryset=Cluster.objects.all(),
  409. label='VM cluster (ID)',
  410. )
  411. model = django_filters.ModelMultipleChoiceFilter(
  412. name='device_type__slug',
  413. queryset=DeviceType.objects.all(),
  414. to_field_name='slug',
  415. label='Device model (slug)',
  416. )
  417. status = django_filters.MultipleChoiceFilter(
  418. choices=DEVICE_STATUS_CHOICES,
  419. null_value=None
  420. )
  421. is_full_depth = django_filters.BooleanFilter(
  422. name='device_type__is_full_depth',
  423. label='Is full depth',
  424. )
  425. is_console_server = django_filters.BooleanFilter(
  426. name='device_type__is_console_server',
  427. label='Is a console server',
  428. )
  429. is_pdu = django_filters.BooleanFilter(
  430. name='device_type__is_pdu',
  431. label='Is a PDU',
  432. )
  433. is_network_device = django_filters.BooleanFilter(
  434. name='device_type__is_network_device',
  435. label='Is a network device',
  436. )
  437. mac_address = django_filters.CharFilter(
  438. method='_mac_address',
  439. label='MAC address',
  440. )
  441. has_primary_ip = django_filters.BooleanFilter(
  442. method='_has_primary_ip',
  443. label='Has a primary IP',
  444. )
  445. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  446. name='virtual_chassis',
  447. queryset=VirtualChassis.objects.all(),
  448. label='Virtual chassis (ID)',
  449. )
  450. tag = django_filters.CharFilter(
  451. name='tags__slug',
  452. )
  453. class Meta:
  454. model = Device
  455. fields = ['serial', 'position']
  456. def search(self, queryset, name, value):
  457. if not value.strip():
  458. return queryset
  459. return queryset.filter(
  460. Q(name__icontains=value) |
  461. Q(serial__icontains=value.strip()) |
  462. Q(inventory_items__serial__icontains=value.strip()) |
  463. Q(asset_tag__icontains=value.strip()) |
  464. Q(comments__icontains=value)
  465. ).distinct()
  466. def _mac_address(self, queryset, name, value):
  467. value = value.strip()
  468. if not value:
  469. return queryset
  470. try:
  471. mac = EUI(value.strip())
  472. return queryset.filter(interfaces__mac_address=mac).distinct()
  473. except AddrFormatError:
  474. return queryset.none()
  475. def _has_primary_ip(self, queryset, name, value):
  476. if value:
  477. return queryset.filter(
  478. Q(primary_ip4__isnull=False) |
  479. Q(primary_ip6__isnull=False)
  480. )
  481. else:
  482. return queryset.exclude(
  483. Q(primary_ip4__isnull=False) |
  484. Q(primary_ip6__isnull=False)
  485. )
  486. class DeviceComponentFilterSet(django_filters.FilterSet):
  487. device_id = django_filters.ModelChoiceFilter(
  488. queryset=Device.objects.all(),
  489. label='Device (ID)',
  490. )
  491. device = django_filters.ModelChoiceFilter(
  492. queryset=Device.objects.all(),
  493. to_field_name='name',
  494. label='Device (name)',
  495. )
  496. tag = django_filters.CharFilter(
  497. name='tags__slug',
  498. )
  499. class ConsolePortFilter(DeviceComponentFilterSet):
  500. class Meta:
  501. model = ConsolePort
  502. fields = ['name']
  503. class ConsoleServerPortFilter(DeviceComponentFilterSet):
  504. class Meta:
  505. model = ConsoleServerPort
  506. fields = ['name']
  507. class PowerPortFilter(DeviceComponentFilterSet):
  508. class Meta:
  509. model = PowerPort
  510. fields = ['name']
  511. class PowerOutletFilter(DeviceComponentFilterSet):
  512. class Meta:
  513. model = PowerOutlet
  514. fields = ['name']
  515. class InterfaceFilter(django_filters.FilterSet):
  516. """
  517. Not using DeviceComponentFilterSet for Interfaces because we need to glean the ordering logic from the parent
  518. Device's DeviceType.
  519. """
  520. device = django_filters.CharFilter(
  521. method='filter_device',
  522. name='name',
  523. label='Device',
  524. )
  525. device_id = django_filters.NumberFilter(
  526. method='filter_device',
  527. name='pk',
  528. label='Device (ID)',
  529. )
  530. type = django_filters.CharFilter(
  531. method='filter_type',
  532. label='Interface type',
  533. )
  534. lag_id = django_filters.ModelMultipleChoiceFilter(
  535. name='lag',
  536. queryset=Interface.objects.all(),
  537. label='LAG interface (ID)',
  538. )
  539. mac_address = django_filters.CharFilter(
  540. method='_mac_address',
  541. label='MAC address',
  542. )
  543. tag = django_filters.CharFilter(
  544. name='tags__slug',
  545. )
  546. class Meta:
  547. model = Interface
  548. fields = ['name', 'form_factor', 'enabled', 'mtu', 'mgmt_only']
  549. def filter_device(self, queryset, name, value):
  550. try:
  551. device = Device.objects.select_related('device_type').get(**{name: value})
  552. vc_interface_ids = [i['id'] for i in device.vc_interfaces.values('id')]
  553. ordering = device.device_type.interface_ordering
  554. return queryset.filter(pk__in=vc_interface_ids).order_naturally(ordering)
  555. except Device.DoesNotExist:
  556. return queryset.none()
  557. def filter_type(self, queryset, name, value):
  558. value = value.strip().lower()
  559. return {
  560. 'physical': queryset.exclude(form_factor__in=NONCONNECTABLE_IFACE_TYPES),
  561. 'virtual': queryset.filter(form_factor__in=VIRTUAL_IFACE_TYPES),
  562. 'wireless': queryset.filter(form_factor__in=WIRELESS_IFACE_TYPES),
  563. 'lag': queryset.filter(form_factor=IFACE_FF_LAG),
  564. }.get(value, queryset.none())
  565. def _mac_address(self, queryset, name, value):
  566. value = value.strip()
  567. if not value:
  568. return queryset
  569. try:
  570. mac = EUI(value.strip())
  571. return queryset.filter(mac_address=mac)
  572. except AddrFormatError:
  573. return queryset.none()
  574. class DeviceBayFilter(DeviceComponentFilterSet):
  575. class Meta:
  576. model = DeviceBay
  577. fields = ['name']
  578. class InventoryItemFilter(DeviceComponentFilterSet):
  579. q = django_filters.CharFilter(
  580. method='search',
  581. label='Search',
  582. )
  583. parent_id = django_filters.ModelMultipleChoiceFilter(
  584. queryset=InventoryItem.objects.all(),
  585. label='Parent inventory item (ID)',
  586. )
  587. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  588. queryset=Manufacturer.objects.all(),
  589. label='Manufacturer (ID)',
  590. )
  591. manufacturer = django_filters.ModelMultipleChoiceFilter(
  592. name='manufacturer__slug',
  593. queryset=Manufacturer.objects.all(),
  594. to_field_name='slug',
  595. label='Manufacturer (slug)',
  596. )
  597. asset_tag = NullableCharFieldFilter()
  598. class Meta:
  599. model = InventoryItem
  600. fields = ['name', 'part_id', 'serial', 'asset_tag', 'discovered']
  601. def search(self, queryset, name, value):
  602. if not value.strip():
  603. return queryset
  604. qs_filter = (
  605. Q(name__icontains=value) |
  606. Q(part_id__icontains=value) |
  607. Q(serial__iexact=value) |
  608. Q(asset_tag__iexact=value) |
  609. Q(description__icontains=value)
  610. )
  611. return queryset.filter(qs_filter)
  612. class VirtualChassisFilter(django_filters.FilterSet):
  613. q = django_filters.CharFilter(
  614. method='search',
  615. label='Search',
  616. )
  617. site_id = django_filters.ModelMultipleChoiceFilter(
  618. name='master__site',
  619. queryset=Site.objects.all(),
  620. label='Site (ID)',
  621. )
  622. site = django_filters.ModelMultipleChoiceFilter(
  623. name='master__site__slug',
  624. queryset=Site.objects.all(),
  625. to_field_name='slug',
  626. label='Site name (slug)',
  627. )
  628. tenant_id = django_filters.ModelMultipleChoiceFilter(
  629. name='master__tenant',
  630. queryset=Tenant.objects.all(),
  631. label='Tenant (ID)',
  632. )
  633. tenant = django_filters.ModelMultipleChoiceFilter(
  634. name='master__tenant__slug',
  635. queryset=Tenant.objects.all(),
  636. to_field_name='slug',
  637. label='Tenant (slug)',
  638. )
  639. tag = django_filters.CharFilter(
  640. name='tags__slug',
  641. )
  642. class Meta:
  643. model = VirtualChassis
  644. fields = ['domain']
  645. def search(self, queryset, name, value):
  646. if not value.strip():
  647. return queryset
  648. qs_filter = (
  649. Q(master__name__icontains=value) |
  650. Q(domain__icontains=value)
  651. )
  652. return queryset.filter(qs_filter)
  653. class ConsoleConnectionFilter(django_filters.FilterSet):
  654. site = django_filters.CharFilter(
  655. method='filter_site',
  656. label='Site (slug)',
  657. )
  658. device = django_filters.CharFilter(
  659. method='filter_device',
  660. label='Device',
  661. )
  662. class Meta:
  663. model = ConsolePort
  664. fields = ['name', 'connection_status']
  665. def filter_site(self, queryset, name, value):
  666. if not value.strip():
  667. return queryset
  668. return queryset.filter(cs_port__device__site__slug=value)
  669. def filter_device(self, queryset, name, value):
  670. if not value.strip():
  671. return queryset
  672. return queryset.filter(
  673. Q(device__name__icontains=value) |
  674. Q(cs_port__device__name__icontains=value)
  675. )
  676. class PowerConnectionFilter(django_filters.FilterSet):
  677. site = django_filters.CharFilter(
  678. method='filter_site',
  679. label='Site (slug)',
  680. )
  681. device = django_filters.CharFilter(
  682. method='filter_device',
  683. label='Device',
  684. )
  685. class Meta:
  686. model = PowerPort
  687. fields = ['name', 'connection_status']
  688. def filter_site(self, queryset, name, value):
  689. if not value.strip():
  690. return queryset
  691. return queryset.filter(power_outlet__device__site__slug=value)
  692. def filter_device(self, queryset, name, value):
  693. if not value.strip():
  694. return queryset
  695. return queryset.filter(
  696. Q(device__name__icontains=value) |
  697. Q(power_outlet__device__name__icontains=value)
  698. )
  699. class InterfaceConnectionFilter(django_filters.FilterSet):
  700. site = django_filters.CharFilter(
  701. method='filter_site',
  702. label='Site (slug)',
  703. )
  704. device = django_filters.CharFilter(
  705. method='filter_device',
  706. label='Device',
  707. )
  708. class Meta:
  709. model = InterfaceConnection
  710. fields = ['connection_status']
  711. def filter_site(self, queryset, name, value):
  712. if not value.strip():
  713. return queryset
  714. return queryset.filter(
  715. Q(interface_a__device__site__slug=value) |
  716. Q(interface_b__device__site__slug=value)
  717. )
  718. def filter_device(self, queryset, name, value):
  719. if not value.strip():
  720. return queryset
  721. return queryset.filter(
  722. Q(interface_a__device__name__icontains=value) |
  723. Q(interface_b__device__name__icontains=value)
  724. )