filtersets.py 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023
  1. import django_filters
  2. from django.contrib.auth import get_user_model
  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=get_user_model().objects.all(),
  374. label=_('User (ID)'),
  375. )
  376. user = django_filters.ModelMultipleChoiceFilter(
  377. field_name='user__username',
  378. queryset=get_user_model().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. rf_role = django_filters.MultipleChoiceFilter(
  626. choices=WirelessRoleChoices
  627. )
  628. class Meta:
  629. model = InterfaceTemplate
  630. fields = ['id', 'name', 'type', 'enabled', 'mgmt_only']
  631. class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  632. type = django_filters.MultipleChoiceFilter(
  633. choices=PortTypeChoices,
  634. null_value=None
  635. )
  636. class Meta:
  637. model = FrontPortTemplate
  638. fields = ['id', 'name', 'type', 'color']
  639. class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  640. type = django_filters.MultipleChoiceFilter(
  641. choices=PortTypeChoices,
  642. null_value=None
  643. )
  644. class Meta:
  645. model = RearPortTemplate
  646. fields = ['id', 'name', 'type', 'color', 'positions']
  647. class ModuleBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  648. class Meta:
  649. model = ModuleBayTemplate
  650. fields = ['id', 'name']
  651. class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  652. class Meta:
  653. model = DeviceBayTemplate
  654. fields = ['id', 'name']
  655. class InventoryItemTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  656. parent_id = django_filters.ModelMultipleChoiceFilter(
  657. queryset=InventoryItemTemplate.objects.all(),
  658. label=_('Parent inventory item (ID)'),
  659. )
  660. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  661. queryset=Manufacturer.objects.all(),
  662. label=_('Manufacturer (ID)'),
  663. )
  664. manufacturer = django_filters.ModelMultipleChoiceFilter(
  665. field_name='manufacturer__slug',
  666. queryset=Manufacturer.objects.all(),
  667. to_field_name='slug',
  668. label=_('Manufacturer (slug)'),
  669. )
  670. role_id = django_filters.ModelMultipleChoiceFilter(
  671. queryset=InventoryItemRole.objects.all(),
  672. label=_('Role (ID)'),
  673. )
  674. role = django_filters.ModelMultipleChoiceFilter(
  675. field_name='role__slug',
  676. queryset=InventoryItemRole.objects.all(),
  677. to_field_name='slug',
  678. label=_('Role (slug)'),
  679. )
  680. component_type = ContentTypeFilter()
  681. component_id = MultiValueNumberFilter()
  682. class Meta:
  683. model = InventoryItemTemplate
  684. fields = ['id', 'name', 'label', 'part_id']
  685. def search(self, queryset, name, value):
  686. if not value.strip():
  687. return queryset
  688. qs_filter = (
  689. Q(name__icontains=value) |
  690. Q(part_id__icontains=value) |
  691. Q(description__icontains=value)
  692. )
  693. return queryset.filter(qs_filter)
  694. class DeviceRoleFilterSet(OrganizationalModelFilterSet):
  695. config_template_id = django_filters.ModelMultipleChoiceFilter(
  696. queryset=ConfigTemplate.objects.all(),
  697. label=_('Config template (ID)'),
  698. )
  699. class Meta:
  700. model = DeviceRole
  701. fields = ['id', 'name', 'slug', 'color', 'vm_role', 'description']
  702. class PlatformFilterSet(OrganizationalModelFilterSet):
  703. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  704. field_name='manufacturer',
  705. queryset=Manufacturer.objects.all(),
  706. label=_('Manufacturer (ID)'),
  707. )
  708. manufacturer = django_filters.ModelMultipleChoiceFilter(
  709. field_name='manufacturer__slug',
  710. queryset=Manufacturer.objects.all(),
  711. to_field_name='slug',
  712. label=_('Manufacturer (slug)'),
  713. )
  714. config_template_id = django_filters.ModelMultipleChoiceFilter(
  715. queryset=ConfigTemplate.objects.all(),
  716. label=_('Config template (ID)'),
  717. )
  718. class Meta:
  719. model = Platform
  720. fields = ['id', 'name', 'slug', 'description']
  721. class DeviceFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet, LocalConfigContextFilterSet):
  722. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  723. field_name='device_type__manufacturer',
  724. queryset=Manufacturer.objects.all(),
  725. label=_('Manufacturer (ID)'),
  726. )
  727. manufacturer = django_filters.ModelMultipleChoiceFilter(
  728. field_name='device_type__manufacturer__slug',
  729. queryset=Manufacturer.objects.all(),
  730. to_field_name='slug',
  731. label=_('Manufacturer (slug)'),
  732. )
  733. device_type = django_filters.ModelMultipleChoiceFilter(
  734. field_name='device_type__slug',
  735. queryset=DeviceType.objects.all(),
  736. to_field_name='slug',
  737. label=_('Device type (slug)'),
  738. )
  739. device_type_id = django_filters.ModelMultipleChoiceFilter(
  740. queryset=DeviceType.objects.all(),
  741. label=_('Device type (ID)'),
  742. )
  743. role_id = django_filters.ModelMultipleChoiceFilter(
  744. field_name='role_id',
  745. queryset=DeviceRole.objects.all(),
  746. label=_('Role (ID)'),
  747. )
  748. role = django_filters.ModelMultipleChoiceFilter(
  749. field_name='role__slug',
  750. queryset=DeviceRole.objects.all(),
  751. to_field_name='slug',
  752. label=_('Role (slug)'),
  753. )
  754. parent_device_id = django_filters.ModelMultipleChoiceFilter(
  755. field_name='parent_bay__device',
  756. queryset=Device.objects.all(),
  757. label=_('Parent Device (ID)'),
  758. )
  759. platform_id = django_filters.ModelMultipleChoiceFilter(
  760. queryset=Platform.objects.all(),
  761. label=_('Platform (ID)'),
  762. )
  763. platform = django_filters.ModelMultipleChoiceFilter(
  764. field_name='platform__slug',
  765. queryset=Platform.objects.all(),
  766. to_field_name='slug',
  767. label=_('Platform (slug)'),
  768. )
  769. region_id = TreeNodeMultipleChoiceFilter(
  770. queryset=Region.objects.all(),
  771. field_name='site__region',
  772. lookup_expr='in',
  773. label=_('Region (ID)'),
  774. )
  775. region = TreeNodeMultipleChoiceFilter(
  776. queryset=Region.objects.all(),
  777. field_name='site__region',
  778. lookup_expr='in',
  779. to_field_name='slug',
  780. label=_('Region (slug)'),
  781. )
  782. site_group_id = TreeNodeMultipleChoiceFilter(
  783. queryset=SiteGroup.objects.all(),
  784. field_name='site__group',
  785. lookup_expr='in',
  786. label=_('Site group (ID)'),
  787. )
  788. site_group = TreeNodeMultipleChoiceFilter(
  789. queryset=SiteGroup.objects.all(),
  790. field_name='site__group',
  791. lookup_expr='in',
  792. to_field_name='slug',
  793. label=_('Site group (slug)'),
  794. )
  795. site_id = django_filters.ModelMultipleChoiceFilter(
  796. queryset=Site.objects.all(),
  797. label=_('Site (ID)'),
  798. )
  799. site = django_filters.ModelMultipleChoiceFilter(
  800. field_name='site__slug',
  801. queryset=Site.objects.all(),
  802. to_field_name='slug',
  803. label=_('Site name (slug)'),
  804. )
  805. location_id = TreeNodeMultipleChoiceFilter(
  806. queryset=Location.objects.all(),
  807. field_name='location',
  808. lookup_expr='in',
  809. label=_('Location (ID)'),
  810. )
  811. rack_id = django_filters.ModelMultipleChoiceFilter(
  812. field_name='rack',
  813. queryset=Rack.objects.all(),
  814. label=_('Rack (ID)'),
  815. )
  816. cluster_id = django_filters.ModelMultipleChoiceFilter(
  817. queryset=Cluster.objects.all(),
  818. label=_('VM cluster (ID)'),
  819. )
  820. model = django_filters.ModelMultipleChoiceFilter(
  821. field_name='device_type__slug',
  822. queryset=DeviceType.objects.all(),
  823. to_field_name='slug',
  824. label=_('Device model (slug)'),
  825. )
  826. name = MultiValueCharFilter(
  827. lookup_expr='iexact'
  828. )
  829. status = django_filters.MultipleChoiceFilter(
  830. choices=DeviceStatusChoices,
  831. null_value=None
  832. )
  833. is_full_depth = django_filters.BooleanFilter(
  834. field_name='device_type__is_full_depth',
  835. label=_('Is full depth'),
  836. )
  837. mac_address = MultiValueMACAddressFilter(
  838. field_name='interfaces__mac_address',
  839. label=_('MAC address'),
  840. )
  841. serial = MultiValueCharFilter(
  842. lookup_expr='iexact'
  843. )
  844. has_primary_ip = django_filters.BooleanFilter(
  845. method='_has_primary_ip',
  846. label=_('Has a primary IP'),
  847. )
  848. has_oob_ip = django_filters.BooleanFilter(
  849. method='_has_oob_ip',
  850. label=_('Has an out-of-band IP'),
  851. )
  852. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  853. field_name='virtual_chassis',
  854. queryset=VirtualChassis.objects.all(),
  855. label=_('Virtual chassis (ID)'),
  856. )
  857. virtual_chassis_member = django_filters.BooleanFilter(
  858. method='_virtual_chassis_member',
  859. label=_('Is a virtual chassis member')
  860. )
  861. config_template_id = django_filters.ModelMultipleChoiceFilter(
  862. queryset=ConfigTemplate.objects.all(),
  863. label=_('Config template (ID)'),
  864. )
  865. console_ports = django_filters.BooleanFilter(
  866. method='_console_ports',
  867. label=_('Has console ports'),
  868. )
  869. console_server_ports = django_filters.BooleanFilter(
  870. method='_console_server_ports',
  871. label=_('Has console server ports'),
  872. )
  873. power_ports = django_filters.BooleanFilter(
  874. method='_power_ports',
  875. label=_('Has power ports'),
  876. )
  877. power_outlets = django_filters.BooleanFilter(
  878. method='_power_outlets',
  879. label=_('Has power outlets'),
  880. )
  881. interfaces = django_filters.BooleanFilter(
  882. method='_interfaces',
  883. label=_('Has interfaces'),
  884. )
  885. pass_through_ports = django_filters.BooleanFilter(
  886. method='_pass_through_ports',
  887. label=_('Has pass-through ports'),
  888. )
  889. module_bays = django_filters.BooleanFilter(
  890. method='_module_bays',
  891. label=_('Has module bays'),
  892. )
  893. device_bays = django_filters.BooleanFilter(
  894. method='_device_bays',
  895. label=_('Has device bays'),
  896. )
  897. primary_ip4_id = django_filters.ModelMultipleChoiceFilter(
  898. field_name='primary_ip4',
  899. queryset=IPAddress.objects.all(),
  900. label=_('Primary IPv4 (ID)'),
  901. )
  902. primary_ip6_id = django_filters.ModelMultipleChoiceFilter(
  903. field_name='primary_ip6',
  904. queryset=IPAddress.objects.all(),
  905. label=_('Primary IPv6 (ID)'),
  906. )
  907. oob_ip_id = django_filters.ModelMultipleChoiceFilter(
  908. field_name='oob_ip',
  909. queryset=IPAddress.objects.all(),
  910. label=_('OOB IP (ID)'),
  911. )
  912. class Meta:
  913. model = Device
  914. fields = ['id', 'asset_tag', 'face', 'position', 'latitude', 'longitude', 'airflow', 'vc_position', 'vc_priority']
  915. def search(self, queryset, name, value):
  916. if not value.strip():
  917. return queryset
  918. return queryset.filter(
  919. Q(name__icontains=value) |
  920. Q(serial__icontains=value.strip()) |
  921. Q(inventoryitems__serial__icontains=value.strip()) |
  922. Q(asset_tag__icontains=value.strip()) |
  923. Q(comments__icontains=value) |
  924. Q(primary_ip4__address__startswith=value) |
  925. Q(primary_ip6__address__startswith=value)
  926. ).distinct()
  927. def _has_primary_ip(self, queryset, name, value):
  928. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  929. if value:
  930. return queryset.filter(params)
  931. return queryset.exclude(params)
  932. def _has_oob_ip(self, queryset, name, value):
  933. params = Q(oob_ip__isnull=False)
  934. if value:
  935. return queryset.filter(params)
  936. return queryset.exclude(params)
  937. def _virtual_chassis_member(self, queryset, name, value):
  938. return queryset.exclude(virtual_chassis__isnull=value)
  939. def _console_ports(self, queryset, name, value):
  940. return queryset.exclude(consoleports__isnull=value)
  941. def _console_server_ports(self, queryset, name, value):
  942. return queryset.exclude(consoleserverports__isnull=value)
  943. def _power_ports(self, queryset, name, value):
  944. return queryset.exclude(powerports__isnull=value)
  945. def _power_outlets(self, queryset, name, value):
  946. return queryset.exclude(poweroutlets__isnull=value)
  947. def _interfaces(self, queryset, name, value):
  948. return queryset.exclude(interfaces__isnull=value)
  949. def _pass_through_ports(self, queryset, name, value):
  950. return queryset.exclude(
  951. frontports__isnull=value,
  952. rearports__isnull=value
  953. )
  954. def _module_bays(self, queryset, name, value):
  955. return queryset.exclude(modulebays__isnull=value)
  956. def _device_bays(self, queryset, name, value):
  957. return queryset.exclude(devicebays__isnull=value)
  958. class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
  959. device_id = django_filters.ModelMultipleChoiceFilter(
  960. field_name='device',
  961. queryset=Device.objects.all(),
  962. label='VDC (ID)',
  963. )
  964. device = django_filters.ModelMultipleChoiceFilter(
  965. field_name='device',
  966. queryset=Device.objects.all(),
  967. label='Device model',
  968. )
  969. status = django_filters.MultipleChoiceFilter(
  970. choices=VirtualDeviceContextStatusChoices
  971. )
  972. has_primary_ip = django_filters.BooleanFilter(
  973. method='_has_primary_ip',
  974. label='Has a primary IP',
  975. )
  976. class Meta:
  977. model = VirtualDeviceContext
  978. fields = ['id', 'device', 'name']
  979. def search(self, queryset, name, value):
  980. if not value.strip():
  981. return queryset
  982. qs_filter = Q(name__icontains=value)
  983. try:
  984. qs_filter |= Q(identifier=int(value))
  985. except ValueError:
  986. pass
  987. return queryset.filter(qs_filter).distinct()
  988. def _has_primary_ip(self, queryset, name, value):
  989. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  990. if value:
  991. return queryset.filter(params)
  992. return queryset.exclude(params)
  993. class ModuleFilterSet(NetBoxModelFilterSet):
  994. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  995. field_name='module_type__manufacturer',
  996. queryset=Manufacturer.objects.all(),
  997. label=_('Manufacturer (ID)'),
  998. )
  999. manufacturer = django_filters.ModelMultipleChoiceFilter(
  1000. field_name='module_type__manufacturer__slug',
  1001. queryset=Manufacturer.objects.all(),
  1002. to_field_name='slug',
  1003. label=_('Manufacturer (slug)'),
  1004. )
  1005. module_type_id = django_filters.ModelMultipleChoiceFilter(
  1006. field_name='module_type',
  1007. queryset=ModuleType.objects.all(),
  1008. label=_('Module type (ID)'),
  1009. )
  1010. module_type = django_filters.ModelMultipleChoiceFilter(
  1011. field_name='module_type__model',
  1012. queryset=ModuleType.objects.all(),
  1013. to_field_name='model',
  1014. label=_('Module type (model)'),
  1015. )
  1016. module_bay_id = django_filters.ModelMultipleChoiceFilter(
  1017. field_name='module_bay',
  1018. queryset=ModuleBay.objects.all(),
  1019. to_field_name='id',
  1020. label=_('Module Bay (ID)')
  1021. )
  1022. device_id = django_filters.ModelMultipleChoiceFilter(
  1023. queryset=Device.objects.all(),
  1024. label=_('Device (ID)'),
  1025. )
  1026. status = django_filters.MultipleChoiceFilter(
  1027. choices=ModuleStatusChoices,
  1028. null_value=None
  1029. )
  1030. serial = MultiValueCharFilter(
  1031. lookup_expr='iexact'
  1032. )
  1033. class Meta:
  1034. model = Module
  1035. fields = ['id', 'status', 'asset_tag']
  1036. def search(self, queryset, name, value):
  1037. if not value.strip():
  1038. return queryset
  1039. return queryset.filter(
  1040. Q(device__name__icontains=value.strip()) |
  1041. Q(serial__icontains=value.strip()) |
  1042. Q(asset_tag__icontains=value.strip()) |
  1043. Q(comments__icontains=value)
  1044. ).distinct()
  1045. class DeviceComponentFilterSet(django_filters.FilterSet):
  1046. q = django_filters.CharFilter(
  1047. method='search',
  1048. label=_('Search'),
  1049. )
  1050. region_id = TreeNodeMultipleChoiceFilter(
  1051. queryset=Region.objects.all(),
  1052. field_name='device__site__region',
  1053. lookup_expr='in',
  1054. label=_('Region (ID)'),
  1055. )
  1056. region = TreeNodeMultipleChoiceFilter(
  1057. queryset=Region.objects.all(),
  1058. field_name='device__site__region',
  1059. lookup_expr='in',
  1060. to_field_name='slug',
  1061. label=_('Region (slug)'),
  1062. )
  1063. site_group_id = TreeNodeMultipleChoiceFilter(
  1064. queryset=SiteGroup.objects.all(),
  1065. field_name='device__site__group',
  1066. lookup_expr='in',
  1067. label=_('Site group (ID)'),
  1068. )
  1069. site_group = TreeNodeMultipleChoiceFilter(
  1070. queryset=SiteGroup.objects.all(),
  1071. field_name='device__site__group',
  1072. lookup_expr='in',
  1073. to_field_name='slug',
  1074. label=_('Site group (slug)'),
  1075. )
  1076. site_id = django_filters.ModelMultipleChoiceFilter(
  1077. field_name='device__site',
  1078. queryset=Site.objects.all(),
  1079. label=_('Site (ID)'),
  1080. )
  1081. site = django_filters.ModelMultipleChoiceFilter(
  1082. field_name='device__site__slug',
  1083. queryset=Site.objects.all(),
  1084. to_field_name='slug',
  1085. label=_('Site name (slug)'),
  1086. )
  1087. location_id = django_filters.ModelMultipleChoiceFilter(
  1088. field_name='device__location',
  1089. queryset=Location.objects.all(),
  1090. label=_('Location (ID)'),
  1091. )
  1092. location = django_filters.ModelMultipleChoiceFilter(
  1093. field_name='device__location__slug',
  1094. queryset=Location.objects.all(),
  1095. to_field_name='slug',
  1096. label=_('Location (slug)'),
  1097. )
  1098. rack_id = django_filters.ModelMultipleChoiceFilter(
  1099. field_name='device__rack',
  1100. queryset=Rack.objects.all(),
  1101. label=_('Rack (ID)'),
  1102. )
  1103. rack = django_filters.ModelMultipleChoiceFilter(
  1104. field_name='device__rack__name',
  1105. queryset=Rack.objects.all(),
  1106. to_field_name='name',
  1107. label=_('Rack (name)'),
  1108. )
  1109. device_id = django_filters.ModelMultipleChoiceFilter(
  1110. queryset=Device.objects.all(),
  1111. label=_('Device (ID)'),
  1112. )
  1113. device = django_filters.ModelMultipleChoiceFilter(
  1114. field_name='device__name',
  1115. queryset=Device.objects.all(),
  1116. to_field_name='name',
  1117. label=_('Device (name)'),
  1118. )
  1119. device_type_id = django_filters.ModelMultipleChoiceFilter(
  1120. field_name='device__device_type',
  1121. queryset=DeviceType.objects.all(),
  1122. label=_('Device type (ID)'),
  1123. )
  1124. device_type = django_filters.ModelMultipleChoiceFilter(
  1125. field_name='device__device_type__model',
  1126. queryset=DeviceType.objects.all(),
  1127. to_field_name='model',
  1128. label=_('Device type (model)'),
  1129. )
  1130. role_id = django_filters.ModelMultipleChoiceFilter(
  1131. field_name='device__role',
  1132. queryset=DeviceRole.objects.all(),
  1133. label=_('Device role (ID)'),
  1134. )
  1135. role = django_filters.ModelMultipleChoiceFilter(
  1136. field_name='device__role__slug',
  1137. queryset=DeviceRole.objects.all(),
  1138. to_field_name='slug',
  1139. label=_('Device role (slug)'),
  1140. )
  1141. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  1142. field_name='device__virtual_chassis',
  1143. queryset=VirtualChassis.objects.all(),
  1144. label=_('Virtual Chassis (ID)')
  1145. )
  1146. virtual_chassis = django_filters.ModelMultipleChoiceFilter(
  1147. field_name='device__virtual_chassis__name',
  1148. queryset=VirtualChassis.objects.all(),
  1149. to_field_name='name',
  1150. label=_('Virtual Chassis'),
  1151. )
  1152. # TODO: Remove in v4.0
  1153. device_role_id = django_filters.ModelMultipleChoiceFilter(
  1154. field_name='device__role',
  1155. queryset=DeviceRole.objects.all(),
  1156. label=_('Device role (ID)'),
  1157. )
  1158. device_role = django_filters.ModelMultipleChoiceFilter(
  1159. field_name='device__role__slug',
  1160. queryset=DeviceRole.objects.all(),
  1161. to_field_name='slug',
  1162. label=_('Device role (slug)'),
  1163. )
  1164. def search(self, queryset, name, value):
  1165. if not value.strip():
  1166. return queryset
  1167. return queryset.filter(
  1168. Q(name__icontains=value) |
  1169. Q(label__icontains=value) |
  1170. Q(description__icontains=value)
  1171. )
  1172. class ModularDeviceComponentFilterSet(DeviceComponentFilterSet):
  1173. """
  1174. Extends DeviceComponentFilterSet to add a module_id filter for components
  1175. which can be associated with a particular module within a device.
  1176. """
  1177. module_id = django_filters.ModelMultipleChoiceFilter(
  1178. queryset=Module.objects.all(),
  1179. label=_('Module (ID)'),
  1180. )
  1181. class CabledObjectFilterSet(django_filters.FilterSet):
  1182. cabled = django_filters.BooleanFilter(
  1183. field_name='cable',
  1184. lookup_expr='isnull',
  1185. exclude=True
  1186. )
  1187. occupied = django_filters.BooleanFilter(
  1188. method='filter_occupied'
  1189. )
  1190. def filter_occupied(self, queryset, name, value):
  1191. if value:
  1192. return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True))
  1193. else:
  1194. return queryset.filter(cable__isnull=True, mark_connected=False)
  1195. class PathEndpointFilterSet(django_filters.FilterSet):
  1196. connected = django_filters.BooleanFilter(
  1197. method='filter_connected'
  1198. )
  1199. def filter_connected(self, queryset, name, value):
  1200. if value:
  1201. return queryset.filter(_path__is_active=True)
  1202. else:
  1203. return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
  1204. class ConsolePortFilterSet(
  1205. ModularDeviceComponentFilterSet,
  1206. NetBoxModelFilterSet,
  1207. CabledObjectFilterSet,
  1208. PathEndpointFilterSet
  1209. ):
  1210. type = django_filters.MultipleChoiceFilter(
  1211. choices=ConsolePortTypeChoices,
  1212. null_value=None
  1213. )
  1214. class Meta:
  1215. model = ConsolePort
  1216. fields = ['id', 'name', 'label', 'description', 'cable_end']
  1217. class ConsoleServerPortFilterSet(
  1218. ModularDeviceComponentFilterSet,
  1219. NetBoxModelFilterSet,
  1220. CabledObjectFilterSet,
  1221. PathEndpointFilterSet
  1222. ):
  1223. type = django_filters.MultipleChoiceFilter(
  1224. choices=ConsolePortTypeChoices,
  1225. null_value=None
  1226. )
  1227. class Meta:
  1228. model = ConsoleServerPort
  1229. fields = ['id', 'name', 'label', 'description', 'cable_end']
  1230. class PowerPortFilterSet(
  1231. ModularDeviceComponentFilterSet,
  1232. NetBoxModelFilterSet,
  1233. CabledObjectFilterSet,
  1234. PathEndpointFilterSet
  1235. ):
  1236. type = django_filters.MultipleChoiceFilter(
  1237. choices=PowerPortTypeChoices,
  1238. null_value=None
  1239. )
  1240. class Meta:
  1241. model = PowerPort
  1242. fields = ['id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'cable_end']
  1243. class PowerOutletFilterSet(
  1244. ModularDeviceComponentFilterSet,
  1245. NetBoxModelFilterSet,
  1246. CabledObjectFilterSet,
  1247. PathEndpointFilterSet
  1248. ):
  1249. type = django_filters.MultipleChoiceFilter(
  1250. choices=PowerOutletTypeChoices,
  1251. null_value=None
  1252. )
  1253. feed_leg = django_filters.MultipleChoiceFilter(
  1254. choices=PowerOutletFeedLegChoices,
  1255. null_value=None
  1256. )
  1257. class Meta:
  1258. model = PowerOutlet
  1259. fields = ['id', 'name', 'label', 'feed_leg', 'description', 'cable_end']
  1260. class CommonInterfaceFilterSet(django_filters.FilterSet):
  1261. vlan_id = django_filters.CharFilter(
  1262. method='filter_vlan_id',
  1263. label=_('Assigned VLAN')
  1264. )
  1265. vlan = django_filters.CharFilter(
  1266. method='filter_vlan',
  1267. label=_('Assigned VID')
  1268. )
  1269. vrf_id = django_filters.ModelMultipleChoiceFilter(
  1270. field_name='vrf',
  1271. queryset=VRF.objects.all(),
  1272. label=_('VRF'),
  1273. )
  1274. vrf = django_filters.ModelMultipleChoiceFilter(
  1275. field_name='vrf__rd',
  1276. queryset=VRF.objects.all(),
  1277. to_field_name='rd',
  1278. label=_('VRF (RD)'),
  1279. )
  1280. l2vpn_id = django_filters.ModelMultipleChoiceFilter(
  1281. field_name='l2vpn_terminations__l2vpn',
  1282. queryset=L2VPN.objects.all(),
  1283. label=_('L2VPN (ID)'),
  1284. )
  1285. l2vpn = django_filters.ModelMultipleChoiceFilter(
  1286. field_name='l2vpn_terminations__l2vpn__identifier',
  1287. queryset=L2VPN.objects.all(),
  1288. to_field_name='identifier',
  1289. label=_('L2VPN'),
  1290. )
  1291. def filter_vlan_id(self, queryset, name, value):
  1292. value = value.strip()
  1293. if not value:
  1294. return queryset
  1295. return queryset.filter(
  1296. Q(untagged_vlan_id=value) |
  1297. Q(tagged_vlans=value)
  1298. )
  1299. def filter_vlan(self, queryset, name, value):
  1300. value = value.strip()
  1301. if not value:
  1302. return queryset
  1303. return queryset.filter(
  1304. Q(untagged_vlan_id__vid=value) |
  1305. Q(tagged_vlans__vid=value)
  1306. )
  1307. class InterfaceFilterSet(
  1308. ModularDeviceComponentFilterSet,
  1309. NetBoxModelFilterSet,
  1310. CabledObjectFilterSet,
  1311. PathEndpointFilterSet,
  1312. CommonInterfaceFilterSet
  1313. ):
  1314. # Override device and device_id filters from DeviceComponentFilterSet to match against any peer virtual chassis
  1315. # members
  1316. device = MultiValueCharFilter(
  1317. method='filter_device',
  1318. field_name='name',
  1319. label=_('Device'),
  1320. )
  1321. device_id = MultiValueNumberFilter(
  1322. method='filter_device_id',
  1323. field_name='pk',
  1324. label=_('Device (ID)'),
  1325. )
  1326. kind = django_filters.CharFilter(
  1327. method='filter_kind',
  1328. label=_('Kind of interface'),
  1329. )
  1330. parent_id = django_filters.ModelMultipleChoiceFilter(
  1331. field_name='parent',
  1332. queryset=Interface.objects.all(),
  1333. label=_('Parent interface (ID)'),
  1334. )
  1335. bridge_id = django_filters.ModelMultipleChoiceFilter(
  1336. field_name='bridge',
  1337. queryset=Interface.objects.all(),
  1338. label=_('Bridged interface (ID)'),
  1339. )
  1340. lag_id = django_filters.ModelMultipleChoiceFilter(
  1341. field_name='lag',
  1342. queryset=Interface.objects.all(),
  1343. label=_('LAG interface (ID)'),
  1344. )
  1345. speed = MultiValueNumberFilter()
  1346. duplex = django_filters.MultipleChoiceFilter(
  1347. choices=InterfaceDuplexChoices
  1348. )
  1349. mac_address = MultiValueMACAddressFilter()
  1350. wwn = MultiValueWWNFilter()
  1351. poe_mode = django_filters.MultipleChoiceFilter(
  1352. choices=InterfacePoEModeChoices
  1353. )
  1354. poe_type = django_filters.MultipleChoiceFilter(
  1355. choices=InterfacePoETypeChoices
  1356. )
  1357. type = django_filters.MultipleChoiceFilter(
  1358. choices=InterfaceTypeChoices,
  1359. null_value=None
  1360. )
  1361. rf_role = django_filters.MultipleChoiceFilter(
  1362. choices=WirelessRoleChoices
  1363. )
  1364. rf_channel = django_filters.MultipleChoiceFilter(
  1365. choices=WirelessChannelChoices
  1366. )
  1367. vdc_id = django_filters.ModelMultipleChoiceFilter(
  1368. field_name='vdcs',
  1369. queryset=VirtualDeviceContext.objects.all(),
  1370. label='Virtual Device Context',
  1371. )
  1372. vdc_identifier = django_filters.ModelMultipleChoiceFilter(
  1373. field_name='vdcs__identifier',
  1374. queryset=VirtualDeviceContext.objects.all(),
  1375. to_field_name='identifier',
  1376. label='Virtual Device Context (Identifier)',
  1377. )
  1378. vdc = django_filters.ModelMultipleChoiceFilter(
  1379. field_name='vdcs__name',
  1380. queryset=VirtualDeviceContext.objects.all(),
  1381. to_field_name='name',
  1382. label='Virtual Device Context',
  1383. )
  1384. class Meta:
  1385. model = Interface
  1386. fields = [
  1387. 'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 'poe_type', 'mode', 'rf_role',
  1388. 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description', 'cable_end',
  1389. ]
  1390. def filter_device(self, queryset, name, value):
  1391. try:
  1392. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  1393. vc_interface_ids = []
  1394. for device in devices:
  1395. vc_interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  1396. return queryset.filter(pk__in=vc_interface_ids)
  1397. except Device.DoesNotExist:
  1398. return queryset.none()
  1399. def filter_device_id(self, queryset, name, id_list):
  1400. # Include interfaces belonging to peer virtual chassis members
  1401. vc_interface_ids = []
  1402. try:
  1403. devices = Device.objects.filter(pk__in=id_list)
  1404. for device in devices:
  1405. vc_interface_ids += device.vc_interfaces(if_master=False).values_list('id', flat=True)
  1406. return queryset.filter(pk__in=vc_interface_ids)
  1407. except Device.DoesNotExist:
  1408. return queryset.none()
  1409. def filter_kind(self, queryset, name, value):
  1410. value = value.strip().lower()
  1411. return {
  1412. 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES),
  1413. 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES),
  1414. 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES),
  1415. }.get(value, queryset.none())
  1416. class FrontPortFilterSet(
  1417. ModularDeviceComponentFilterSet,
  1418. NetBoxModelFilterSet,
  1419. CabledObjectFilterSet
  1420. ):
  1421. type = django_filters.MultipleChoiceFilter(
  1422. choices=PortTypeChoices,
  1423. null_value=None
  1424. )
  1425. class Meta:
  1426. model = FrontPort
  1427. fields = ['id', 'name', 'label', 'type', 'color', 'description', 'cable_end']
  1428. class RearPortFilterSet(
  1429. ModularDeviceComponentFilterSet,
  1430. NetBoxModelFilterSet,
  1431. CabledObjectFilterSet
  1432. ):
  1433. type = django_filters.MultipleChoiceFilter(
  1434. choices=PortTypeChoices,
  1435. null_value=None
  1436. )
  1437. class Meta:
  1438. model = RearPort
  1439. fields = ['id', 'name', 'label', 'type', 'color', 'positions', 'description', 'cable_end']
  1440. class ModuleBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1441. class Meta:
  1442. model = ModuleBay
  1443. fields = ['id', 'name', 'label', 'description']
  1444. class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1445. class Meta:
  1446. model = DeviceBay
  1447. fields = ['id', 'name', 'label', 'description']
  1448. class InventoryItemFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1449. parent_id = django_filters.ModelMultipleChoiceFilter(
  1450. queryset=InventoryItem.objects.all(),
  1451. label=_('Parent inventory item (ID)'),
  1452. )
  1453. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  1454. queryset=Manufacturer.objects.all(),
  1455. label=_('Manufacturer (ID)'),
  1456. )
  1457. manufacturer = django_filters.ModelMultipleChoiceFilter(
  1458. field_name='manufacturer__slug',
  1459. queryset=Manufacturer.objects.all(),
  1460. to_field_name='slug',
  1461. label=_('Manufacturer (slug)'),
  1462. )
  1463. role_id = django_filters.ModelMultipleChoiceFilter(
  1464. queryset=InventoryItemRole.objects.all(),
  1465. label=_('Role (ID)'),
  1466. )
  1467. role = django_filters.ModelMultipleChoiceFilter(
  1468. field_name='role__slug',
  1469. queryset=InventoryItemRole.objects.all(),
  1470. to_field_name='slug',
  1471. label=_('Role (slug)'),
  1472. )
  1473. component_type = ContentTypeFilter()
  1474. component_id = MultiValueNumberFilter()
  1475. serial = MultiValueCharFilter(
  1476. lookup_expr='iexact'
  1477. )
  1478. class Meta:
  1479. model = InventoryItem
  1480. fields = ['id', 'name', 'label', 'part_id', 'asset_tag', 'discovered']
  1481. def search(self, queryset, name, value):
  1482. if not value.strip():
  1483. return queryset
  1484. qs_filter = (
  1485. Q(name__icontains=value) |
  1486. Q(part_id__icontains=value) |
  1487. Q(serial__icontains=value) |
  1488. Q(asset_tag__icontains=value) |
  1489. Q(description__icontains=value)
  1490. )
  1491. return queryset.filter(qs_filter)
  1492. class InventoryItemRoleFilterSet(OrganizationalModelFilterSet):
  1493. class Meta:
  1494. model = InventoryItemRole
  1495. fields = ['id', 'name', 'slug', 'color']
  1496. class VirtualChassisFilterSet(NetBoxModelFilterSet):
  1497. master_id = django_filters.ModelMultipleChoiceFilter(
  1498. queryset=Device.objects.all(),
  1499. label=_('Master (ID)'),
  1500. )
  1501. master = django_filters.ModelMultipleChoiceFilter(
  1502. field_name='master__name',
  1503. queryset=Device.objects.all(),
  1504. to_field_name='name',
  1505. label=_('Master (name)'),
  1506. )
  1507. region_id = TreeNodeMultipleChoiceFilter(
  1508. queryset=Region.objects.all(),
  1509. field_name='master__site__region',
  1510. lookup_expr='in',
  1511. label=_('Region (ID)'),
  1512. )
  1513. region = TreeNodeMultipleChoiceFilter(
  1514. queryset=Region.objects.all(),
  1515. field_name='master__site__region',
  1516. lookup_expr='in',
  1517. to_field_name='slug',
  1518. label=_('Region (slug)'),
  1519. )
  1520. site_group_id = TreeNodeMultipleChoiceFilter(
  1521. queryset=SiteGroup.objects.all(),
  1522. field_name='master__site__group',
  1523. lookup_expr='in',
  1524. label=_('Site group (ID)'),
  1525. )
  1526. site_group = TreeNodeMultipleChoiceFilter(
  1527. queryset=SiteGroup.objects.all(),
  1528. field_name='master__site__group',
  1529. lookup_expr='in',
  1530. to_field_name='slug',
  1531. label=_('Site group (slug)'),
  1532. )
  1533. site_id = django_filters.ModelMultipleChoiceFilter(
  1534. field_name='master__site',
  1535. queryset=Site.objects.all(),
  1536. label=_('Site (ID)'),
  1537. )
  1538. site = django_filters.ModelMultipleChoiceFilter(
  1539. field_name='master__site__slug',
  1540. queryset=Site.objects.all(),
  1541. to_field_name='slug',
  1542. label=_('Site name (slug)'),
  1543. )
  1544. tenant_id = django_filters.ModelMultipleChoiceFilter(
  1545. field_name='master__tenant',
  1546. queryset=Tenant.objects.all(),
  1547. label=_('Tenant (ID)'),
  1548. )
  1549. tenant = django_filters.ModelMultipleChoiceFilter(
  1550. field_name='master__tenant__slug',
  1551. queryset=Tenant.objects.all(),
  1552. to_field_name='slug',
  1553. label=_('Tenant (slug)'),
  1554. )
  1555. class Meta:
  1556. model = VirtualChassis
  1557. fields = ['id', 'domain', 'name']
  1558. def search(self, queryset, name, value):
  1559. if not value.strip():
  1560. return queryset
  1561. qs_filter = (
  1562. Q(name__icontains=value) |
  1563. Q(members__name__icontains=value) |
  1564. Q(domain__icontains=value)
  1565. )
  1566. return queryset.filter(qs_filter).distinct()
  1567. class CableFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
  1568. termination_a_type = ContentTypeFilter(
  1569. field_name='terminations__termination_type'
  1570. )
  1571. termination_a_id = MultiValueNumberFilter(
  1572. method='filter_by_cable_end_a',
  1573. field_name='terminations__termination_id'
  1574. )
  1575. termination_b_type = ContentTypeFilter(
  1576. field_name='terminations__termination_type'
  1577. )
  1578. termination_b_id = MultiValueNumberFilter(
  1579. method='filter_by_cable_end_b',
  1580. field_name='terminations__termination_id'
  1581. )
  1582. type = django_filters.MultipleChoiceFilter(
  1583. choices=CableTypeChoices
  1584. )
  1585. status = django_filters.MultipleChoiceFilter(
  1586. choices=LinkStatusChoices
  1587. )
  1588. color = django_filters.MultipleChoiceFilter(
  1589. choices=ColorChoices
  1590. )
  1591. device_id = MultiValueNumberFilter(
  1592. method='filter_by_termination'
  1593. )
  1594. device = MultiValueCharFilter(
  1595. method='filter_by_termination',
  1596. field_name='device__name'
  1597. )
  1598. rack_id = MultiValueNumberFilter(
  1599. method='filter_by_termination',
  1600. field_name='rack_id'
  1601. )
  1602. rack = MultiValueCharFilter(
  1603. method='filter_by_termination',
  1604. field_name='rack__name'
  1605. )
  1606. location_id = MultiValueNumberFilter(
  1607. method='filter_by_termination',
  1608. field_name='location_id'
  1609. )
  1610. location = MultiValueCharFilter(
  1611. method='filter_by_termination',
  1612. field_name='location__name'
  1613. )
  1614. site_id = MultiValueNumberFilter(
  1615. method='filter_by_termination',
  1616. field_name='site_id'
  1617. )
  1618. site = MultiValueCharFilter(
  1619. method='filter_by_termination',
  1620. field_name='site__slug'
  1621. )
  1622. class Meta:
  1623. model = Cable
  1624. fields = ['id', 'label', 'length', 'length_unit']
  1625. def search(self, queryset, name, value):
  1626. if not value.strip():
  1627. return queryset
  1628. return queryset.filter(label__icontains=value)
  1629. def filter_by_termination(self, queryset, name, value):
  1630. # Filter by a related object cached on CableTermination. Note the underscore preceding the field name.
  1631. # Supported objects: device, rack, location, site
  1632. return queryset.filter(**{f'terminations___{name}__in': value}).distinct()
  1633. def filter_by_cable_end(self, queryset, name, value, side):
  1634. # Filter by termination id and cable_end type
  1635. return queryset.filter(**{f'{name}__in': value, 'terminations__cable_end': side}).distinct()
  1636. def filter_by_cable_end_a(self, queryset, name, value):
  1637. # Filter by termination id and cable_end type
  1638. return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_A)
  1639. def filter_by_cable_end_b(self, queryset, name, value):
  1640. # Filter by termination id and cable_end type
  1641. return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_B)
  1642. class CableTerminationFilterSet(BaseFilterSet):
  1643. termination_type = ContentTypeFilter()
  1644. class Meta:
  1645. model = CableTermination
  1646. fields = ['id', 'cable', 'cable_end', 'termination_type', 'termination_id']
  1647. class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
  1648. region_id = TreeNodeMultipleChoiceFilter(
  1649. queryset=Region.objects.all(),
  1650. field_name='site__region',
  1651. lookup_expr='in',
  1652. label=_('Region (ID)'),
  1653. )
  1654. region = TreeNodeMultipleChoiceFilter(
  1655. queryset=Region.objects.all(),
  1656. field_name='site__region',
  1657. lookup_expr='in',
  1658. to_field_name='slug',
  1659. label=_('Region (slug)'),
  1660. )
  1661. site_group_id = TreeNodeMultipleChoiceFilter(
  1662. queryset=SiteGroup.objects.all(),
  1663. field_name='site__group',
  1664. lookup_expr='in',
  1665. label=_('Site group (ID)'),
  1666. )
  1667. site_group = TreeNodeMultipleChoiceFilter(
  1668. queryset=SiteGroup.objects.all(),
  1669. field_name='site__group',
  1670. lookup_expr='in',
  1671. to_field_name='slug',
  1672. label=_('Site group (slug)'),
  1673. )
  1674. site_id = django_filters.ModelMultipleChoiceFilter(
  1675. queryset=Site.objects.all(),
  1676. label=_('Site (ID)'),
  1677. )
  1678. site = django_filters.ModelMultipleChoiceFilter(
  1679. field_name='site__slug',
  1680. queryset=Site.objects.all(),
  1681. to_field_name='slug',
  1682. label=_('Site name (slug)'),
  1683. )
  1684. location_id = TreeNodeMultipleChoiceFilter(
  1685. queryset=Location.objects.all(),
  1686. field_name='location',
  1687. lookup_expr='in',
  1688. label=_('Location (ID)'),
  1689. )
  1690. class Meta:
  1691. model = PowerPanel
  1692. fields = ['id', 'name']
  1693. def search(self, queryset, name, value):
  1694. if not value.strip():
  1695. return queryset
  1696. qs_filter = (
  1697. Q(name__icontains=value)
  1698. )
  1699. return queryset.filter(qs_filter)
  1700. class PowerFeedFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, TenancyFilterSet):
  1701. region_id = TreeNodeMultipleChoiceFilter(
  1702. queryset=Region.objects.all(),
  1703. field_name='power_panel__site__region',
  1704. lookup_expr='in',
  1705. label=_('Region (ID)'),
  1706. )
  1707. region = TreeNodeMultipleChoiceFilter(
  1708. queryset=Region.objects.all(),
  1709. field_name='power_panel__site__region',
  1710. lookup_expr='in',
  1711. to_field_name='slug',
  1712. label=_('Region (slug)'),
  1713. )
  1714. site_group_id = TreeNodeMultipleChoiceFilter(
  1715. queryset=SiteGroup.objects.all(),
  1716. field_name='power_panel__site__group',
  1717. lookup_expr='in',
  1718. label=_('Site group (ID)'),
  1719. )
  1720. site_group = TreeNodeMultipleChoiceFilter(
  1721. queryset=SiteGroup.objects.all(),
  1722. field_name='power_panel__site__group',
  1723. lookup_expr='in',
  1724. to_field_name='slug',
  1725. label=_('Site group (slug)'),
  1726. )
  1727. site_id = django_filters.ModelMultipleChoiceFilter(
  1728. field_name='power_panel__site',
  1729. queryset=Site.objects.all(),
  1730. label=_('Site (ID)'),
  1731. )
  1732. site = django_filters.ModelMultipleChoiceFilter(
  1733. field_name='power_panel__site__slug',
  1734. queryset=Site.objects.all(),
  1735. to_field_name='slug',
  1736. label=_('Site name (slug)'),
  1737. )
  1738. power_panel_id = django_filters.ModelMultipleChoiceFilter(
  1739. queryset=PowerPanel.objects.all(),
  1740. label=_('Power panel (ID)'),
  1741. )
  1742. rack_id = django_filters.ModelMultipleChoiceFilter(
  1743. field_name='rack',
  1744. queryset=Rack.objects.all(),
  1745. label=_('Rack (ID)'),
  1746. )
  1747. status = django_filters.MultipleChoiceFilter(
  1748. choices=PowerFeedStatusChoices,
  1749. null_value=None
  1750. )
  1751. class Meta:
  1752. model = PowerFeed
  1753. fields = [
  1754. 'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 'cable_end',
  1755. ]
  1756. def search(self, queryset, name, value):
  1757. if not value.strip():
  1758. return queryset
  1759. qs_filter = (
  1760. Q(name__icontains=value) |
  1761. Q(power_panel__name__icontains=value) |
  1762. Q(comments__icontains=value)
  1763. )
  1764. return queryset.filter(qs_filter)
  1765. #
  1766. # Connection filter sets
  1767. #
  1768. class ConnectionFilterSet(BaseFilterSet):
  1769. q = django_filters.CharFilter(
  1770. method='search',
  1771. label=_('Search'),
  1772. )
  1773. site_id = MultiValueNumberFilter(
  1774. method='filter_connections',
  1775. field_name='device__site_id'
  1776. )
  1777. site = MultiValueCharFilter(
  1778. method='filter_connections',
  1779. field_name='device__site__slug'
  1780. )
  1781. device_id = MultiValueNumberFilter(
  1782. method='filter_connections',
  1783. field_name='device_id'
  1784. )
  1785. device = MultiValueCharFilter(
  1786. method='filter_connections',
  1787. field_name='device__name'
  1788. )
  1789. def filter_connections(self, queryset, name, value):
  1790. if not value:
  1791. return queryset
  1792. return queryset.filter(**{f'{name}__in': value})
  1793. def search(self, queryset, name, value):
  1794. if not value.strip():
  1795. return queryset
  1796. qs_filter = (
  1797. Q(device__name__icontains=value) |
  1798. Q(cable__label__icontains=value)
  1799. )
  1800. return queryset.filter(qs_filter)
  1801. class ConsoleConnectionFilterSet(ConnectionFilterSet):
  1802. class Meta:
  1803. model = ConsolePort
  1804. fields = ['name']
  1805. class PowerConnectionFilterSet(ConnectionFilterSet):
  1806. class Meta:
  1807. model = PowerPort
  1808. fields = ['name']
  1809. class InterfaceConnectionFilterSet(ConnectionFilterSet):
  1810. class Meta:
  1811. model = Interface
  1812. fields = []