filtersets.py 67 KB

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