filtersets.py 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990
  1. import django_filters
  2. from django.contrib.auth.models import User
  3. from django.utils.translation import gettext as _
  4. from extras.filtersets import LocalConfigContextFilterSet
  5. from extras.models import ConfigTemplate
  6. from ipam.models import ASN, L2VPN, IPAddress, VRF
  7. from netbox.filtersets import (
  8. BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet,
  9. )
  10. from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
  11. from tenancy.models import *
  12. from utilities.choices import ColorChoices
  13. from utilities.filters import (
  14. ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter,
  15. TreeNodeMultipleChoiceFilter,
  16. )
  17. from virtualization.models import Cluster
  18. from wireless.choices import WirelessRoleChoices, WirelessChannelChoices
  19. from .choices import *
  20. from .constants import *
  21. from .models import *
  22. __all__ = (
  23. 'CableFilterSet',
  24. 'CabledObjectFilterSet',
  25. 'CableTerminationFilterSet',
  26. 'CommonInterfaceFilterSet',
  27. 'ConsoleConnectionFilterSet',
  28. 'ConsolePortFilterSet',
  29. 'ConsolePortTemplateFilterSet',
  30. 'ConsoleServerPortFilterSet',
  31. 'ConsoleServerPortTemplateFilterSet',
  32. 'DeviceBayFilterSet',
  33. 'DeviceBayTemplateFilterSet',
  34. 'DeviceFilterSet',
  35. 'DeviceRoleFilterSet',
  36. 'DeviceTypeFilterSet',
  37. 'FrontPortFilterSet',
  38. 'FrontPortTemplateFilterSet',
  39. 'InterfaceConnectionFilterSet',
  40. 'InterfaceFilterSet',
  41. 'InterfaceTemplateFilterSet',
  42. 'InventoryItemFilterSet',
  43. 'InventoryItemRoleFilterSet',
  44. 'InventoryItemTemplateFilterSet',
  45. 'LocationFilterSet',
  46. 'ManufacturerFilterSet',
  47. 'ModuleBayFilterSet',
  48. 'ModuleBayTemplateFilterSet',
  49. 'ModuleFilterSet',
  50. 'ModuleTypeFilterSet',
  51. 'PathEndpointFilterSet',
  52. 'PlatformFilterSet',
  53. 'PowerConnectionFilterSet',
  54. 'PowerFeedFilterSet',
  55. 'PowerOutletFilterSet',
  56. 'PowerOutletTemplateFilterSet',
  57. 'PowerPanelFilterSet',
  58. 'PowerPortFilterSet',
  59. 'PowerPortTemplateFilterSet',
  60. 'RackFilterSet',
  61. 'RackReservationFilterSet',
  62. 'RackRoleFilterSet',
  63. 'RearPortFilterSet',
  64. 'RearPortTemplateFilterSet',
  65. 'RegionFilterSet',
  66. 'SiteFilterSet',
  67. 'SiteGroupFilterSet',
  68. 'VirtualChassisFilterSet',
  69. 'VirtualDeviceContextFilterSet',
  70. )
  71. class RegionFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  72. parent_id = django_filters.ModelMultipleChoiceFilter(
  73. queryset=Region.objects.all(),
  74. label=_('Parent region (ID)'),
  75. )
  76. parent = django_filters.ModelMultipleChoiceFilter(
  77. field_name='parent__slug',
  78. queryset=Region.objects.all(),
  79. to_field_name='slug',
  80. label=_('Parent region (slug)'),
  81. )
  82. class Meta:
  83. model = Region
  84. fields = ['id', 'name', 'slug', 'description']
  85. class SiteGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  86. parent_id = django_filters.ModelMultipleChoiceFilter(
  87. queryset=SiteGroup.objects.all(),
  88. label=_('Parent site group (ID)'),
  89. )
  90. parent = django_filters.ModelMultipleChoiceFilter(
  91. field_name='parent__slug',
  92. queryset=SiteGroup.objects.all(),
  93. to_field_name='slug',
  94. label=_('Parent site group (slug)'),
  95. )
  96. class Meta:
  97. model = SiteGroup
  98. fields = ['id', 'name', 'slug', 'description']
  99. class SiteFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  100. status = django_filters.MultipleChoiceFilter(
  101. choices=SiteStatusChoices,
  102. null_value=None
  103. )
  104. region_id = TreeNodeMultipleChoiceFilter(
  105. queryset=Region.objects.all(),
  106. field_name='region',
  107. lookup_expr='in',
  108. label=_('Region (ID)'),
  109. )
  110. region = TreeNodeMultipleChoiceFilter(
  111. queryset=Region.objects.all(),
  112. lookup_expr='in',
  113. to_field_name='slug',
  114. label=_('Region (slug)'),
  115. )
  116. group_id = TreeNodeMultipleChoiceFilter(
  117. queryset=SiteGroup.objects.all(),
  118. field_name='group',
  119. lookup_expr='in',
  120. label=_('Group (ID)'),
  121. )
  122. group = TreeNodeMultipleChoiceFilter(
  123. queryset=SiteGroup.objects.all(),
  124. lookup_expr='in',
  125. to_field_name='slug',
  126. label=_('Group (slug)'),
  127. )
  128. asn = django_filters.ModelMultipleChoiceFilter(
  129. field_name='asns__asn',
  130. queryset=ASN.objects.all(),
  131. to_field_name='asn',
  132. label=_('AS (ID)'),
  133. )
  134. asn_id = django_filters.ModelMultipleChoiceFilter(
  135. field_name='asns',
  136. queryset=ASN.objects.all(),
  137. label=_('AS (ID)'),
  138. )
  139. class Meta:
  140. model = Site
  141. fields = (
  142. 'id', 'name', 'slug', 'facility', 'latitude', 'longitude', 'description'
  143. )
  144. def search(self, queryset, name, value):
  145. if not value.strip():
  146. return queryset
  147. qs_filter = (
  148. Q(name__icontains=value) |
  149. Q(facility__icontains=value) |
  150. Q(description__icontains=value) |
  151. Q(physical_address__icontains=value) |
  152. Q(shipping_address__icontains=value) |
  153. Q(comments__icontains=value)
  154. )
  155. try:
  156. qs_filter |= Q(asns__asn=int(value.strip()))
  157. except ValueError:
  158. pass
  159. return queryset.filter(qs_filter).distinct()
  160. class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, OrganizationalModelFilterSet):
  161. region_id = TreeNodeMultipleChoiceFilter(
  162. queryset=Region.objects.all(),
  163. field_name='site__region',
  164. lookup_expr='in',
  165. label=_('Region (ID)'),
  166. )
  167. region = TreeNodeMultipleChoiceFilter(
  168. queryset=Region.objects.all(),
  169. field_name='site__region',
  170. lookup_expr='in',
  171. to_field_name='slug',
  172. label=_('Region (slug)'),
  173. )
  174. site_group_id = TreeNodeMultipleChoiceFilter(
  175. queryset=SiteGroup.objects.all(),
  176. field_name='site__group',
  177. lookup_expr='in',
  178. label=_('Site group (ID)'),
  179. )
  180. site_group = TreeNodeMultipleChoiceFilter(
  181. queryset=SiteGroup.objects.all(),
  182. field_name='site__group',
  183. lookup_expr='in',
  184. to_field_name='slug',
  185. label=_('Site group (slug)'),
  186. )
  187. site_id = django_filters.ModelMultipleChoiceFilter(
  188. queryset=Site.objects.all(),
  189. label=_('Site (ID)'),
  190. )
  191. site = django_filters.ModelMultipleChoiceFilter(
  192. field_name='site__slug',
  193. queryset=Site.objects.all(),
  194. to_field_name='slug',
  195. label=_('Site (slug)'),
  196. )
  197. parent_id = TreeNodeMultipleChoiceFilter(
  198. queryset=Location.objects.all(),
  199. field_name='parent',
  200. lookup_expr='in',
  201. label=_('Location (ID)'),
  202. )
  203. parent = TreeNodeMultipleChoiceFilter(
  204. queryset=Location.objects.all(),
  205. field_name='parent',
  206. lookup_expr='in',
  207. to_field_name='slug',
  208. label=_('Location (slug)'),
  209. )
  210. status = django_filters.MultipleChoiceFilter(
  211. choices=LocationStatusChoices,
  212. null_value=None
  213. )
  214. class Meta:
  215. model = Location
  216. fields = ['id', 'name', 'slug', 'status', 'description']
  217. def search(self, queryset, name, value):
  218. if not value.strip():
  219. return queryset
  220. return queryset.filter(
  221. Q(name__icontains=value) |
  222. Q(description__icontains=value)
  223. )
  224. class RackRoleFilterSet(OrganizationalModelFilterSet):
  225. class Meta:
  226. model = RackRole
  227. fields = ['id', 'name', 'slug', 'color', 'description']
  228. class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  229. region_id = TreeNodeMultipleChoiceFilter(
  230. queryset=Region.objects.all(),
  231. field_name='site__region',
  232. lookup_expr='in',
  233. label=_('Region (ID)'),
  234. )
  235. region = TreeNodeMultipleChoiceFilter(
  236. queryset=Region.objects.all(),
  237. field_name='site__region',
  238. lookup_expr='in',
  239. to_field_name='slug',
  240. label=_('Region (slug)'),
  241. )
  242. site_group_id = TreeNodeMultipleChoiceFilter(
  243. queryset=SiteGroup.objects.all(),
  244. field_name='site__group',
  245. lookup_expr='in',
  246. label=_('Site group (ID)'),
  247. )
  248. site_group = TreeNodeMultipleChoiceFilter(
  249. queryset=SiteGroup.objects.all(),
  250. field_name='site__group',
  251. lookup_expr='in',
  252. to_field_name='slug',
  253. label=_('Site group (slug)'),
  254. )
  255. site_id = django_filters.ModelMultipleChoiceFilter(
  256. queryset=Site.objects.all(),
  257. label=_('Site (ID)'),
  258. )
  259. site = django_filters.ModelMultipleChoiceFilter(
  260. field_name='site__slug',
  261. queryset=Site.objects.all(),
  262. to_field_name='slug',
  263. label=_('Site (slug)'),
  264. )
  265. location_id = TreeNodeMultipleChoiceFilter(
  266. queryset=Location.objects.all(),
  267. field_name='location',
  268. lookup_expr='in',
  269. label=_('Location (ID)'),
  270. )
  271. location = TreeNodeMultipleChoiceFilter(
  272. queryset=Location.objects.all(),
  273. field_name='location',
  274. lookup_expr='in',
  275. to_field_name='slug',
  276. label=_('Location (slug)'),
  277. )
  278. status = django_filters.MultipleChoiceFilter(
  279. choices=RackStatusChoices,
  280. null_value=None
  281. )
  282. type = django_filters.MultipleChoiceFilter(
  283. choices=RackTypeChoices
  284. )
  285. width = django_filters.MultipleChoiceFilter(
  286. choices=RackWidthChoices
  287. )
  288. role_id = django_filters.ModelMultipleChoiceFilter(
  289. queryset=RackRole.objects.all(),
  290. label=_('Role (ID)'),
  291. )
  292. role = django_filters.ModelMultipleChoiceFilter(
  293. field_name='role__slug',
  294. queryset=RackRole.objects.all(),
  295. to_field_name='slug',
  296. label=_('Role (slug)'),
  297. )
  298. serial = MultiValueCharFilter(
  299. lookup_expr='iexact'
  300. )
  301. class Meta:
  302. model = Rack
  303. fields = [
  304. 'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'desc_units', 'outer_width', 'outer_depth',
  305. 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit'
  306. ]
  307. def search(self, queryset, name, value):
  308. if not value.strip():
  309. return queryset
  310. return queryset.filter(
  311. Q(name__icontains=value) |
  312. Q(facility_id__icontains=value) |
  313. Q(serial__icontains=value.strip()) |
  314. Q(asset_tag__icontains=value.strip()) |
  315. Q(comments__icontains=value)
  316. )
  317. class RackReservationFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
  318. rack_id = django_filters.ModelMultipleChoiceFilter(
  319. queryset=Rack.objects.all(),
  320. label=_('Rack (ID)'),
  321. )
  322. site_id = django_filters.ModelMultipleChoiceFilter(
  323. field_name='rack__site',
  324. queryset=Site.objects.all(),
  325. label=_('Site (ID)'),
  326. )
  327. site = django_filters.ModelMultipleChoiceFilter(
  328. field_name='rack__site__slug',
  329. queryset=Site.objects.all(),
  330. to_field_name='slug',
  331. label=_('Site (slug)'),
  332. )
  333. region_id = TreeNodeMultipleChoiceFilter(
  334. queryset=Region.objects.all(),
  335. field_name='rack__site__region',
  336. lookup_expr='in',
  337. label=_('Region (ID)'),
  338. )
  339. region = TreeNodeMultipleChoiceFilter(
  340. queryset=Region.objects.all(),
  341. field_name='rack__site__region',
  342. lookup_expr='in',
  343. to_field_name='slug',
  344. label=_('Region (slug)'),
  345. )
  346. site_group_id = TreeNodeMultipleChoiceFilter(
  347. queryset=SiteGroup.objects.all(),
  348. field_name='rack__site__group',
  349. lookup_expr='in',
  350. label=_('Site group (ID)'),
  351. )
  352. site_group = TreeNodeMultipleChoiceFilter(
  353. queryset=SiteGroup.objects.all(),
  354. field_name='rack__site__group',
  355. lookup_expr='in',
  356. to_field_name='slug',
  357. label=_('Site group (slug)'),
  358. )
  359. location_id = TreeNodeMultipleChoiceFilter(
  360. queryset=Location.objects.all(),
  361. field_name='rack__location',
  362. lookup_expr='in',
  363. label=_('Location (ID)'),
  364. )
  365. location = TreeNodeMultipleChoiceFilter(
  366. queryset=Location.objects.all(),
  367. field_name='rack__location',
  368. lookup_expr='in',
  369. to_field_name='slug',
  370. label=_('Location (slug)'),
  371. )
  372. user_id = django_filters.ModelMultipleChoiceFilter(
  373. queryset=User.objects.all(),
  374. label=_('User (ID)'),
  375. )
  376. user = django_filters.ModelMultipleChoiceFilter(
  377. field_name='user__username',
  378. queryset=User.objects.all(),
  379. to_field_name='username',
  380. label=_('User (name)'),
  381. )
  382. class Meta:
  383. model = RackReservation
  384. fields = ['id', 'created', 'description']
  385. def search(self, queryset, name, value):
  386. if not value.strip():
  387. return queryset
  388. return queryset.filter(
  389. Q(rack__name__icontains=value) |
  390. Q(rack__facility_id__icontains=value) |
  391. Q(user__username__icontains=value) |
  392. Q(description__icontains=value)
  393. )
  394. class ManufacturerFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  395. class Meta:
  396. model = Manufacturer
  397. fields = ['id', 'name', 'slug', 'description']
  398. class DeviceTypeFilterSet(NetBoxModelFilterSet):
  399. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  400. queryset=Manufacturer.objects.all(),
  401. label=_('Manufacturer (ID)'),
  402. )
  403. manufacturer = django_filters.ModelMultipleChoiceFilter(
  404. field_name='manufacturer__slug',
  405. queryset=Manufacturer.objects.all(),
  406. to_field_name='slug',
  407. label=_('Manufacturer (slug)'),
  408. )
  409. default_platform_id = django_filters.ModelMultipleChoiceFilter(
  410. queryset=Platform.objects.all(),
  411. label=_('Default platform (ID)'),
  412. )
  413. default_platform = django_filters.ModelMultipleChoiceFilter(
  414. field_name='default_platform__slug',
  415. queryset=Platform.objects.all(),
  416. to_field_name='slug',
  417. label=_('Default platform (slug)'),
  418. )
  419. has_front_image = django_filters.BooleanFilter(
  420. label=_('Has a front image'),
  421. method='_has_front_image'
  422. )
  423. has_rear_image = django_filters.BooleanFilter(
  424. label=_('Has a rear image'),
  425. method='_has_rear_image'
  426. )
  427. console_ports = django_filters.BooleanFilter(
  428. method='_console_ports',
  429. label=_('Has console ports'),
  430. )
  431. console_server_ports = django_filters.BooleanFilter(
  432. method='_console_server_ports',
  433. label=_('Has console server ports'),
  434. )
  435. power_ports = django_filters.BooleanFilter(
  436. method='_power_ports',
  437. label=_('Has power ports'),
  438. )
  439. power_outlets = django_filters.BooleanFilter(
  440. method='_power_outlets',
  441. label=_('Has power outlets'),
  442. )
  443. interfaces = django_filters.BooleanFilter(
  444. method='_interfaces',
  445. label=_('Has interfaces'),
  446. )
  447. pass_through_ports = django_filters.BooleanFilter(
  448. method='_pass_through_ports',
  449. label=_('Has pass-through ports'),
  450. )
  451. module_bays = django_filters.BooleanFilter(
  452. method='_module_bays',
  453. label=_('Has module bays'),
  454. )
  455. device_bays = django_filters.BooleanFilter(
  456. method='_device_bays',
  457. label=_('Has device bays'),
  458. )
  459. inventory_items = django_filters.BooleanFilter(
  460. method='_inventory_items',
  461. label=_('Has inventory items'),
  462. )
  463. class Meta:
  464. model = DeviceType
  465. fields = [
  466. 'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit',
  467. ]
  468. def search(self, queryset, name, value):
  469. if not value.strip():
  470. return queryset
  471. return queryset.filter(
  472. Q(manufacturer__name__icontains=value) |
  473. Q(model__icontains=value) |
  474. Q(part_number__icontains=value) |
  475. Q(comments__icontains=value)
  476. )
  477. def _has_front_image(self, queryset, name, value):
  478. if value:
  479. return queryset.exclude(front_image='')
  480. else:
  481. return queryset.filter(front_image='')
  482. def _has_rear_image(self, queryset, name, value):
  483. if value:
  484. return queryset.exclude(rear_image='')
  485. else:
  486. return queryset.filter(rear_image='')
  487. def _console_ports(self, queryset, name, value):
  488. return queryset.exclude(consoleporttemplates__isnull=value)
  489. def _console_server_ports(self, queryset, name, value):
  490. return queryset.exclude(consoleserverporttemplates__isnull=value)
  491. def _power_ports(self, queryset, name, value):
  492. return queryset.exclude(powerporttemplates__isnull=value)
  493. def _power_outlets(self, queryset, name, value):
  494. return queryset.exclude(poweroutlettemplates__isnull=value)
  495. def _interfaces(self, queryset, name, value):
  496. return queryset.exclude(interfacetemplates__isnull=value)
  497. def _pass_through_ports(self, queryset, name, value):
  498. return queryset.exclude(
  499. frontporttemplates__isnull=value,
  500. rearporttemplates__isnull=value
  501. )
  502. def _module_bays(self, queryset, name, value):
  503. return queryset.exclude(modulebaytemplates__isnull=value)
  504. def _device_bays(self, queryset, name, value):
  505. return queryset.exclude(devicebaytemplates__isnull=value)
  506. def _inventory_items(self, queryset, name, value):
  507. return queryset.exclude(inventoryitemtemplates__isnull=value)
  508. class ModuleTypeFilterSet(NetBoxModelFilterSet):
  509. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  510. queryset=Manufacturer.objects.all(),
  511. label=_('Manufacturer (ID)'),
  512. )
  513. manufacturer = django_filters.ModelMultipleChoiceFilter(
  514. field_name='manufacturer__slug',
  515. queryset=Manufacturer.objects.all(),
  516. to_field_name='slug',
  517. label=_('Manufacturer (slug)'),
  518. )
  519. console_ports = django_filters.BooleanFilter(
  520. method='_console_ports',
  521. label=_('Has console ports'),
  522. )
  523. console_server_ports = django_filters.BooleanFilter(
  524. method='_console_server_ports',
  525. label=_('Has console server ports'),
  526. )
  527. power_ports = django_filters.BooleanFilter(
  528. method='_power_ports',
  529. label=_('Has power ports'),
  530. )
  531. power_outlets = django_filters.BooleanFilter(
  532. method='_power_outlets',
  533. label=_('Has power outlets'),
  534. )
  535. interfaces = django_filters.BooleanFilter(
  536. method='_interfaces',
  537. label=_('Has interfaces'),
  538. )
  539. pass_through_ports = django_filters.BooleanFilter(
  540. method='_pass_through_ports',
  541. label=_('Has pass-through ports'),
  542. )
  543. class Meta:
  544. model = ModuleType
  545. fields = ['id', 'model', 'part_number', 'weight', 'weight_unit']
  546. def search(self, queryset, name, value):
  547. if not value.strip():
  548. return queryset
  549. return queryset.filter(
  550. Q(manufacturer__name__icontains=value) |
  551. Q(model__icontains=value) |
  552. Q(part_number__icontains=value) |
  553. Q(comments__icontains=value)
  554. )
  555. def _console_ports(self, queryset, name, value):
  556. return queryset.exclude(consoleporttemplates__isnull=value)
  557. def _console_server_ports(self, queryset, name, value):
  558. return queryset.exclude(consoleserverporttemplates__isnull=value)
  559. def _power_ports(self, queryset, name, value):
  560. return queryset.exclude(powerporttemplates__isnull=value)
  561. def _power_outlets(self, queryset, name, value):
  562. return queryset.exclude(poweroutlettemplates__isnull=value)
  563. def _interfaces(self, queryset, name, value):
  564. return queryset.exclude(interfacetemplates__isnull=value)
  565. def _pass_through_ports(self, queryset, name, value):
  566. return queryset.exclude(
  567. frontporttemplates__isnull=value,
  568. rearporttemplates__isnull=value
  569. )
  570. class DeviceTypeComponentFilterSet(django_filters.FilterSet):
  571. q = django_filters.CharFilter(
  572. method='search',
  573. label=_('Search'),
  574. )
  575. devicetype_id = django_filters.ModelMultipleChoiceFilter(
  576. queryset=DeviceType.objects.all(),
  577. field_name='device_type_id',
  578. label=_('Device type (ID)'),
  579. )
  580. def search(self, queryset, name, value):
  581. if not value.strip():
  582. return queryset
  583. return queryset.filter(name__icontains=value)
  584. class ModularDeviceTypeComponentFilterSet(DeviceTypeComponentFilterSet):
  585. moduletype_id = django_filters.ModelMultipleChoiceFilter(
  586. queryset=ModuleType.objects.all(),
  587. field_name='module_type_id',
  588. label=_('Module type (ID)'),
  589. )
  590. class ConsolePortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  591. class Meta:
  592. model = ConsolePortTemplate
  593. fields = ['id', 'name', 'type']
  594. class ConsoleServerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  595. class Meta:
  596. model = ConsoleServerPortTemplate
  597. fields = ['id', 'name', 'type']
  598. class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  599. class Meta:
  600. model = PowerPortTemplate
  601. fields = ['id', 'name', 'type', 'maximum_draw', 'allocated_draw']
  602. class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  603. feed_leg = django_filters.MultipleChoiceFilter(
  604. choices=PowerOutletFeedLegChoices,
  605. null_value=None
  606. )
  607. class Meta:
  608. model = PowerOutletTemplate
  609. fields = ['id', 'name', 'type', 'feed_leg']
  610. class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  611. type = django_filters.MultipleChoiceFilter(
  612. choices=InterfaceTypeChoices,
  613. null_value=None
  614. )
  615. bridge_id = django_filters.ModelMultipleChoiceFilter(
  616. field_name='bridge',
  617. queryset=InterfaceTemplate.objects.all()
  618. )
  619. poe_mode = django_filters.MultipleChoiceFilter(
  620. choices=InterfacePoEModeChoices
  621. )
  622. poe_type = django_filters.MultipleChoiceFilter(
  623. choices=InterfacePoETypeChoices
  624. )
  625. class Meta:
  626. model = InterfaceTemplate
  627. fields = ['id', 'name', 'type', 'enabled', 'mgmt_only']
  628. class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  629. type = django_filters.MultipleChoiceFilter(
  630. choices=PortTypeChoices,
  631. null_value=None
  632. )
  633. class Meta:
  634. model = FrontPortTemplate
  635. fields = ['id', 'name', 'type', 'color']
  636. class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  637. type = django_filters.MultipleChoiceFilter(
  638. choices=PortTypeChoices,
  639. null_value=None
  640. )
  641. class Meta:
  642. model = RearPortTemplate
  643. fields = ['id', 'name', 'type', 'color', 'positions']
  644. class ModuleBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  645. class Meta:
  646. model = ModuleBayTemplate
  647. fields = ['id', 'name']
  648. class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  649. class Meta:
  650. model = DeviceBayTemplate
  651. fields = ['id', 'name']
  652. class InventoryItemTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  653. parent_id = django_filters.ModelMultipleChoiceFilter(
  654. queryset=InventoryItemTemplate.objects.all(),
  655. label=_('Parent inventory item (ID)'),
  656. )
  657. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  658. queryset=Manufacturer.objects.all(),
  659. label=_('Manufacturer (ID)'),
  660. )
  661. manufacturer = django_filters.ModelMultipleChoiceFilter(
  662. field_name='manufacturer__slug',
  663. queryset=Manufacturer.objects.all(),
  664. to_field_name='slug',
  665. label=_('Manufacturer (slug)'),
  666. )
  667. role_id = django_filters.ModelMultipleChoiceFilter(
  668. queryset=InventoryItemRole.objects.all(),
  669. label=_('Role (ID)'),
  670. )
  671. role = django_filters.ModelMultipleChoiceFilter(
  672. field_name='role__slug',
  673. queryset=InventoryItemRole.objects.all(),
  674. to_field_name='slug',
  675. label=_('Role (slug)'),
  676. )
  677. component_type = ContentTypeFilter()
  678. component_id = MultiValueNumberFilter()
  679. class Meta:
  680. model = InventoryItemTemplate
  681. fields = ['id', 'name', 'label', 'part_id']
  682. def search(self, queryset, name, value):
  683. if not value.strip():
  684. return queryset
  685. qs_filter = (
  686. Q(name__icontains=value) |
  687. Q(part_id__icontains=value) |
  688. Q(description__icontains=value)
  689. )
  690. return queryset.filter(qs_filter)
  691. class DeviceRoleFilterSet(OrganizationalModelFilterSet):
  692. config_template_id = django_filters.ModelMultipleChoiceFilter(
  693. queryset=ConfigTemplate.objects.all(),
  694. label=_('Config template (ID)'),
  695. )
  696. class Meta:
  697. model = DeviceRole
  698. fields = ['id', 'name', 'slug', 'color', 'vm_role', 'description']
  699. class PlatformFilterSet(OrganizationalModelFilterSet):
  700. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  701. field_name='manufacturer',
  702. queryset=Manufacturer.objects.all(),
  703. label=_('Manufacturer (ID)'),
  704. )
  705. manufacturer = django_filters.ModelMultipleChoiceFilter(
  706. field_name='manufacturer__slug',
  707. queryset=Manufacturer.objects.all(),
  708. to_field_name='slug',
  709. label=_('Manufacturer (slug)'),
  710. )
  711. config_template_id = django_filters.ModelMultipleChoiceFilter(
  712. queryset=ConfigTemplate.objects.all(),
  713. label=_('Config template (ID)'),
  714. )
  715. class Meta:
  716. model = Platform
  717. fields = ['id', 'name', 'slug', 'napalm_driver', 'description']
  718. class DeviceFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet, LocalConfigContextFilterSet):
  719. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  720. field_name='device_type__manufacturer',
  721. queryset=Manufacturer.objects.all(),
  722. label=_('Manufacturer (ID)'),
  723. )
  724. manufacturer = django_filters.ModelMultipleChoiceFilter(
  725. field_name='device_type__manufacturer__slug',
  726. queryset=Manufacturer.objects.all(),
  727. to_field_name='slug',
  728. label=_('Manufacturer (slug)'),
  729. )
  730. device_type = django_filters.ModelMultipleChoiceFilter(
  731. field_name='device_type__slug',
  732. queryset=DeviceType.objects.all(),
  733. to_field_name='slug',
  734. label=_('Device type (slug)'),
  735. )
  736. device_type_id = django_filters.ModelMultipleChoiceFilter(
  737. queryset=DeviceType.objects.all(),
  738. label=_('Device type (ID)'),
  739. )
  740. role_id = django_filters.ModelMultipleChoiceFilter(
  741. field_name='device_role_id',
  742. queryset=DeviceRole.objects.all(),
  743. label=_('Role (ID)'),
  744. )
  745. role = django_filters.ModelMultipleChoiceFilter(
  746. field_name='device_role__slug',
  747. queryset=DeviceRole.objects.all(),
  748. to_field_name='slug',
  749. label=_('Role (slug)'),
  750. )
  751. parent_device_id = django_filters.ModelMultipleChoiceFilter(
  752. field_name='parent_bay__device',
  753. queryset=Device.objects.all(),
  754. label=_('Parent Device (ID)'),
  755. )
  756. platform_id = django_filters.ModelMultipleChoiceFilter(
  757. queryset=Platform.objects.all(),
  758. label=_('Platform (ID)'),
  759. )
  760. platform = django_filters.ModelMultipleChoiceFilter(
  761. field_name='platform__slug',
  762. queryset=Platform.objects.all(),
  763. to_field_name='slug',
  764. label=_('Platform (slug)'),
  765. )
  766. region_id = TreeNodeMultipleChoiceFilter(
  767. queryset=Region.objects.all(),
  768. field_name='site__region',
  769. lookup_expr='in',
  770. label=_('Region (ID)'),
  771. )
  772. region = TreeNodeMultipleChoiceFilter(
  773. queryset=Region.objects.all(),
  774. field_name='site__region',
  775. lookup_expr='in',
  776. to_field_name='slug',
  777. label=_('Region (slug)'),
  778. )
  779. site_group_id = TreeNodeMultipleChoiceFilter(
  780. queryset=SiteGroup.objects.all(),
  781. field_name='site__group',
  782. lookup_expr='in',
  783. label=_('Site group (ID)'),
  784. )
  785. site_group = TreeNodeMultipleChoiceFilter(
  786. queryset=SiteGroup.objects.all(),
  787. field_name='site__group',
  788. lookup_expr='in',
  789. to_field_name='slug',
  790. label=_('Site group (slug)'),
  791. )
  792. site_id = django_filters.ModelMultipleChoiceFilter(
  793. queryset=Site.objects.all(),
  794. label=_('Site (ID)'),
  795. )
  796. site = django_filters.ModelMultipleChoiceFilter(
  797. field_name='site__slug',
  798. queryset=Site.objects.all(),
  799. to_field_name='slug',
  800. label=_('Site name (slug)'),
  801. )
  802. location_id = TreeNodeMultipleChoiceFilter(
  803. queryset=Location.objects.all(),
  804. field_name='location',
  805. lookup_expr='in',
  806. label=_('Location (ID)'),
  807. )
  808. rack_id = django_filters.ModelMultipleChoiceFilter(
  809. field_name='rack',
  810. queryset=Rack.objects.all(),
  811. label=_('Rack (ID)'),
  812. )
  813. cluster_id = django_filters.ModelMultipleChoiceFilter(
  814. queryset=Cluster.objects.all(),
  815. label=_('VM cluster (ID)'),
  816. )
  817. model = django_filters.ModelMultipleChoiceFilter(
  818. field_name='device_type__slug',
  819. queryset=DeviceType.objects.all(),
  820. to_field_name='slug',
  821. label=_('Device model (slug)'),
  822. )
  823. name = MultiValueCharFilter(
  824. lookup_expr='iexact'
  825. )
  826. status = django_filters.MultipleChoiceFilter(
  827. choices=DeviceStatusChoices,
  828. null_value=None
  829. )
  830. is_full_depth = django_filters.BooleanFilter(
  831. field_name='device_type__is_full_depth',
  832. label=_('Is full depth'),
  833. )
  834. mac_address = MultiValueMACAddressFilter(
  835. field_name='interfaces__mac_address',
  836. label=_('MAC address'),
  837. )
  838. serial = MultiValueCharFilter(
  839. lookup_expr='iexact'
  840. )
  841. has_primary_ip = django_filters.BooleanFilter(
  842. method='_has_primary_ip',
  843. label=_('Has a primary IP'),
  844. )
  845. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  846. field_name='virtual_chassis',
  847. queryset=VirtualChassis.objects.all(),
  848. label=_('Virtual chassis (ID)'),
  849. )
  850. virtual_chassis_member = django_filters.BooleanFilter(
  851. method='_virtual_chassis_member',
  852. label=_('Is a virtual chassis member')
  853. )
  854. config_template_id = django_filters.ModelMultipleChoiceFilter(
  855. queryset=ConfigTemplate.objects.all(),
  856. label=_('Config template (ID)'),
  857. )
  858. console_ports = django_filters.BooleanFilter(
  859. method='_console_ports',
  860. label=_('Has console ports'),
  861. )
  862. console_server_ports = django_filters.BooleanFilter(
  863. method='_console_server_ports',
  864. label=_('Has console server ports'),
  865. )
  866. power_ports = django_filters.BooleanFilter(
  867. method='_power_ports',
  868. label=_('Has power ports'),
  869. )
  870. power_outlets = django_filters.BooleanFilter(
  871. method='_power_outlets',
  872. label=_('Has power outlets'),
  873. )
  874. interfaces = django_filters.BooleanFilter(
  875. method='_interfaces',
  876. label=_('Has interfaces'),
  877. )
  878. pass_through_ports = django_filters.BooleanFilter(
  879. method='_pass_through_ports',
  880. label=_('Has pass-through ports'),
  881. )
  882. module_bays = django_filters.BooleanFilter(
  883. method='_module_bays',
  884. label=_('Has module bays'),
  885. )
  886. device_bays = django_filters.BooleanFilter(
  887. method='_device_bays',
  888. label=_('Has device bays'),
  889. )
  890. primary_ip4_id = django_filters.ModelMultipleChoiceFilter(
  891. field_name='primary_ip4',
  892. queryset=IPAddress.objects.all(),
  893. label=_('Primary IPv4 (ID)'),
  894. )
  895. primary_ip6_id = django_filters.ModelMultipleChoiceFilter(
  896. field_name='primary_ip6',
  897. queryset=IPAddress.objects.all(),
  898. label=_('Primary IPv6 (ID)'),
  899. )
  900. class Meta:
  901. model = Device
  902. fields = ['id', 'asset_tag', 'face', 'position', 'airflow', 'vc_position', 'vc_priority']
  903. def search(self, queryset, name, value):
  904. if not value.strip():
  905. return queryset
  906. return queryset.filter(
  907. Q(name__icontains=value) |
  908. Q(serial__icontains=value.strip()) |
  909. Q(inventoryitems__serial__icontains=value.strip()) |
  910. Q(asset_tag__icontains=value.strip()) |
  911. Q(comments__icontains=value) |
  912. Q(primary_ip4__address__startswith=value) |
  913. Q(primary_ip6__address__startswith=value)
  914. ).distinct()
  915. def _has_primary_ip(self, queryset, name, value):
  916. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  917. if value:
  918. return queryset.filter(params)
  919. return queryset.exclude(params)
  920. def _virtual_chassis_member(self, queryset, name, value):
  921. return queryset.exclude(virtual_chassis__isnull=value)
  922. def _console_ports(self, queryset, name, value):
  923. return queryset.exclude(consoleports__isnull=value)
  924. def _console_server_ports(self, queryset, name, value):
  925. return queryset.exclude(consoleserverports__isnull=value)
  926. def _power_ports(self, queryset, name, value):
  927. return queryset.exclude(powerports__isnull=value)
  928. def _power_outlets(self, queryset, name, value):
  929. return queryset.exclude(poweroutlets__isnull=value)
  930. def _interfaces(self, queryset, name, value):
  931. return queryset.exclude(interfaces__isnull=value)
  932. def _pass_through_ports(self, queryset, name, value):
  933. return queryset.exclude(
  934. frontports__isnull=value,
  935. rearports__isnull=value
  936. )
  937. def _module_bays(self, queryset, name, value):
  938. return queryset.exclude(modulebays__isnull=value)
  939. def _device_bays(self, queryset, name, value):
  940. return queryset.exclude(devicebays__isnull=value)
  941. class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
  942. device_id = django_filters.ModelMultipleChoiceFilter(
  943. field_name='device',
  944. queryset=Device.objects.all(),
  945. label='VDC (ID)',
  946. )
  947. device = django_filters.ModelMultipleChoiceFilter(
  948. field_name='device',
  949. queryset=Device.objects.all(),
  950. label='Device model',
  951. )
  952. status = django_filters.MultipleChoiceFilter(
  953. choices=VirtualDeviceContextStatusChoices
  954. )
  955. has_primary_ip = django_filters.BooleanFilter(
  956. method='_has_primary_ip',
  957. label='Has a primary IP',
  958. )
  959. class Meta:
  960. model = VirtualDeviceContext
  961. fields = ['id', 'device', 'name']
  962. def search(self, queryset, name, value):
  963. if not value.strip():
  964. return queryset
  965. return queryset.filter(
  966. Q(name__icontains=value) |
  967. Q(identifier=value.strip())
  968. ).distinct()
  969. def _has_primary_ip(self, queryset, name, value):
  970. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  971. if value:
  972. return queryset.filter(params)
  973. return queryset.exclude(params)
  974. class ModuleFilterSet(NetBoxModelFilterSet):
  975. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  976. field_name='module_type__manufacturer',
  977. queryset=Manufacturer.objects.all(),
  978. label=_('Manufacturer (ID)'),
  979. )
  980. manufacturer = django_filters.ModelMultipleChoiceFilter(
  981. field_name='module_type__manufacturer__slug',
  982. queryset=Manufacturer.objects.all(),
  983. to_field_name='slug',
  984. label=_('Manufacturer (slug)'),
  985. )
  986. module_type_id = django_filters.ModelMultipleChoiceFilter(
  987. field_name='module_type',
  988. queryset=ModuleType.objects.all(),
  989. label=_('Module type (ID)'),
  990. )
  991. module_type = django_filters.ModelMultipleChoiceFilter(
  992. field_name='module_type__model',
  993. queryset=ModuleType.objects.all(),
  994. to_field_name='model',
  995. label=_('Module type (model)'),
  996. )
  997. module_bay_id = django_filters.ModelMultipleChoiceFilter(
  998. field_name='module_bay',
  999. queryset=ModuleBay.objects.all(),
  1000. to_field_name='id',
  1001. label=_('Module Bay (ID)')
  1002. )
  1003. device_id = django_filters.ModelMultipleChoiceFilter(
  1004. queryset=Device.objects.all(),
  1005. label=_('Device (ID)'),
  1006. )
  1007. status = django_filters.MultipleChoiceFilter(
  1008. choices=ModuleStatusChoices,
  1009. null_value=None
  1010. )
  1011. serial = MultiValueCharFilter(
  1012. lookup_expr='iexact'
  1013. )
  1014. class Meta:
  1015. model = Module
  1016. fields = ['id', 'status', 'asset_tag']
  1017. def search(self, queryset, name, value):
  1018. if not value.strip():
  1019. return queryset
  1020. return queryset.filter(
  1021. Q(device__name__icontains=value.strip()) |
  1022. Q(serial__icontains=value.strip()) |
  1023. Q(asset_tag__icontains=value.strip()) |
  1024. Q(comments__icontains=value)
  1025. ).distinct()
  1026. class DeviceComponentFilterSet(django_filters.FilterSet):
  1027. q = django_filters.CharFilter(
  1028. method='search',
  1029. label=_('Search'),
  1030. )
  1031. region_id = TreeNodeMultipleChoiceFilter(
  1032. queryset=Region.objects.all(),
  1033. field_name='device__site__region',
  1034. lookup_expr='in',
  1035. label=_('Region (ID)'),
  1036. )
  1037. region = TreeNodeMultipleChoiceFilter(
  1038. queryset=Region.objects.all(),
  1039. field_name='device__site__region',
  1040. lookup_expr='in',
  1041. to_field_name='slug',
  1042. label=_('Region (slug)'),
  1043. )
  1044. site_group_id = TreeNodeMultipleChoiceFilter(
  1045. queryset=SiteGroup.objects.all(),
  1046. field_name='device__site__group',
  1047. lookup_expr='in',
  1048. label=_('Site group (ID)'),
  1049. )
  1050. site_group = TreeNodeMultipleChoiceFilter(
  1051. queryset=SiteGroup.objects.all(),
  1052. field_name='device__site__group',
  1053. lookup_expr='in',
  1054. to_field_name='slug',
  1055. label=_('Site group (slug)'),
  1056. )
  1057. site_id = django_filters.ModelMultipleChoiceFilter(
  1058. field_name='device__site',
  1059. queryset=Site.objects.all(),
  1060. label=_('Site (ID)'),
  1061. )
  1062. site = django_filters.ModelMultipleChoiceFilter(
  1063. field_name='device__site__slug',
  1064. queryset=Site.objects.all(),
  1065. to_field_name='slug',
  1066. label=_('Site name (slug)'),
  1067. )
  1068. location_id = django_filters.ModelMultipleChoiceFilter(
  1069. field_name='device__location',
  1070. queryset=Location.objects.all(),
  1071. label=_('Location (ID)'),
  1072. )
  1073. location = django_filters.ModelMultipleChoiceFilter(
  1074. field_name='device__location__slug',
  1075. queryset=Location.objects.all(),
  1076. to_field_name='slug',
  1077. label=_('Location (slug)'),
  1078. )
  1079. rack_id = django_filters.ModelMultipleChoiceFilter(
  1080. field_name='device__rack',
  1081. queryset=Rack.objects.all(),
  1082. label=_('Rack (ID)'),
  1083. )
  1084. rack = django_filters.ModelMultipleChoiceFilter(
  1085. field_name='device__rack__name',
  1086. queryset=Rack.objects.all(),
  1087. to_field_name='name',
  1088. label=_('Rack (name)'),
  1089. )
  1090. device_id = django_filters.ModelMultipleChoiceFilter(
  1091. queryset=Device.objects.all(),
  1092. label=_('Device (ID)'),
  1093. )
  1094. device = django_filters.ModelMultipleChoiceFilter(
  1095. field_name='device__name',
  1096. queryset=Device.objects.all(),
  1097. to_field_name='name',
  1098. label=_('Device (name)'),
  1099. )
  1100. device_type_id = django_filters.ModelMultipleChoiceFilter(
  1101. field_name='device__device_type',
  1102. queryset=DeviceType.objects.all(),
  1103. label=_('Device type (ID)'),
  1104. )
  1105. device_type = django_filters.ModelMultipleChoiceFilter(
  1106. field_name='device__device_type__model',
  1107. queryset=DeviceType.objects.all(),
  1108. to_field_name='model',
  1109. label=_('Device type (model)'),
  1110. )
  1111. device_role_id = django_filters.ModelMultipleChoiceFilter(
  1112. field_name='device__device_role',
  1113. queryset=DeviceRole.objects.all(),
  1114. label=_('Device role (ID)'),
  1115. )
  1116. device_role = django_filters.ModelMultipleChoiceFilter(
  1117. field_name='device__device_role__slug',
  1118. queryset=DeviceRole.objects.all(),
  1119. to_field_name='slug',
  1120. label=_('Device role (slug)'),
  1121. )
  1122. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  1123. field_name='device__virtual_chassis',
  1124. queryset=VirtualChassis.objects.all(),
  1125. label=_('Virtual Chassis (ID)')
  1126. )
  1127. virtual_chassis = django_filters.ModelMultipleChoiceFilter(
  1128. field_name='device__virtual_chassis__name',
  1129. queryset=VirtualChassis.objects.all(),
  1130. to_field_name='name',
  1131. label=_('Virtual Chassis'),
  1132. )
  1133. def search(self, queryset, name, value):
  1134. if not value.strip():
  1135. return queryset
  1136. return queryset.filter(
  1137. Q(name__icontains=value) |
  1138. Q(label__icontains=value) |
  1139. Q(description__icontains=value)
  1140. )
  1141. class ModularDeviceComponentFilterSet(DeviceComponentFilterSet):
  1142. """
  1143. Extends DeviceComponentFilterSet to add a module_id filter for components
  1144. which can be associated with a particular module within a device.
  1145. """
  1146. module_id = django_filters.ModelMultipleChoiceFilter(
  1147. queryset=Module.objects.all(),
  1148. label=_('Module (ID)'),
  1149. )
  1150. class CabledObjectFilterSet(django_filters.FilterSet):
  1151. cabled = django_filters.BooleanFilter(
  1152. field_name='cable',
  1153. lookup_expr='isnull',
  1154. exclude=True
  1155. )
  1156. occupied = django_filters.BooleanFilter(
  1157. method='filter_occupied'
  1158. )
  1159. def filter_occupied(self, queryset, name, value):
  1160. if value:
  1161. return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True))
  1162. else:
  1163. return queryset.filter(cable__isnull=True, mark_connected=False)
  1164. class PathEndpointFilterSet(django_filters.FilterSet):
  1165. connected = django_filters.BooleanFilter(
  1166. method='filter_connected'
  1167. )
  1168. def filter_connected(self, queryset, name, value):
  1169. if value:
  1170. return queryset.filter(_path__is_active=True)
  1171. else:
  1172. return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
  1173. class ConsolePortFilterSet(
  1174. ModularDeviceComponentFilterSet,
  1175. NetBoxModelFilterSet,
  1176. CabledObjectFilterSet,
  1177. PathEndpointFilterSet
  1178. ):
  1179. type = django_filters.MultipleChoiceFilter(
  1180. choices=ConsolePortTypeChoices,
  1181. null_value=None
  1182. )
  1183. class Meta:
  1184. model = ConsolePort
  1185. fields = ['id', 'name', 'label', 'description', 'cable_end']
  1186. class ConsoleServerPortFilterSet(
  1187. ModularDeviceComponentFilterSet,
  1188. NetBoxModelFilterSet,
  1189. CabledObjectFilterSet,
  1190. PathEndpointFilterSet
  1191. ):
  1192. type = django_filters.MultipleChoiceFilter(
  1193. choices=ConsolePortTypeChoices,
  1194. null_value=None
  1195. )
  1196. class Meta:
  1197. model = ConsoleServerPort
  1198. fields = ['id', 'name', 'label', 'description', 'cable_end']
  1199. class PowerPortFilterSet(
  1200. ModularDeviceComponentFilterSet,
  1201. NetBoxModelFilterSet,
  1202. CabledObjectFilterSet,
  1203. PathEndpointFilterSet
  1204. ):
  1205. type = django_filters.MultipleChoiceFilter(
  1206. choices=PowerPortTypeChoices,
  1207. null_value=None
  1208. )
  1209. class Meta:
  1210. model = PowerPort
  1211. fields = ['id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'cable_end']
  1212. class PowerOutletFilterSet(
  1213. ModularDeviceComponentFilterSet,
  1214. NetBoxModelFilterSet,
  1215. CabledObjectFilterSet,
  1216. PathEndpointFilterSet
  1217. ):
  1218. type = django_filters.MultipleChoiceFilter(
  1219. choices=PowerOutletTypeChoices,
  1220. null_value=None
  1221. )
  1222. feed_leg = django_filters.MultipleChoiceFilter(
  1223. choices=PowerOutletFeedLegChoices,
  1224. null_value=None
  1225. )
  1226. class Meta:
  1227. model = PowerOutlet
  1228. fields = ['id', 'name', 'label', 'feed_leg', 'description', 'cable_end']
  1229. class CommonInterfaceFilterSet(django_filters.FilterSet):
  1230. vlan_id = django_filters.CharFilter(
  1231. method='filter_vlan_id',
  1232. label=_('Assigned VLAN')
  1233. )
  1234. vlan = django_filters.CharFilter(
  1235. method='filter_vlan',
  1236. label=_('Assigned VID')
  1237. )
  1238. vrf_id = django_filters.ModelMultipleChoiceFilter(
  1239. field_name='vrf',
  1240. queryset=VRF.objects.all(),
  1241. label=_('VRF'),
  1242. )
  1243. vrf = django_filters.ModelMultipleChoiceFilter(
  1244. field_name='vrf__rd',
  1245. queryset=VRF.objects.all(),
  1246. to_field_name='rd',
  1247. label=_('VRF (RD)'),
  1248. )
  1249. l2vpn_id = django_filters.ModelMultipleChoiceFilter(
  1250. field_name='l2vpn_terminations__l2vpn',
  1251. queryset=L2VPN.objects.all(),
  1252. label=_('L2VPN (ID)'),
  1253. )
  1254. l2vpn = django_filters.ModelMultipleChoiceFilter(
  1255. field_name='l2vpn_terminations__l2vpn__identifier',
  1256. queryset=L2VPN.objects.all(),
  1257. to_field_name='identifier',
  1258. label=_('L2VPN'),
  1259. )
  1260. def filter_vlan_id(self, queryset, name, value):
  1261. value = value.strip()
  1262. if not value:
  1263. return queryset
  1264. return queryset.filter(
  1265. Q(untagged_vlan_id=value) |
  1266. Q(tagged_vlans=value)
  1267. )
  1268. def filter_vlan(self, queryset, name, value):
  1269. value = value.strip()
  1270. if not value:
  1271. return queryset
  1272. return queryset.filter(
  1273. Q(untagged_vlan_id__vid=value) |
  1274. Q(tagged_vlans__vid=value)
  1275. )
  1276. class InterfaceFilterSet(
  1277. ModularDeviceComponentFilterSet,
  1278. NetBoxModelFilterSet,
  1279. CabledObjectFilterSet,
  1280. PathEndpointFilterSet,
  1281. CommonInterfaceFilterSet
  1282. ):
  1283. # Override device and device_id filters from DeviceComponentFilterSet to match against any peer virtual chassis
  1284. # members
  1285. device = MultiValueCharFilter(
  1286. method='filter_device',
  1287. field_name='name',
  1288. label=_('Device'),
  1289. )
  1290. device_id = MultiValueNumberFilter(
  1291. method='filter_device_id',
  1292. field_name='pk',
  1293. label=_('Device (ID)'),
  1294. )
  1295. kind = django_filters.CharFilter(
  1296. method='filter_kind',
  1297. label=_('Kind of interface'),
  1298. )
  1299. parent_id = django_filters.ModelMultipleChoiceFilter(
  1300. field_name='parent',
  1301. queryset=Interface.objects.all(),
  1302. label=_('Parent interface (ID)'),
  1303. )
  1304. bridge_id = django_filters.ModelMultipleChoiceFilter(
  1305. field_name='bridge',
  1306. queryset=Interface.objects.all(),
  1307. label=_('Bridged interface (ID)'),
  1308. )
  1309. lag_id = django_filters.ModelMultipleChoiceFilter(
  1310. field_name='lag',
  1311. queryset=Interface.objects.all(),
  1312. label=_('LAG interface (ID)'),
  1313. )
  1314. speed = MultiValueNumberFilter()
  1315. duplex = django_filters.MultipleChoiceFilter(
  1316. choices=InterfaceDuplexChoices
  1317. )
  1318. mac_address = MultiValueMACAddressFilter()
  1319. wwn = MultiValueWWNFilter()
  1320. poe_mode = django_filters.MultipleChoiceFilter(
  1321. choices=InterfacePoEModeChoices
  1322. )
  1323. poe_type = django_filters.MultipleChoiceFilter(
  1324. choices=InterfacePoETypeChoices
  1325. )
  1326. type = django_filters.MultipleChoiceFilter(
  1327. choices=InterfaceTypeChoices,
  1328. null_value=None
  1329. )
  1330. rf_role = django_filters.MultipleChoiceFilter(
  1331. choices=WirelessRoleChoices
  1332. )
  1333. rf_channel = django_filters.MultipleChoiceFilter(
  1334. choices=WirelessChannelChoices
  1335. )
  1336. vdc_id = django_filters.ModelMultipleChoiceFilter(
  1337. field_name='vdcs',
  1338. queryset=VirtualDeviceContext.objects.all(),
  1339. label='Virtual Device Context',
  1340. )
  1341. vdc_identifier = django_filters.ModelMultipleChoiceFilter(
  1342. field_name='vdcs__identifier',
  1343. queryset=VirtualDeviceContext.objects.all(),
  1344. to_field_name='identifier',
  1345. label='Virtual Device Context (Identifier)',
  1346. )
  1347. vdc = django_filters.ModelMultipleChoiceFilter(
  1348. field_name='vdcs__name',
  1349. queryset=VirtualDeviceContext.objects.all(),
  1350. to_field_name='name',
  1351. label='Virtual Device Context',
  1352. )
  1353. class Meta:
  1354. model = Interface
  1355. fields = [
  1356. 'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 'poe_type', 'mode', 'rf_role',
  1357. 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description', 'cable_end',
  1358. ]
  1359. def filter_device(self, queryset, name, value):
  1360. try:
  1361. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  1362. vc_interface_ids = []
  1363. for device in devices:
  1364. vc_interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  1365. return queryset.filter(pk__in=vc_interface_ids)
  1366. except Device.DoesNotExist:
  1367. return queryset.none()
  1368. def filter_device_id(self, queryset, name, id_list):
  1369. # Include interfaces belonging to peer virtual chassis members
  1370. vc_interface_ids = []
  1371. try:
  1372. devices = Device.objects.filter(pk__in=id_list)
  1373. for device in devices:
  1374. vc_interface_ids += device.vc_interfaces(if_master=False).values_list('id', flat=True)
  1375. return queryset.filter(pk__in=vc_interface_ids)
  1376. except Device.DoesNotExist:
  1377. return queryset.none()
  1378. def filter_kind(self, queryset, name, value):
  1379. value = value.strip().lower()
  1380. return {
  1381. 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES),
  1382. 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES),
  1383. 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES),
  1384. }.get(value, queryset.none())
  1385. class FrontPortFilterSet(
  1386. ModularDeviceComponentFilterSet,
  1387. NetBoxModelFilterSet,
  1388. CabledObjectFilterSet
  1389. ):
  1390. type = django_filters.MultipleChoiceFilter(
  1391. choices=PortTypeChoices,
  1392. null_value=None
  1393. )
  1394. class Meta:
  1395. model = FrontPort
  1396. fields = ['id', 'name', 'label', 'type', 'color', 'description', 'cable_end']
  1397. class RearPortFilterSet(
  1398. ModularDeviceComponentFilterSet,
  1399. NetBoxModelFilterSet,
  1400. CabledObjectFilterSet
  1401. ):
  1402. type = django_filters.MultipleChoiceFilter(
  1403. choices=PortTypeChoices,
  1404. null_value=None
  1405. )
  1406. class Meta:
  1407. model = RearPort
  1408. fields = ['id', 'name', 'label', 'type', 'color', 'positions', 'description', 'cable_end']
  1409. class ModuleBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1410. class Meta:
  1411. model = ModuleBay
  1412. fields = ['id', 'name', 'label', 'description']
  1413. class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1414. class Meta:
  1415. model = DeviceBay
  1416. fields = ['id', 'name', 'label', 'description']
  1417. class InventoryItemFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1418. parent_id = django_filters.ModelMultipleChoiceFilter(
  1419. queryset=InventoryItem.objects.all(),
  1420. label=_('Parent inventory item (ID)'),
  1421. )
  1422. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  1423. queryset=Manufacturer.objects.all(),
  1424. label=_('Manufacturer (ID)'),
  1425. )
  1426. manufacturer = django_filters.ModelMultipleChoiceFilter(
  1427. field_name='manufacturer__slug',
  1428. queryset=Manufacturer.objects.all(),
  1429. to_field_name='slug',
  1430. label=_('Manufacturer (slug)'),
  1431. )
  1432. role_id = django_filters.ModelMultipleChoiceFilter(
  1433. queryset=InventoryItemRole.objects.all(),
  1434. label=_('Role (ID)'),
  1435. )
  1436. role = django_filters.ModelMultipleChoiceFilter(
  1437. field_name='role__slug',
  1438. queryset=InventoryItemRole.objects.all(),
  1439. to_field_name='slug',
  1440. label=_('Role (slug)'),
  1441. )
  1442. component_type = ContentTypeFilter()
  1443. component_id = MultiValueNumberFilter()
  1444. serial = MultiValueCharFilter(
  1445. lookup_expr='iexact'
  1446. )
  1447. class Meta:
  1448. model = InventoryItem
  1449. fields = ['id', 'name', 'label', 'part_id', 'asset_tag', 'discovered']
  1450. def search(self, queryset, name, value):
  1451. if not value.strip():
  1452. return queryset
  1453. qs_filter = (
  1454. Q(name__icontains=value) |
  1455. Q(part_id__icontains=value) |
  1456. Q(serial__icontains=value) |
  1457. Q(asset_tag__icontains=value) |
  1458. Q(description__icontains=value)
  1459. )
  1460. return queryset.filter(qs_filter)
  1461. class InventoryItemRoleFilterSet(OrganizationalModelFilterSet):
  1462. class Meta:
  1463. model = InventoryItemRole
  1464. fields = ['id', 'name', 'slug', 'color']
  1465. class VirtualChassisFilterSet(NetBoxModelFilterSet):
  1466. master_id = django_filters.ModelMultipleChoiceFilter(
  1467. queryset=Device.objects.all(),
  1468. label=_('Master (ID)'),
  1469. )
  1470. master = django_filters.ModelMultipleChoiceFilter(
  1471. field_name='master__name',
  1472. queryset=Device.objects.all(),
  1473. to_field_name='name',
  1474. label=_('Master (name)'),
  1475. )
  1476. region_id = TreeNodeMultipleChoiceFilter(
  1477. queryset=Region.objects.all(),
  1478. field_name='master__site__region',
  1479. lookup_expr='in',
  1480. label=_('Region (ID)'),
  1481. )
  1482. region = TreeNodeMultipleChoiceFilter(
  1483. queryset=Region.objects.all(),
  1484. field_name='master__site__region',
  1485. lookup_expr='in',
  1486. to_field_name='slug',
  1487. label=_('Region (slug)'),
  1488. )
  1489. site_group_id = TreeNodeMultipleChoiceFilter(
  1490. queryset=SiteGroup.objects.all(),
  1491. field_name='master__site__group',
  1492. lookup_expr='in',
  1493. label=_('Site group (ID)'),
  1494. )
  1495. site_group = TreeNodeMultipleChoiceFilter(
  1496. queryset=SiteGroup.objects.all(),
  1497. field_name='master__site__group',
  1498. lookup_expr='in',
  1499. to_field_name='slug',
  1500. label=_('Site group (slug)'),
  1501. )
  1502. site_id = django_filters.ModelMultipleChoiceFilter(
  1503. field_name='master__site',
  1504. queryset=Site.objects.all(),
  1505. label=_('Site (ID)'),
  1506. )
  1507. site = django_filters.ModelMultipleChoiceFilter(
  1508. field_name='master__site__slug',
  1509. queryset=Site.objects.all(),
  1510. to_field_name='slug',
  1511. label=_('Site name (slug)'),
  1512. )
  1513. tenant_id = django_filters.ModelMultipleChoiceFilter(
  1514. field_name='master__tenant',
  1515. queryset=Tenant.objects.all(),
  1516. label=_('Tenant (ID)'),
  1517. )
  1518. tenant = django_filters.ModelMultipleChoiceFilter(
  1519. field_name='master__tenant__slug',
  1520. queryset=Tenant.objects.all(),
  1521. to_field_name='slug',
  1522. label=_('Tenant (slug)'),
  1523. )
  1524. class Meta:
  1525. model = VirtualChassis
  1526. fields = ['id', 'domain', 'name']
  1527. def search(self, queryset, name, value):
  1528. if not value.strip():
  1529. return queryset
  1530. qs_filter = (
  1531. Q(name__icontains=value) |
  1532. Q(members__name__icontains=value) |
  1533. Q(domain__icontains=value)
  1534. )
  1535. return queryset.filter(qs_filter).distinct()
  1536. class CableFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
  1537. termination_a_type = ContentTypeFilter(
  1538. field_name='terminations__termination_type'
  1539. )
  1540. termination_a_id = MultiValueNumberFilter(
  1541. method='filter_by_cable_end_a',
  1542. field_name='terminations__termination_id'
  1543. )
  1544. termination_b_type = ContentTypeFilter(
  1545. field_name='terminations__termination_type'
  1546. )
  1547. termination_b_id = MultiValueNumberFilter(
  1548. method='filter_by_cable_end_b',
  1549. field_name='terminations__termination_id'
  1550. )
  1551. type = django_filters.MultipleChoiceFilter(
  1552. choices=CableTypeChoices
  1553. )
  1554. status = django_filters.MultipleChoiceFilter(
  1555. choices=LinkStatusChoices
  1556. )
  1557. color = django_filters.MultipleChoiceFilter(
  1558. choices=ColorChoices
  1559. )
  1560. device_id = MultiValueNumberFilter(
  1561. method='filter_by_termination'
  1562. )
  1563. device = MultiValueCharFilter(
  1564. method='filter_by_termination',
  1565. field_name='device__name'
  1566. )
  1567. rack_id = MultiValueNumberFilter(
  1568. method='filter_by_termination',
  1569. field_name='rack_id'
  1570. )
  1571. rack = MultiValueCharFilter(
  1572. method='filter_by_termination',
  1573. field_name='rack__name'
  1574. )
  1575. location_id = MultiValueNumberFilter(
  1576. method='filter_by_termination',
  1577. field_name='location_id'
  1578. )
  1579. location = MultiValueCharFilter(
  1580. method='filter_by_termination',
  1581. field_name='location__name'
  1582. )
  1583. site_id = MultiValueNumberFilter(
  1584. method='filter_by_termination',
  1585. field_name='site_id'
  1586. )
  1587. site = MultiValueCharFilter(
  1588. method='filter_by_termination',
  1589. field_name='site__slug'
  1590. )
  1591. class Meta:
  1592. model = Cable
  1593. fields = ['id', 'label', 'length', 'length_unit']
  1594. def search(self, queryset, name, value):
  1595. if not value.strip():
  1596. return queryset
  1597. return queryset.filter(label__icontains=value)
  1598. def filter_by_termination(self, queryset, name, value):
  1599. # Filter by a related object cached on CableTermination. Note the underscore preceding the field name.
  1600. # Supported objects: device, rack, location, site
  1601. return queryset.filter(**{f'terminations___{name}__in': value}).distinct()
  1602. def filter_by_cable_end(self, queryset, name, value, side):
  1603. # Filter by termination id and cable_end type
  1604. return queryset.filter(**{f'{name}__in': value, 'terminations__cable_end': side}).distinct()
  1605. def filter_by_cable_end_a(self, queryset, name, value):
  1606. # Filter by termination id and cable_end type
  1607. return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_A)
  1608. def filter_by_cable_end_b(self, queryset, name, value):
  1609. # Filter by termination id and cable_end type
  1610. return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_B)
  1611. class CableTerminationFilterSet(BaseFilterSet):
  1612. termination_type = ContentTypeFilter()
  1613. class Meta:
  1614. model = CableTermination
  1615. fields = ['id', 'cable', 'cable_end', 'termination_type', 'termination_id']
  1616. class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
  1617. region_id = TreeNodeMultipleChoiceFilter(
  1618. queryset=Region.objects.all(),
  1619. field_name='site__region',
  1620. lookup_expr='in',
  1621. label=_('Region (ID)'),
  1622. )
  1623. region = TreeNodeMultipleChoiceFilter(
  1624. queryset=Region.objects.all(),
  1625. field_name='site__region',
  1626. lookup_expr='in',
  1627. to_field_name='slug',
  1628. label=_('Region (slug)'),
  1629. )
  1630. site_group_id = TreeNodeMultipleChoiceFilter(
  1631. queryset=SiteGroup.objects.all(),
  1632. field_name='site__group',
  1633. lookup_expr='in',
  1634. label=_('Site group (ID)'),
  1635. )
  1636. site_group = TreeNodeMultipleChoiceFilter(
  1637. queryset=SiteGroup.objects.all(),
  1638. field_name='site__group',
  1639. lookup_expr='in',
  1640. to_field_name='slug',
  1641. label=_('Site group (slug)'),
  1642. )
  1643. site_id = django_filters.ModelMultipleChoiceFilter(
  1644. queryset=Site.objects.all(),
  1645. label=_('Site (ID)'),
  1646. )
  1647. site = django_filters.ModelMultipleChoiceFilter(
  1648. field_name='site__slug',
  1649. queryset=Site.objects.all(),
  1650. to_field_name='slug',
  1651. label=_('Site name (slug)'),
  1652. )
  1653. location_id = TreeNodeMultipleChoiceFilter(
  1654. queryset=Location.objects.all(),
  1655. field_name='location',
  1656. lookup_expr='in',
  1657. label=_('Location (ID)'),
  1658. )
  1659. class Meta:
  1660. model = PowerPanel
  1661. fields = ['id', 'name']
  1662. def search(self, queryset, name, value):
  1663. if not value.strip():
  1664. return queryset
  1665. qs_filter = (
  1666. Q(name__icontains=value)
  1667. )
  1668. return queryset.filter(qs_filter)
  1669. class PowerFeedFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
  1670. region_id = TreeNodeMultipleChoiceFilter(
  1671. queryset=Region.objects.all(),
  1672. field_name='power_panel__site__region',
  1673. lookup_expr='in',
  1674. label=_('Region (ID)'),
  1675. )
  1676. region = TreeNodeMultipleChoiceFilter(
  1677. queryset=Region.objects.all(),
  1678. field_name='power_panel__site__region',
  1679. lookup_expr='in',
  1680. to_field_name='slug',
  1681. label=_('Region (slug)'),
  1682. )
  1683. site_group_id = TreeNodeMultipleChoiceFilter(
  1684. queryset=SiteGroup.objects.all(),
  1685. field_name='power_panel__site__group',
  1686. lookup_expr='in',
  1687. label=_('Site group (ID)'),
  1688. )
  1689. site_group = TreeNodeMultipleChoiceFilter(
  1690. queryset=SiteGroup.objects.all(),
  1691. field_name='power_panel__site__group',
  1692. lookup_expr='in',
  1693. to_field_name='slug',
  1694. label=_('Site group (slug)'),
  1695. )
  1696. site_id = django_filters.ModelMultipleChoiceFilter(
  1697. field_name='power_panel__site',
  1698. queryset=Site.objects.all(),
  1699. label=_('Site (ID)'),
  1700. )
  1701. site = django_filters.ModelMultipleChoiceFilter(
  1702. field_name='power_panel__site__slug',
  1703. queryset=Site.objects.all(),
  1704. to_field_name='slug',
  1705. label=_('Site name (slug)'),
  1706. )
  1707. power_panel_id = django_filters.ModelMultipleChoiceFilter(
  1708. queryset=PowerPanel.objects.all(),
  1709. label=_('Power panel (ID)'),
  1710. )
  1711. rack_id = django_filters.ModelMultipleChoiceFilter(
  1712. field_name='rack',
  1713. queryset=Rack.objects.all(),
  1714. label=_('Rack (ID)'),
  1715. )
  1716. status = django_filters.MultipleChoiceFilter(
  1717. choices=PowerFeedStatusChoices,
  1718. null_value=None
  1719. )
  1720. class Meta:
  1721. model = PowerFeed
  1722. fields = [
  1723. 'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 'cable_end',
  1724. ]
  1725. def search(self, queryset, name, value):
  1726. if not value.strip():
  1727. return queryset
  1728. qs_filter = (
  1729. Q(name__icontains=value) |
  1730. Q(power_panel__name__icontains=value) |
  1731. Q(comments__icontains=value)
  1732. )
  1733. return queryset.filter(qs_filter)
  1734. #
  1735. # Connection filter sets
  1736. #
  1737. class ConnectionFilterSet(BaseFilterSet):
  1738. q = django_filters.CharFilter(
  1739. method='search',
  1740. label=_('Search'),
  1741. )
  1742. site_id = MultiValueNumberFilter(
  1743. method='filter_connections',
  1744. field_name='device__site_id'
  1745. )
  1746. site = MultiValueCharFilter(
  1747. method='filter_connections',
  1748. field_name='device__site__slug'
  1749. )
  1750. device_id = MultiValueNumberFilter(
  1751. method='filter_connections',
  1752. field_name='device_id'
  1753. )
  1754. device = MultiValueCharFilter(
  1755. method='filter_connections',
  1756. field_name='device__name'
  1757. )
  1758. def filter_connections(self, queryset, name, value):
  1759. if not value:
  1760. return queryset
  1761. return queryset.filter(**{f'{name}__in': value})
  1762. def search(self, queryset, name, value):
  1763. if not value.strip():
  1764. return queryset
  1765. qs_filter = (
  1766. Q(device__name__icontains=value) |
  1767. Q(cable__label__icontains=value)
  1768. )
  1769. return queryset.filter(qs_filter)
  1770. class ConsoleConnectionFilterSet(ConnectionFilterSet):
  1771. class Meta:
  1772. model = ConsolePort
  1773. fields = ['name']
  1774. class PowerConnectionFilterSet(ConnectionFilterSet):
  1775. class Meta:
  1776. model = PowerPort
  1777. fields = ['name']
  1778. class InterfaceConnectionFilterSet(ConnectionFilterSet):
  1779. class Meta:
  1780. model = Interface
  1781. fields = []