filtersets.py 45 KB

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