filters.py 44 KB

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