filtersets.py 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465
  1. import django_filters
  2. from django.contrib.auth.models import User
  3. from extras.filters import TagFilter
  4. from extras.filtersets import LocalConfigContextFilterSet
  5. from netbox.filtersets import (
  6. BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet,
  7. )
  8. from tenancy.filtersets import TenancyFilterSet
  9. from tenancy.models import Tenant
  10. from utilities.choices import ColorChoices
  11. from utilities.filters import (
  12. MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, TreeNodeMultipleChoiceFilter,
  13. )
  14. from virtualization.models import Cluster
  15. from .choices import *
  16. from .constants import *
  17. from .models import *
  18. __all__ = (
  19. 'CableFilterSet',
  20. 'CableTerminationFilterSet',
  21. 'ConsoleConnectionFilterSet',
  22. 'ConsolePortFilterSet',
  23. 'ConsolePortTemplateFilterSet',
  24. 'ConsoleServerPortFilterSet',
  25. 'ConsoleServerPortTemplateFilterSet',
  26. 'DeviceBayFilterSet',
  27. 'DeviceBayTemplateFilterSet',
  28. 'DeviceFilterSet',
  29. 'DeviceRoleFilterSet',
  30. 'DeviceTypeFilterSet',
  31. 'FrontPortFilterSet',
  32. 'FrontPortTemplateFilterSet',
  33. 'InterfaceConnectionFilterSet',
  34. 'InterfaceFilterSet',
  35. 'InterfaceTemplateFilterSet',
  36. 'InventoryItemFilterSet',
  37. 'LocationFilterSet',
  38. 'ManufacturerFilterSet',
  39. 'PathEndpointFilterSet',
  40. 'PlatformFilterSet',
  41. 'PowerConnectionFilterSet',
  42. 'PowerFeedFilterSet',
  43. 'PowerOutletFilterSet',
  44. 'PowerOutletTemplateFilterSet',
  45. 'PowerPanelFilterSet',
  46. 'PowerPortFilterSet',
  47. 'PowerPortTemplateFilterSet',
  48. 'RackFilterSet',
  49. 'RackReservationFilterSet',
  50. 'RackRoleFilterSet',
  51. 'RearPortFilterSet',
  52. 'RearPortTemplateFilterSet',
  53. 'RegionFilterSet',
  54. 'SiteFilterSet',
  55. 'SiteGroupFilterSet',
  56. 'VirtualChassisFilterSet',
  57. )
  58. class RegionFilterSet(OrganizationalModelFilterSet):
  59. parent_id = django_filters.ModelMultipleChoiceFilter(
  60. queryset=Region.objects.all(),
  61. label='Parent region (ID)',
  62. )
  63. parent = django_filters.ModelMultipleChoiceFilter(
  64. field_name='parent__slug',
  65. queryset=Region.objects.all(),
  66. to_field_name='slug',
  67. label='Parent region (slug)',
  68. )
  69. class Meta:
  70. model = Region
  71. fields = ['id', 'name', 'slug', 'description']
  72. class SiteGroupFilterSet(OrganizationalModelFilterSet):
  73. parent_id = django_filters.ModelMultipleChoiceFilter(
  74. queryset=SiteGroup.objects.all(),
  75. label='Parent site group (ID)',
  76. )
  77. parent = django_filters.ModelMultipleChoiceFilter(
  78. field_name='parent__slug',
  79. queryset=SiteGroup.objects.all(),
  80. to_field_name='slug',
  81. label='Parent site group (slug)',
  82. )
  83. class Meta:
  84. model = SiteGroup
  85. fields = ['id', 'name', 'slug', 'description']
  86. class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  87. q = django_filters.CharFilter(
  88. method='search',
  89. label='Search',
  90. )
  91. status = django_filters.MultipleChoiceFilter(
  92. choices=SiteStatusChoices,
  93. null_value=None
  94. )
  95. region_id = TreeNodeMultipleChoiceFilter(
  96. queryset=Region.objects.all(),
  97. field_name='region',
  98. lookup_expr='in',
  99. label='Region (ID)',
  100. )
  101. region = TreeNodeMultipleChoiceFilter(
  102. queryset=Region.objects.all(),
  103. lookup_expr='in',
  104. to_field_name='slug',
  105. label='Region (slug)',
  106. )
  107. group_id = TreeNodeMultipleChoiceFilter(
  108. queryset=SiteGroup.objects.all(),
  109. field_name='group',
  110. lookup_expr='in',
  111. label='Group (ID)',
  112. )
  113. group = TreeNodeMultipleChoiceFilter(
  114. queryset=SiteGroup.objects.all(),
  115. lookup_expr='in',
  116. to_field_name='slug',
  117. label='Group (slug)',
  118. )
  119. tag = TagFilter()
  120. class Meta:
  121. model = Site
  122. fields = [
  123. 'id', 'name', 'slug', 'facility', 'asn', 'latitude', 'longitude', 'contact_name', 'contact_phone',
  124. 'contact_email',
  125. ]
  126. def search(self, queryset, name, value):
  127. if not value.strip():
  128. return queryset
  129. qs_filter = (
  130. Q(name__icontains=value) |
  131. Q(facility__icontains=value) |
  132. Q(description__icontains=value) |
  133. Q(physical_address__icontains=value) |
  134. Q(shipping_address__icontains=value) |
  135. Q(contact_name__icontains=value) |
  136. Q(contact_phone__icontains=value) |
  137. Q(contact_email__icontains=value) |
  138. Q(comments__icontains=value)
  139. )
  140. try:
  141. qs_filter |= Q(asn=int(value.strip()))
  142. except ValueError:
  143. pass
  144. return queryset.filter(qs_filter)
  145. class LocationFilterSet(OrganizationalModelFilterSet):
  146. region_id = TreeNodeMultipleChoiceFilter(
  147. queryset=Region.objects.all(),
  148. field_name='site__region',
  149. lookup_expr='in',
  150. label='Region (ID)',
  151. )
  152. region = TreeNodeMultipleChoiceFilter(
  153. queryset=Region.objects.all(),
  154. field_name='site__region',
  155. lookup_expr='in',
  156. to_field_name='slug',
  157. label='Region (slug)',
  158. )
  159. site_group_id = TreeNodeMultipleChoiceFilter(
  160. queryset=SiteGroup.objects.all(),
  161. field_name='site__group',
  162. lookup_expr='in',
  163. label='Site group (ID)',
  164. )
  165. site_group = TreeNodeMultipleChoiceFilter(
  166. queryset=SiteGroup.objects.all(),
  167. field_name='site__group',
  168. lookup_expr='in',
  169. to_field_name='slug',
  170. label='Site group (slug)',
  171. )
  172. site_id = django_filters.ModelMultipleChoiceFilter(
  173. queryset=Site.objects.all(),
  174. label='Site (ID)',
  175. )
  176. site = django_filters.ModelMultipleChoiceFilter(
  177. field_name='site__slug',
  178. queryset=Site.objects.all(),
  179. to_field_name='slug',
  180. label='Site (slug)',
  181. )
  182. parent_id = TreeNodeMultipleChoiceFilter(
  183. queryset=Location.objects.all(),
  184. field_name='parent',
  185. lookup_expr='in',
  186. label='Location (ID)',
  187. )
  188. parent = TreeNodeMultipleChoiceFilter(
  189. queryset=Location.objects.all(),
  190. field_name='parent',
  191. lookup_expr='in',
  192. to_field_name='slug',
  193. label='Location (slug)',
  194. )
  195. class Meta:
  196. model = Location
  197. fields = ['id', 'name', 'slug', 'description']
  198. def search(self, queryset, name, value):
  199. if not value.strip():
  200. return queryset
  201. return queryset.filter(
  202. Q(name__icontains=value) |
  203. Q(description__icontains=value)
  204. )
  205. class RackRoleFilterSet(OrganizationalModelFilterSet):
  206. class Meta:
  207. model = RackRole
  208. fields = ['id', 'name', 'slug', 'color']
  209. class RackFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  210. q = django_filters.CharFilter(
  211. method='search',
  212. label='Search',
  213. )
  214. region_id = TreeNodeMultipleChoiceFilter(
  215. queryset=Region.objects.all(),
  216. field_name='site__region',
  217. lookup_expr='in',
  218. label='Region (ID)',
  219. )
  220. region = TreeNodeMultipleChoiceFilter(
  221. queryset=Region.objects.all(),
  222. field_name='site__region',
  223. lookup_expr='in',
  224. to_field_name='slug',
  225. label='Region (slug)',
  226. )
  227. site_group_id = TreeNodeMultipleChoiceFilter(
  228. queryset=SiteGroup.objects.all(),
  229. field_name='site__group',
  230. lookup_expr='in',
  231. label='Site group (ID)',
  232. )
  233. site_group = TreeNodeMultipleChoiceFilter(
  234. queryset=SiteGroup.objects.all(),
  235. field_name='site__group',
  236. lookup_expr='in',
  237. to_field_name='slug',
  238. label='Site group (slug)',
  239. )
  240. site_id = django_filters.ModelMultipleChoiceFilter(
  241. queryset=Site.objects.all(),
  242. label='Site (ID)',
  243. )
  244. site = django_filters.ModelMultipleChoiceFilter(
  245. field_name='site__slug',
  246. queryset=Site.objects.all(),
  247. to_field_name='slug',
  248. label='Site (slug)',
  249. )
  250. location_id = TreeNodeMultipleChoiceFilter(
  251. queryset=Location.objects.all(),
  252. field_name='location',
  253. lookup_expr='in',
  254. label='Location (ID)',
  255. )
  256. location = TreeNodeMultipleChoiceFilter(
  257. queryset=Location.objects.all(),
  258. field_name='location',
  259. lookup_expr='in',
  260. to_field_name='slug',
  261. label='Location (slug)',
  262. )
  263. status = django_filters.MultipleChoiceFilter(
  264. choices=RackStatusChoices,
  265. null_value=None
  266. )
  267. type = django_filters.MultipleChoiceFilter(
  268. choices=RackTypeChoices
  269. )
  270. width = django_filters.MultipleChoiceFilter(
  271. choices=RackWidthChoices
  272. )
  273. role_id = django_filters.ModelMultipleChoiceFilter(
  274. queryset=RackRole.objects.all(),
  275. label='Role (ID)',
  276. )
  277. role = django_filters.ModelMultipleChoiceFilter(
  278. field_name='role__slug',
  279. queryset=RackRole.objects.all(),
  280. to_field_name='slug',
  281. label='Role (slug)',
  282. )
  283. serial = django_filters.CharFilter(
  284. lookup_expr='iexact'
  285. )
  286. tag = TagFilter()
  287. class Meta:
  288. model = Rack
  289. fields = [
  290. 'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'desc_units', 'outer_width', 'outer_depth',
  291. 'outer_unit',
  292. ]
  293. def search(self, queryset, name, value):
  294. if not value.strip():
  295. return queryset
  296. return queryset.filter(
  297. Q(name__icontains=value) |
  298. Q(facility_id__icontains=value) |
  299. Q(serial__icontains=value.strip()) |
  300. Q(asset_tag__icontains=value.strip()) |
  301. Q(comments__icontains=value)
  302. )
  303. class RackReservationFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  304. q = django_filters.CharFilter(
  305. method='search',
  306. label='Search',
  307. )
  308. rack_id = django_filters.ModelMultipleChoiceFilter(
  309. queryset=Rack.objects.all(),
  310. label='Rack (ID)',
  311. )
  312. site_id = django_filters.ModelMultipleChoiceFilter(
  313. field_name='rack__site',
  314. queryset=Site.objects.all(),
  315. label='Site (ID)',
  316. )
  317. site = django_filters.ModelMultipleChoiceFilter(
  318. field_name='rack__site__slug',
  319. queryset=Site.objects.all(),
  320. to_field_name='slug',
  321. label='Site (slug)',
  322. )
  323. location_id = TreeNodeMultipleChoiceFilter(
  324. queryset=Location.objects.all(),
  325. field_name='rack__location',
  326. lookup_expr='in',
  327. label='Location (ID)',
  328. )
  329. location = TreeNodeMultipleChoiceFilter(
  330. queryset=Location.objects.all(),
  331. field_name='rack__location',
  332. lookup_expr='in',
  333. to_field_name='slug',
  334. label='Location (slug)',
  335. )
  336. user_id = django_filters.ModelMultipleChoiceFilter(
  337. queryset=User.objects.all(),
  338. label='User (ID)',
  339. )
  340. user = django_filters.ModelMultipleChoiceFilter(
  341. field_name='user__username',
  342. queryset=User.objects.all(),
  343. to_field_name='username',
  344. label='User (name)',
  345. )
  346. tag = TagFilter()
  347. class Meta:
  348. model = RackReservation
  349. fields = ['id', 'created']
  350. def search(self, queryset, name, value):
  351. if not value.strip():
  352. return queryset
  353. return queryset.filter(
  354. Q(rack__name__icontains=value) |
  355. Q(rack__facility_id__icontains=value) |
  356. Q(user__username__icontains=value) |
  357. Q(description__icontains=value)
  358. )
  359. class ManufacturerFilterSet(OrganizationalModelFilterSet):
  360. class Meta:
  361. model = Manufacturer
  362. fields = ['id', 'name', 'slug', 'description']
  363. class DeviceTypeFilterSet(PrimaryModelFilterSet):
  364. q = django_filters.CharFilter(
  365. method='search',
  366. label='Search',
  367. )
  368. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  369. queryset=Manufacturer.objects.all(),
  370. label='Manufacturer (ID)',
  371. )
  372. manufacturer = django_filters.ModelMultipleChoiceFilter(
  373. field_name='manufacturer__slug',
  374. queryset=Manufacturer.objects.all(),
  375. to_field_name='slug',
  376. label='Manufacturer (slug)',
  377. )
  378. console_ports = django_filters.BooleanFilter(
  379. method='_console_ports',
  380. label='Has console ports',
  381. )
  382. console_server_ports = django_filters.BooleanFilter(
  383. method='_console_server_ports',
  384. label='Has console server ports',
  385. )
  386. power_ports = django_filters.BooleanFilter(
  387. method='_power_ports',
  388. label='Has power ports',
  389. )
  390. power_outlets = django_filters.BooleanFilter(
  391. method='_power_outlets',
  392. label='Has power outlets',
  393. )
  394. interfaces = django_filters.BooleanFilter(
  395. method='_interfaces',
  396. label='Has interfaces',
  397. )
  398. pass_through_ports = django_filters.BooleanFilter(
  399. method='_pass_through_ports',
  400. label='Has pass-through ports',
  401. )
  402. device_bays = django_filters.BooleanFilter(
  403. method='_device_bays',
  404. label='Has device bays',
  405. )
  406. tag = TagFilter()
  407. class Meta:
  408. model = DeviceType
  409. fields = [
  410. 'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role',
  411. ]
  412. def search(self, queryset, name, value):
  413. if not value.strip():
  414. return queryset
  415. return queryset.filter(
  416. Q(manufacturer__name__icontains=value) |
  417. Q(model__icontains=value) |
  418. Q(part_number__icontains=value) |
  419. Q(comments__icontains=value)
  420. )
  421. def _console_ports(self, queryset, name, value):
  422. return queryset.exclude(consoleporttemplates__isnull=value)
  423. def _console_server_ports(self, queryset, name, value):
  424. return queryset.exclude(consoleserverporttemplates__isnull=value)
  425. def _power_ports(self, queryset, name, value):
  426. return queryset.exclude(powerporttemplates__isnull=value)
  427. def _power_outlets(self, queryset, name, value):
  428. return queryset.exclude(poweroutlettemplates__isnull=value)
  429. def _interfaces(self, queryset, name, value):
  430. return queryset.exclude(interfacetemplates__isnull=value)
  431. def _pass_through_ports(self, queryset, name, value):
  432. return queryset.exclude(
  433. frontporttemplates__isnull=value,
  434. rearporttemplates__isnull=value
  435. )
  436. def _device_bays(self, queryset, name, value):
  437. return queryset.exclude(devicebaytemplates__isnull=value)
  438. class DeviceTypeComponentFilterSet(django_filters.FilterSet):
  439. devicetype_id = django_filters.ModelMultipleChoiceFilter(
  440. queryset=DeviceType.objects.all(),
  441. field_name='device_type_id',
  442. label='Device type (ID)',
  443. )
  444. class ConsolePortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  445. class Meta:
  446. model = ConsolePortTemplate
  447. fields = ['id', 'name', 'type']
  448. class ConsoleServerPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  449. class Meta:
  450. model = ConsoleServerPortTemplate
  451. fields = ['id', 'name', 'type']
  452. class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  453. class Meta:
  454. model = PowerPortTemplate
  455. fields = ['id', 'name', 'type', 'maximum_draw', 'allocated_draw']
  456. class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  457. feed_leg = django_filters.MultipleChoiceFilter(
  458. choices=PowerOutletFeedLegChoices,
  459. null_value=None
  460. )
  461. class Meta:
  462. model = PowerOutletTemplate
  463. fields = ['id', 'name', 'type', 'feed_leg']
  464. class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  465. type = django_filters.MultipleChoiceFilter(
  466. choices=InterfaceTypeChoices,
  467. null_value=None
  468. )
  469. class Meta:
  470. model = InterfaceTemplate
  471. fields = ['id', 'name', 'type', 'mgmt_only']
  472. class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  473. type = django_filters.MultipleChoiceFilter(
  474. choices=PortTypeChoices,
  475. null_value=None
  476. )
  477. class Meta:
  478. model = FrontPortTemplate
  479. fields = ['id', 'name', 'type']
  480. class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  481. type = django_filters.MultipleChoiceFilter(
  482. choices=PortTypeChoices,
  483. null_value=None
  484. )
  485. class Meta:
  486. model = RearPortTemplate
  487. fields = ['id', 'name', 'type', 'positions']
  488. class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  489. class Meta:
  490. model = DeviceBayTemplate
  491. fields = ['id', 'name']
  492. class DeviceRoleFilterSet(OrganizationalModelFilterSet):
  493. class Meta:
  494. model = DeviceRole
  495. fields = ['id', 'name', 'slug', 'color', 'vm_role']
  496. class PlatformFilterSet(OrganizationalModelFilterSet):
  497. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  498. field_name='manufacturer',
  499. queryset=Manufacturer.objects.all(),
  500. label='Manufacturer (ID)',
  501. )
  502. manufacturer = django_filters.ModelMultipleChoiceFilter(
  503. field_name='manufacturer__slug',
  504. queryset=Manufacturer.objects.all(),
  505. to_field_name='slug',
  506. label='Manufacturer (slug)',
  507. )
  508. class Meta:
  509. model = Platform
  510. fields = ['id', 'name', 'slug', 'napalm_driver', 'description']
  511. class DeviceFilterSet(PrimaryModelFilterSet, TenancyFilterSet, LocalConfigContextFilterSet):
  512. q = django_filters.CharFilter(
  513. method='search',
  514. label='Search',
  515. )
  516. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  517. field_name='device_type__manufacturer',
  518. queryset=Manufacturer.objects.all(),
  519. label='Manufacturer (ID)',
  520. )
  521. manufacturer = django_filters.ModelMultipleChoiceFilter(
  522. field_name='device_type__manufacturer__slug',
  523. queryset=Manufacturer.objects.all(),
  524. to_field_name='slug',
  525. label='Manufacturer (slug)',
  526. )
  527. device_type_id = django_filters.ModelMultipleChoiceFilter(
  528. queryset=DeviceType.objects.all(),
  529. label='Device type (ID)',
  530. )
  531. role_id = django_filters.ModelMultipleChoiceFilter(
  532. field_name='device_role_id',
  533. queryset=DeviceRole.objects.all(),
  534. label='Role (ID)',
  535. )
  536. role = django_filters.ModelMultipleChoiceFilter(
  537. field_name='device_role__slug',
  538. queryset=DeviceRole.objects.all(),
  539. to_field_name='slug',
  540. label='Role (slug)',
  541. )
  542. platform_id = django_filters.ModelMultipleChoiceFilter(
  543. queryset=Platform.objects.all(),
  544. label='Platform (ID)',
  545. )
  546. platform = django_filters.ModelMultipleChoiceFilter(
  547. field_name='platform__slug',
  548. queryset=Platform.objects.all(),
  549. to_field_name='slug',
  550. label='Platform (slug)',
  551. )
  552. region_id = TreeNodeMultipleChoiceFilter(
  553. queryset=Region.objects.all(),
  554. field_name='site__region',
  555. lookup_expr='in',
  556. label='Region (ID)',
  557. )
  558. region = TreeNodeMultipleChoiceFilter(
  559. queryset=Region.objects.all(),
  560. field_name='site__region',
  561. lookup_expr='in',
  562. to_field_name='slug',
  563. label='Region (slug)',
  564. )
  565. site_group_id = TreeNodeMultipleChoiceFilter(
  566. queryset=SiteGroup.objects.all(),
  567. field_name='site__group',
  568. lookup_expr='in',
  569. label='Site group (ID)',
  570. )
  571. site_group = TreeNodeMultipleChoiceFilter(
  572. queryset=SiteGroup.objects.all(),
  573. field_name='site__group',
  574. lookup_expr='in',
  575. to_field_name='slug',
  576. label='Site group (slug)',
  577. )
  578. site_id = django_filters.ModelMultipleChoiceFilter(
  579. queryset=Site.objects.all(),
  580. label='Site (ID)',
  581. )
  582. site = django_filters.ModelMultipleChoiceFilter(
  583. field_name='site__slug',
  584. queryset=Site.objects.all(),
  585. to_field_name='slug',
  586. label='Site name (slug)',
  587. )
  588. location_id = TreeNodeMultipleChoiceFilter(
  589. queryset=Location.objects.all(),
  590. field_name='location',
  591. lookup_expr='in',
  592. label='Location (ID)',
  593. )
  594. rack_id = django_filters.ModelMultipleChoiceFilter(
  595. field_name='rack',
  596. queryset=Rack.objects.all(),
  597. label='Rack (ID)',
  598. )
  599. cluster_id = django_filters.ModelMultipleChoiceFilter(
  600. queryset=Cluster.objects.all(),
  601. label='VM cluster (ID)',
  602. )
  603. model = django_filters.ModelMultipleChoiceFilter(
  604. field_name='device_type__slug',
  605. queryset=DeviceType.objects.all(),
  606. to_field_name='slug',
  607. label='Device model (slug)',
  608. )
  609. status = django_filters.MultipleChoiceFilter(
  610. choices=DeviceStatusChoices,
  611. null_value=None
  612. )
  613. is_full_depth = django_filters.BooleanFilter(
  614. field_name='device_type__is_full_depth',
  615. label='Is full depth',
  616. )
  617. mac_address = MultiValueMACAddressFilter(
  618. field_name='interfaces__mac_address',
  619. label='MAC address',
  620. )
  621. serial = django_filters.CharFilter(
  622. lookup_expr='iexact'
  623. )
  624. has_primary_ip = django_filters.BooleanFilter(
  625. method='_has_primary_ip',
  626. label='Has a primary IP',
  627. )
  628. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  629. field_name='virtual_chassis',
  630. queryset=VirtualChassis.objects.all(),
  631. label='Virtual chassis (ID)',
  632. )
  633. virtual_chassis_member = django_filters.BooleanFilter(
  634. method='_virtual_chassis_member',
  635. label='Is a virtual chassis member'
  636. )
  637. console_ports = django_filters.BooleanFilter(
  638. method='_console_ports',
  639. label='Has console ports',
  640. )
  641. console_server_ports = django_filters.BooleanFilter(
  642. method='_console_server_ports',
  643. label='Has console server ports',
  644. )
  645. power_ports = django_filters.BooleanFilter(
  646. method='_power_ports',
  647. label='Has power ports',
  648. )
  649. power_outlets = django_filters.BooleanFilter(
  650. method='_power_outlets',
  651. label='Has power outlets',
  652. )
  653. interfaces = django_filters.BooleanFilter(
  654. method='_interfaces',
  655. label='Has interfaces',
  656. )
  657. pass_through_ports = django_filters.BooleanFilter(
  658. method='_pass_through_ports',
  659. label='Has pass-through ports',
  660. )
  661. device_bays = django_filters.BooleanFilter(
  662. method='_device_bays',
  663. label='Has device bays',
  664. )
  665. tag = TagFilter()
  666. class Meta:
  667. model = Device
  668. fields = ['id', 'name', 'asset_tag', 'face', 'position', 'vc_position', 'vc_priority']
  669. def search(self, queryset, name, value):
  670. if not value.strip():
  671. return queryset
  672. return queryset.filter(
  673. Q(name__icontains=value) |
  674. Q(serial__icontains=value.strip()) |
  675. Q(inventoryitems__serial__icontains=value.strip()) |
  676. Q(asset_tag__icontains=value.strip()) |
  677. Q(comments__icontains=value)
  678. ).distinct()
  679. def _has_primary_ip(self, queryset, name, value):
  680. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  681. if value:
  682. return queryset.filter(params)
  683. return queryset.exclude(params)
  684. def _virtual_chassis_member(self, queryset, name, value):
  685. return queryset.exclude(virtual_chassis__isnull=value)
  686. def _console_ports(self, queryset, name, value):
  687. return queryset.exclude(consoleports__isnull=value)
  688. def _console_server_ports(self, queryset, name, value):
  689. return queryset.exclude(consoleserverports__isnull=value)
  690. def _power_ports(self, queryset, name, value):
  691. return queryset.exclude(powerports__isnull=value)
  692. def _power_outlets(self, queryset, name, value):
  693. return queryset.exclude(poweroutlets__isnull=value)
  694. def _interfaces(self, queryset, name, value):
  695. return queryset.exclude(interfaces__isnull=value)
  696. def _pass_through_ports(self, queryset, name, value):
  697. return queryset.exclude(
  698. frontports__isnull=value,
  699. rearports__isnull=value
  700. )
  701. def _device_bays(self, queryset, name, value):
  702. return queryset.exclude(devicebays__isnull=value)
  703. class DeviceComponentFilterSet(django_filters.FilterSet):
  704. q = django_filters.CharFilter(
  705. method='search',
  706. label='Search',
  707. )
  708. region_id = TreeNodeMultipleChoiceFilter(
  709. queryset=Region.objects.all(),
  710. field_name='device__site__region',
  711. lookup_expr='in',
  712. label='Region (ID)',
  713. )
  714. region = TreeNodeMultipleChoiceFilter(
  715. queryset=Region.objects.all(),
  716. field_name='device__site__region',
  717. lookup_expr='in',
  718. to_field_name='slug',
  719. label='Region (slug)',
  720. )
  721. site_group_id = TreeNodeMultipleChoiceFilter(
  722. queryset=SiteGroup.objects.all(),
  723. field_name='device__site__group',
  724. lookup_expr='in',
  725. label='Site group (ID)',
  726. )
  727. site_group = TreeNodeMultipleChoiceFilter(
  728. queryset=SiteGroup.objects.all(),
  729. field_name='device__site__group',
  730. lookup_expr='in',
  731. to_field_name='slug',
  732. label='Site group (slug)',
  733. )
  734. site_id = django_filters.ModelMultipleChoiceFilter(
  735. field_name='device__site',
  736. queryset=Site.objects.all(),
  737. label='Site (ID)',
  738. )
  739. site = django_filters.ModelMultipleChoiceFilter(
  740. field_name='device__site__slug',
  741. queryset=Site.objects.all(),
  742. to_field_name='slug',
  743. label='Site name (slug)',
  744. )
  745. device_id = django_filters.ModelMultipleChoiceFilter(
  746. queryset=Device.objects.all(),
  747. label='Device (ID)',
  748. )
  749. device = django_filters.ModelMultipleChoiceFilter(
  750. field_name='device__name',
  751. queryset=Device.objects.all(),
  752. to_field_name='name',
  753. label='Device (name)',
  754. )
  755. tag = TagFilter()
  756. def search(self, queryset, name, value):
  757. if not value.strip():
  758. return queryset
  759. return queryset.filter(
  760. Q(name__icontains=value) |
  761. Q(label__icontains=value) |
  762. Q(description__icontains=value)
  763. )
  764. class CableTerminationFilterSet(django_filters.FilterSet):
  765. cabled = django_filters.BooleanFilter(
  766. field_name='cable',
  767. lookup_expr='isnull',
  768. exclude=True
  769. )
  770. class PathEndpointFilterSet(django_filters.FilterSet):
  771. connected = django_filters.BooleanFilter(
  772. method='filter_connected'
  773. )
  774. def filter_connected(self, queryset, name, value):
  775. if value:
  776. return queryset.filter(_path__is_active=True)
  777. else:
  778. return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
  779. class ConsolePortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
  780. type = django_filters.MultipleChoiceFilter(
  781. choices=ConsolePortTypeChoices,
  782. null_value=None
  783. )
  784. class Meta:
  785. model = ConsolePort
  786. fields = ['id', 'name', 'label', 'description']
  787. class ConsoleServerPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
  788. type = django_filters.MultipleChoiceFilter(
  789. choices=ConsolePortTypeChoices,
  790. null_value=None
  791. )
  792. class Meta:
  793. model = ConsoleServerPort
  794. fields = ['id', 'name', 'label', 'description']
  795. class PowerPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
  796. type = django_filters.MultipleChoiceFilter(
  797. choices=PowerPortTypeChoices,
  798. null_value=None
  799. )
  800. class Meta:
  801. model = PowerPort
  802. fields = ['id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description']
  803. class PowerOutletFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
  804. type = django_filters.MultipleChoiceFilter(
  805. choices=PowerOutletTypeChoices,
  806. null_value=None
  807. )
  808. feed_leg = django_filters.MultipleChoiceFilter(
  809. choices=PowerOutletFeedLegChoices,
  810. null_value=None
  811. )
  812. class Meta:
  813. model = PowerOutlet
  814. fields = ['id', 'name', 'label', 'feed_leg', 'description']
  815. class InterfaceFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
  816. q = django_filters.CharFilter(
  817. method='search',
  818. label='Search',
  819. )
  820. # Override device and device_id filters from DeviceComponentFilterSet to match against any peer virtual chassis
  821. # members
  822. device = MultiValueCharFilter(
  823. method='filter_device',
  824. field_name='name',
  825. label='Device',
  826. )
  827. device_id = MultiValueNumberFilter(
  828. method='filter_device_id',
  829. field_name='pk',
  830. label='Device (ID)',
  831. )
  832. kind = django_filters.CharFilter(
  833. method='filter_kind',
  834. label='Kind of interface',
  835. )
  836. parent_id = django_filters.ModelMultipleChoiceFilter(
  837. field_name='parent',
  838. queryset=Interface.objects.all(),
  839. label='Parent interface (ID)',
  840. )
  841. lag_id = django_filters.ModelMultipleChoiceFilter(
  842. field_name='lag',
  843. queryset=Interface.objects.all(),
  844. label='LAG interface (ID)',
  845. )
  846. mac_address = MultiValueMACAddressFilter()
  847. tag = TagFilter()
  848. vlan_id = django_filters.CharFilter(
  849. method='filter_vlan_id',
  850. label='Assigned VLAN'
  851. )
  852. vlan = django_filters.CharFilter(
  853. method='filter_vlan',
  854. label='Assigned VID'
  855. )
  856. type = django_filters.MultipleChoiceFilter(
  857. choices=InterfaceTypeChoices,
  858. null_value=None
  859. )
  860. class Meta:
  861. model = Interface
  862. fields = ['id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'description']
  863. def filter_device(self, queryset, name, value):
  864. try:
  865. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  866. vc_interface_ids = []
  867. for device in devices:
  868. vc_interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  869. return queryset.filter(pk__in=vc_interface_ids)
  870. except Device.DoesNotExist:
  871. return queryset.none()
  872. def filter_device_id(self, queryset, name, id_list):
  873. # Include interfaces belonging to peer virtual chassis members
  874. vc_interface_ids = []
  875. try:
  876. devices = Device.objects.filter(pk__in=id_list)
  877. for device in devices:
  878. vc_interface_ids += device.vc_interfaces().values_list('id', flat=True)
  879. return queryset.filter(pk__in=vc_interface_ids)
  880. except Device.DoesNotExist:
  881. return queryset.none()
  882. def filter_vlan_id(self, queryset, name, value):
  883. value = value.strip()
  884. if not value:
  885. return queryset
  886. return queryset.filter(
  887. Q(untagged_vlan_id=value) |
  888. Q(tagged_vlans=value)
  889. )
  890. def filter_vlan(self, queryset, name, value):
  891. value = value.strip()
  892. if not value:
  893. return queryset
  894. return queryset.filter(
  895. Q(untagged_vlan_id__vid=value) |
  896. Q(tagged_vlans__vid=value)
  897. )
  898. def filter_kind(self, queryset, name, value):
  899. value = value.strip().lower()
  900. return {
  901. 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES),
  902. 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES),
  903. 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES),
  904. }.get(value, queryset.none())
  905. class FrontPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet):
  906. type = django_filters.MultipleChoiceFilter(
  907. choices=PortTypeChoices,
  908. null_value=None
  909. )
  910. class Meta:
  911. model = FrontPort
  912. fields = ['id', 'name', 'label', 'type', 'description']
  913. class RearPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet):
  914. type = django_filters.MultipleChoiceFilter(
  915. choices=PortTypeChoices,
  916. null_value=None
  917. )
  918. class Meta:
  919. model = RearPort
  920. fields = ['id', 'name', 'label', 'type', 'positions', 'description']
  921. class DeviceBayFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet):
  922. class Meta:
  923. model = DeviceBay
  924. fields = ['id', 'name', 'label', 'description']
  925. class InventoryItemFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet):
  926. q = django_filters.CharFilter(
  927. method='search',
  928. label='Search',
  929. )
  930. region_id = TreeNodeMultipleChoiceFilter(
  931. queryset=Region.objects.all(),
  932. field_name='device__site__region',
  933. lookup_expr='in',
  934. label='Region (ID)',
  935. )
  936. region = TreeNodeMultipleChoiceFilter(
  937. queryset=Region.objects.all(),
  938. field_name='device__site__region',
  939. lookup_expr='in',
  940. to_field_name='slug',
  941. label='Region (slug)',
  942. )
  943. site_id = django_filters.ModelMultipleChoiceFilter(
  944. field_name='device__site',
  945. queryset=Site.objects.all(),
  946. label='Site (ID)',
  947. )
  948. site = django_filters.ModelMultipleChoiceFilter(
  949. field_name='device__site__slug',
  950. queryset=Site.objects.all(),
  951. to_field_name='slug',
  952. label='Site name (slug)',
  953. )
  954. device_id = django_filters.ModelChoiceFilter(
  955. queryset=Device.objects.all(),
  956. label='Device (ID)',
  957. )
  958. device = django_filters.ModelChoiceFilter(
  959. queryset=Device.objects.all(),
  960. to_field_name='name',
  961. label='Device (name)',
  962. )
  963. parent_id = django_filters.ModelMultipleChoiceFilter(
  964. queryset=InventoryItem.objects.all(),
  965. label='Parent inventory item (ID)',
  966. )
  967. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  968. queryset=Manufacturer.objects.all(),
  969. label='Manufacturer (ID)',
  970. )
  971. manufacturer = django_filters.ModelMultipleChoiceFilter(
  972. field_name='manufacturer__slug',
  973. queryset=Manufacturer.objects.all(),
  974. to_field_name='slug',
  975. label='Manufacturer (slug)',
  976. )
  977. serial = django_filters.CharFilter(
  978. lookup_expr='iexact'
  979. )
  980. class Meta:
  981. model = InventoryItem
  982. fields = ['id', 'name', 'label', 'part_id', 'asset_tag', 'discovered']
  983. def search(self, queryset, name, value):
  984. if not value.strip():
  985. return queryset
  986. qs_filter = (
  987. Q(name__icontains=value) |
  988. Q(part_id__icontains=value) |
  989. Q(serial__icontains=value) |
  990. Q(asset_tag__icontains=value) |
  991. Q(description__icontains=value)
  992. )
  993. return queryset.filter(qs_filter)
  994. class VirtualChassisFilterSet(PrimaryModelFilterSet):
  995. q = django_filters.CharFilter(
  996. method='search',
  997. label='Search',
  998. )
  999. master_id = django_filters.ModelMultipleChoiceFilter(
  1000. queryset=Device.objects.all(),
  1001. label='Master (ID)',
  1002. )
  1003. master = django_filters.ModelMultipleChoiceFilter(
  1004. field_name='master__name',
  1005. queryset=Device.objects.all(),
  1006. to_field_name='name',
  1007. label='Master (name)',
  1008. )
  1009. region_id = TreeNodeMultipleChoiceFilter(
  1010. queryset=Region.objects.all(),
  1011. field_name='master__site__region',
  1012. lookup_expr='in',
  1013. label='Region (ID)',
  1014. )
  1015. region = TreeNodeMultipleChoiceFilter(
  1016. queryset=Region.objects.all(),
  1017. field_name='master__site__region',
  1018. lookup_expr='in',
  1019. to_field_name='slug',
  1020. label='Region (slug)',
  1021. )
  1022. site_group_id = TreeNodeMultipleChoiceFilter(
  1023. queryset=SiteGroup.objects.all(),
  1024. field_name='master__site__group',
  1025. lookup_expr='in',
  1026. label='Site group (ID)',
  1027. )
  1028. site_group = TreeNodeMultipleChoiceFilter(
  1029. queryset=SiteGroup.objects.all(),
  1030. field_name='master__site__group',
  1031. lookup_expr='in',
  1032. to_field_name='slug',
  1033. label='Site group (slug)',
  1034. )
  1035. site_id = django_filters.ModelMultipleChoiceFilter(
  1036. field_name='master__site',
  1037. queryset=Site.objects.all(),
  1038. label='Site (ID)',
  1039. )
  1040. site = django_filters.ModelMultipleChoiceFilter(
  1041. field_name='master__site__slug',
  1042. queryset=Site.objects.all(),
  1043. to_field_name='slug',
  1044. label='Site name (slug)',
  1045. )
  1046. tenant_id = django_filters.ModelMultipleChoiceFilter(
  1047. field_name='master__tenant',
  1048. queryset=Tenant.objects.all(),
  1049. label='Tenant (ID)',
  1050. )
  1051. tenant = django_filters.ModelMultipleChoiceFilter(
  1052. field_name='master__tenant__slug',
  1053. queryset=Tenant.objects.all(),
  1054. to_field_name='slug',
  1055. label='Tenant (slug)',
  1056. )
  1057. tag = TagFilter()
  1058. class Meta:
  1059. model = VirtualChassis
  1060. fields = ['id', 'domain', 'name']
  1061. def search(self, queryset, name, value):
  1062. if not value.strip():
  1063. return queryset
  1064. qs_filter = (
  1065. Q(name__icontains=value) |
  1066. Q(members__name__icontains=value) |
  1067. Q(domain__icontains=value)
  1068. )
  1069. return queryset.filter(qs_filter).distinct()
  1070. class CableFilterSet(PrimaryModelFilterSet):
  1071. q = django_filters.CharFilter(
  1072. method='search',
  1073. label='Search',
  1074. )
  1075. type = django_filters.MultipleChoiceFilter(
  1076. choices=CableTypeChoices
  1077. )
  1078. status = django_filters.MultipleChoiceFilter(
  1079. choices=CableStatusChoices
  1080. )
  1081. color = django_filters.MultipleChoiceFilter(
  1082. choices=ColorChoices
  1083. )
  1084. device_id = MultiValueNumberFilter(
  1085. method='filter_device'
  1086. )
  1087. device = MultiValueCharFilter(
  1088. method='filter_device',
  1089. field_name='device__name'
  1090. )
  1091. rack_id = MultiValueNumberFilter(
  1092. method='filter_device',
  1093. field_name='device__rack_id'
  1094. )
  1095. rack = MultiValueNumberFilter(
  1096. method='filter_device',
  1097. field_name='device__rack__name'
  1098. )
  1099. site_id = MultiValueNumberFilter(
  1100. method='filter_device',
  1101. field_name='device__site_id'
  1102. )
  1103. site = MultiValueNumberFilter(
  1104. method='filter_device',
  1105. field_name='device__site__slug'
  1106. )
  1107. tenant_id = MultiValueNumberFilter(
  1108. method='filter_device',
  1109. field_name='device__tenant_id'
  1110. )
  1111. tenant = MultiValueNumberFilter(
  1112. method='filter_device',
  1113. field_name='device__tenant__slug'
  1114. )
  1115. tag = TagFilter()
  1116. class Meta:
  1117. model = Cable
  1118. fields = ['id', 'label', 'length', 'length_unit']
  1119. def search(self, queryset, name, value):
  1120. if not value.strip():
  1121. return queryset
  1122. return queryset.filter(label__icontains=value)
  1123. def filter_device(self, queryset, name, value):
  1124. queryset = queryset.filter(
  1125. Q(**{'_termination_a_{}__in'.format(name): value}) |
  1126. Q(**{'_termination_b_{}__in'.format(name): value})
  1127. )
  1128. return queryset
  1129. class ConnectionFilterSet(BaseFilterSet):
  1130. def filter_site(self, queryset, name, value):
  1131. if not value.strip():
  1132. return queryset
  1133. return queryset.filter(device__site__slug=value)
  1134. def filter_device(self, queryset, name, value):
  1135. if not value:
  1136. return queryset
  1137. return queryset.filter(**{f'{name}__in': value})
  1138. class ConsoleConnectionFilterSet(ConnectionFilterSet):
  1139. site = django_filters.CharFilter(
  1140. method='filter_site',
  1141. label='Site (slug)',
  1142. )
  1143. device_id = MultiValueNumberFilter(
  1144. method='filter_device'
  1145. )
  1146. device = MultiValueCharFilter(
  1147. method='filter_device',
  1148. field_name='device__name'
  1149. )
  1150. class Meta:
  1151. model = ConsolePort
  1152. fields = ['name']
  1153. class PowerConnectionFilterSet(ConnectionFilterSet):
  1154. site = django_filters.CharFilter(
  1155. method='filter_site',
  1156. label='Site (slug)',
  1157. )
  1158. device_id = MultiValueNumberFilter(
  1159. method='filter_device'
  1160. )
  1161. device = MultiValueCharFilter(
  1162. method='filter_device',
  1163. field_name='device__name'
  1164. )
  1165. class Meta:
  1166. model = PowerPort
  1167. fields = ['name']
  1168. class InterfaceConnectionFilterSet(ConnectionFilterSet):
  1169. site = django_filters.CharFilter(
  1170. method='filter_site',
  1171. label='Site (slug)',
  1172. )
  1173. device_id = MultiValueNumberFilter(
  1174. method='filter_device'
  1175. )
  1176. device = MultiValueCharFilter(
  1177. method='filter_device',
  1178. field_name='device__name'
  1179. )
  1180. class Meta:
  1181. model = Interface
  1182. fields = []
  1183. class PowerPanelFilterSet(PrimaryModelFilterSet):
  1184. q = django_filters.CharFilter(
  1185. method='search',
  1186. label='Search',
  1187. )
  1188. region_id = TreeNodeMultipleChoiceFilter(
  1189. queryset=Region.objects.all(),
  1190. field_name='site__region',
  1191. lookup_expr='in',
  1192. label='Region (ID)',
  1193. )
  1194. region = TreeNodeMultipleChoiceFilter(
  1195. queryset=Region.objects.all(),
  1196. field_name='site__region',
  1197. lookup_expr='in',
  1198. to_field_name='slug',
  1199. label='Region (slug)',
  1200. )
  1201. site_group_id = TreeNodeMultipleChoiceFilter(
  1202. queryset=SiteGroup.objects.all(),
  1203. field_name='site__group',
  1204. lookup_expr='in',
  1205. label='Site group (ID)',
  1206. )
  1207. site_group = TreeNodeMultipleChoiceFilter(
  1208. queryset=SiteGroup.objects.all(),
  1209. field_name='site__group',
  1210. lookup_expr='in',
  1211. to_field_name='slug',
  1212. label='Site group (slug)',
  1213. )
  1214. site_id = django_filters.ModelMultipleChoiceFilter(
  1215. queryset=Site.objects.all(),
  1216. label='Site (ID)',
  1217. )
  1218. site = django_filters.ModelMultipleChoiceFilter(
  1219. field_name='site__slug',
  1220. queryset=Site.objects.all(),
  1221. to_field_name='slug',
  1222. label='Site name (slug)',
  1223. )
  1224. location_id = TreeNodeMultipleChoiceFilter(
  1225. queryset=Location.objects.all(),
  1226. field_name='location',
  1227. lookup_expr='in',
  1228. label='Location (ID)',
  1229. )
  1230. tag = TagFilter()
  1231. class Meta:
  1232. model = PowerPanel
  1233. fields = ['id', 'name']
  1234. def search(self, queryset, name, value):
  1235. if not value.strip():
  1236. return queryset
  1237. qs_filter = (
  1238. Q(name__icontains=value)
  1239. )
  1240. return queryset.filter(qs_filter)
  1241. class PowerFeedFilterSet(PrimaryModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
  1242. q = django_filters.CharFilter(
  1243. method='search',
  1244. label='Search',
  1245. )
  1246. region_id = TreeNodeMultipleChoiceFilter(
  1247. queryset=Region.objects.all(),
  1248. field_name='power_panel__site__region',
  1249. lookup_expr='in',
  1250. label='Region (ID)',
  1251. )
  1252. region = TreeNodeMultipleChoiceFilter(
  1253. queryset=Region.objects.all(),
  1254. field_name='power_panel__site__region',
  1255. lookup_expr='in',
  1256. to_field_name='slug',
  1257. label='Region (slug)',
  1258. )
  1259. site_group_id = TreeNodeMultipleChoiceFilter(
  1260. queryset=SiteGroup.objects.all(),
  1261. field_name='power_panel__site__group',
  1262. lookup_expr='in',
  1263. label='Site group (ID)',
  1264. )
  1265. site_group = TreeNodeMultipleChoiceFilter(
  1266. queryset=SiteGroup.objects.all(),
  1267. field_name='power_panel__site__group',
  1268. lookup_expr='in',
  1269. to_field_name='slug',
  1270. label='Site group (slug)',
  1271. )
  1272. site_id = django_filters.ModelMultipleChoiceFilter(
  1273. field_name='power_panel__site',
  1274. queryset=Site.objects.all(),
  1275. label='Site (ID)',
  1276. )
  1277. site = django_filters.ModelMultipleChoiceFilter(
  1278. field_name='power_panel__site__slug',
  1279. queryset=Site.objects.all(),
  1280. to_field_name='slug',
  1281. label='Site name (slug)',
  1282. )
  1283. power_panel_id = django_filters.ModelMultipleChoiceFilter(
  1284. queryset=PowerPanel.objects.all(),
  1285. label='Power panel (ID)',
  1286. )
  1287. rack_id = django_filters.ModelMultipleChoiceFilter(
  1288. field_name='rack',
  1289. queryset=Rack.objects.all(),
  1290. label='Rack (ID)',
  1291. )
  1292. status = django_filters.MultipleChoiceFilter(
  1293. choices=PowerFeedStatusChoices,
  1294. null_value=None
  1295. )
  1296. tag = TagFilter()
  1297. class Meta:
  1298. model = PowerFeed
  1299. fields = ['id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization']
  1300. def search(self, queryset, name, value):
  1301. if not value.strip():
  1302. return queryset
  1303. qs_filter = (
  1304. Q(name__icontains=value) |
  1305. Q(comments__icontains=value)
  1306. )
  1307. return queryset.filter(qs_filter)