Coverage for dcim/filtersets.py: 73%

1063 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1import django_filters 

2import netaddr 

3from django.contrib.contenttypes.models import ContentType 

4from django.db.models import Func, IntegerField, Q 

5from django.utils.translation import gettext as _ 

6from drf_spectacular.types import OpenApiTypes 

7from drf_spectacular.utils import extend_schema_field 

8from netaddr.core import AddrFormatError 

9 

10from circuits.models import CircuitTermination, VirtualCircuit, VirtualCircuitTermination 

11from extras.filtersets import LocalConfigContextFilterSet 

12from extras.models import ConfigTemplate 

13from ipam.filtersets import PrimaryIPFilterSet 

14from ipam.models import ASN, VRF, IPAddress, VLANTranslationPolicy 

15from netbox.choices import ColorChoices, DiameterUnitChoices, FlowRateUnitChoices 

16from netbox.filtersets import ( 

17 AttributeFiltersMixin, 

18 BaseFilterSet, 

19 ChangeLoggedModelFilterSet, 

20 NestedGroupModelFilterSet, 

21 NetBoxModelFilterSet, 

22 OrganizationalModelFilterSet, 

23 PrimaryModelFilterSet, 

24) 

25from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet 

26from tenancy.models import * 

27from users.filterset_mixins import OwnerFilterMixin 

28from users.models import User 

29from utilities.filters import ( 

30 MultiValueBigNumberFilter, 

31 MultiValueCharFilter, 

32 MultiValueContentTypeFilter, 

33 MultiValueMACAddressFilter, 

34 MultiValueNumberFilter, 

35 MultiValueWWNFilter, 

36 NumericArrayFilter, 

37 TreeNodeMultipleChoiceFilter, 

38) 

39from utilities.filtersets import register_filterset 

40from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface 

41from vpn.models import L2VPN 

42from wireless.choices import WirelessChannelChoices, WirelessRoleChoices 

43from wireless.models import WirelessLAN, WirelessLink 

44 

45from .choices import * 

46from .constants import * 

47from .models import * 

48 

49__all__ = ( 

50 'CableBundleFilterSet', 

51 'CableFilterSet', 

52 'CableTerminationFilterSet', 

53 'CabledObjectFilterSet', 

54 'CommonInterfaceFilterSet', 

55 'ConsoleConnectionFilterSet', 

56 'ConsolePortFilterSet', 

57 'ConsolePortTemplateFilterSet', 

58 'ConsoleServerPortFilterSet', 

59 'ConsoleServerPortTemplateFilterSet', 

60 'CoolingFeedFilterSet', 

61 'CoolingIntakeFilterSet', 

62 'CoolingIntakeTemplateFilterSet', 

63 'CoolingOutflowFilterSet', 

64 'CoolingOutflowTemplateFilterSet', 

65 'CoolingSourceFilterSet', 

66 'DeviceBayFilterSet', 

67 'DeviceBayTemplateFilterSet', 

68 'DeviceFilterSet', 

69 'DeviceRoleFilterSet', 

70 'DeviceTypeFilterSet', 

71 'FrontPortFilterSet', 

72 'FrontPortTemplateFilterSet', 

73 'InterfaceConnectionFilterSet', 

74 'InterfaceFilterSet', 

75 'InterfaceTemplateFilterSet', 

76 'InventoryItemFilterSet', 

77 'InventoryItemRoleFilterSet', 

78 'InventoryItemTemplateFilterSet', 

79 'LocationFilterSet', 

80 'MACAddressFilterSet', 

81 'ManufacturerFilterSet', 

82 'ModuleBayFilterSet', 

83 'ModuleBayTemplateFilterSet', 

84 'ModuleBayTypeFilterSet', 

85 'ModuleFilterSet', 

86 'ModuleTypeFilterSet', 

87 'ModuleTypeProfileFilterSet', 

88 'PathEndpointFilterSet', 

89 'PlatformFilterSet', 

90 'PowerConnectionFilterSet', 

91 'PowerFeedFilterSet', 

92 'PowerOutletFilterSet', 

93 'PowerOutletTemplateFilterSet', 

94 'PowerPanelFilterSet', 

95 'PowerPortFilterSet', 

96 'PowerPortTemplateFilterSet', 

97 'RackFilterSet', 

98 'RackGroupFilterSet', 

99 'RackReservationFilterSet', 

100 'RackRoleFilterSet', 

101 'RackTypeFilterSet', 

102 'RearPortFilterSet', 

103 'RearPortTemplateFilterSet', 

104 'RegionFilterSet', 

105 'SiteFilterSet', 

106 'SiteGroupFilterSet', 

107 'VirtualChassisFilterSet', 

108 'VirtualDeviceContextFilterSet', 

109) 

110 

111 

112@register_filterset 

113class RegionFilterSet(NestedGroupModelFilterSet, ContactModelFilterSet): 

114 parent_id = django_filters.ModelMultipleChoiceFilter( 

115 queryset=Region.objects.all(), 

116 distinct=False, 

117 label=_('Parent region (ID)'), 

118 ) 

119 parent = django_filters.ModelMultipleChoiceFilter( 

120 field_name='parent__slug', 

121 queryset=Region.objects.all(), 

122 distinct=False, 

123 to_field_name='slug', 

124 label=_('Parent region (slug)'), 

125 ) 

126 ancestor_id = TreeNodeMultipleChoiceFilter( 

127 queryset=Region.objects.all(), 

128 field_name='parent', 

129 lookup_expr='in', 

130 label=_('Region (ID)'), 

131 ) 

132 ancestor = TreeNodeMultipleChoiceFilter( 

133 queryset=Region.objects.all(), 

134 field_name='parent', 

135 lookup_expr='in', 

136 to_field_name='slug', 

137 label=_('Region (slug)'), 

138 ) 

139 

140 class Meta: 

141 model = Region 

142 fields = ('id', 'name', 'slug', 'description') 

143 

144 

145@register_filterset 

146class SiteGroupFilterSet(NestedGroupModelFilterSet, ContactModelFilterSet): 

147 parent_id = django_filters.ModelMultipleChoiceFilter( 

148 queryset=SiteGroup.objects.all(), 

149 distinct=False, 

150 label=_('Parent site group (ID)'), 

151 ) 

152 parent = django_filters.ModelMultipleChoiceFilter( 

153 field_name='parent__slug', 

154 queryset=SiteGroup.objects.all(), 

155 distinct=False, 

156 to_field_name='slug', 

157 label=_('Parent site group (slug)'), 

158 ) 

159 ancestor_id = TreeNodeMultipleChoiceFilter( 

160 queryset=SiteGroup.objects.all(), 

161 field_name='parent', 

162 lookup_expr='in', 

163 label=_('Site group (ID)'), 

164 ) 

165 ancestor = TreeNodeMultipleChoiceFilter( 

166 queryset=SiteGroup.objects.all(), 

167 field_name='parent', 

168 lookup_expr='in', 

169 to_field_name='slug', 

170 label=_('Site group (slug)'), 

171 ) 

172 

173 class Meta: 

174 model = SiteGroup 

175 fields = ('id', 'name', 'slug', 'description') 

176 

177 

178@register_filterset 

179class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet): 

180 status = django_filters.MultipleChoiceFilter( 

181 choices=SiteStatusChoices, 

182 distinct=False, 

183 null_value=None 

184 ) 

185 region_id = TreeNodeMultipleChoiceFilter( 

186 queryset=Region.objects.all(), 

187 field_name='region', 

188 lookup_expr='in', 

189 label=_('Region (ID)'), 

190 ) 

191 region = TreeNodeMultipleChoiceFilter( 

192 queryset=Region.objects.all(), 

193 lookup_expr='in', 

194 to_field_name='slug', 

195 label=_('Region (slug)'), 

196 ) 

197 group_id = TreeNodeMultipleChoiceFilter( 

198 queryset=SiteGroup.objects.all(), 

199 field_name='group', 

200 lookup_expr='in', 

201 label=_('Group (ID)'), 

202 ) 

203 group = TreeNodeMultipleChoiceFilter( 

204 queryset=SiteGroup.objects.all(), 

205 lookup_expr='in', 

206 to_field_name='slug', 

207 label=_('Group (slug)'), 

208 ) 

209 asn = django_filters.ModelMultipleChoiceFilter( 

210 field_name='asns__asn', 

211 queryset=ASN.objects.all(), 

212 to_field_name='asn', 

213 label=_('AS (ID)'), 

214 ) 

215 asn_id = django_filters.ModelMultipleChoiceFilter( 

216 field_name='asns', 

217 queryset=ASN.objects.all(), 

218 label=_('AS (ID)'), 

219 ) 

220 time_zone = MultiValueCharFilter() 

221 

222 class Meta: 

223 model = Site 

224 fields = ('id', 'name', 'slug', 'facility', 'latitude', 'longitude', 'description') 

225 

226 def search(self, queryset, name, value): 

227 if not value.strip(): 

228 return queryset 

229 qs_filter = ( 

230 Q(name__icontains=value) | 

231 Q(facility__icontains=value) | 

232 Q(description__icontains=value) | 

233 Q(physical_address__icontains=value) | 

234 Q(shipping_address__icontains=value) | 

235 Q(comments__icontains=value) 

236 ) 

237 try: 

238 qs_filter |= Q(asns__asn=int(value.strip())) 

239 except ValueError: 

240 pass 

241 return queryset.filter(qs_filter).distinct() 

242 

243 

244@register_filterset 

245class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, NestedGroupModelFilterSet): 

246 region_id = TreeNodeMultipleChoiceFilter( 

247 queryset=Region.objects.all(), 

248 field_name='site__region', 

249 lookup_expr='in', 

250 label=_('Region (ID)'), 

251 ) 

252 region = TreeNodeMultipleChoiceFilter( 

253 queryset=Region.objects.all(), 

254 field_name='site__region', 

255 lookup_expr='in', 

256 to_field_name='slug', 

257 label=_('Region (slug)'), 

258 ) 

259 site_group_id = TreeNodeMultipleChoiceFilter( 

260 queryset=SiteGroup.objects.all(), 

261 field_name='site__group', 

262 lookup_expr='in', 

263 label=_('Site group (ID)'), 

264 ) 

265 site_group = TreeNodeMultipleChoiceFilter( 

266 queryset=SiteGroup.objects.all(), 

267 field_name='site__group', 

268 lookup_expr='in', 

269 to_field_name='slug', 

270 label=_('Site group (slug)'), 

271 ) 

272 site_id = django_filters.ModelMultipleChoiceFilter( 

273 queryset=Site.objects.all(), 

274 distinct=False, 

275 label=_('Site (ID)'), 

276 ) 

277 site = django_filters.ModelMultipleChoiceFilter( 

278 field_name='site__slug', 

279 queryset=Site.objects.all(), 

280 distinct=False, 

281 to_field_name='slug', 

282 label=_('Site (slug)'), 

283 ) 

284 parent_id = django_filters.ModelMultipleChoiceFilter( 

285 queryset=Location.objects.all(), 

286 distinct=False, 

287 label=_('Parent location (ID)'), 

288 ) 

289 parent = django_filters.ModelMultipleChoiceFilter( 

290 field_name='parent__slug', 

291 queryset=Location.objects.all(), 

292 distinct=False, 

293 to_field_name='slug', 

294 label=_('Parent location (slug)'), 

295 ) 

296 ancestor_id = TreeNodeMultipleChoiceFilter( 

297 queryset=Location.objects.all(), 

298 field_name='parent', 

299 lookup_expr='in', 

300 label=_('Location (ID)'), 

301 ) 

302 ancestor = TreeNodeMultipleChoiceFilter( 

303 queryset=Location.objects.all(), 

304 field_name='parent', 

305 lookup_expr='in', 

306 to_field_name='slug', 

307 label=_('Location (slug)'), 

308 ) 

309 status = django_filters.MultipleChoiceFilter( 

310 choices=LocationStatusChoices, 

311 distinct=False, 

312 null_value=None 

313 ) 

314 

315 class Meta: 

316 model = Location 

317 fields = ('id', 'name', 'slug', 'facility', 'description') 

318 

319 def search(self, queryset, name, value): 

320 # Extend `search()` to include querying on Location.facility 

321 if value.strip(): 

322 return super().search(queryset, name, value) | queryset.filter(facility__icontains=value) 

323 return queryset 

324 

325 

326@register_filterset 

327class RackGroupFilterSet(OrganizationalModelFilterSet): 

328 

329 class Meta: 

330 model = RackGroup 

331 fields = ('id', 'name', 'slug', 'description') 

332 

333 

334@register_filterset 

335class RackRoleFilterSet(OrganizationalModelFilterSet): 

336 

337 class Meta: 

338 model = RackRole 

339 fields = ('id', 'name', 'slug', 'color', 'description') 

340 

341 

342@register_filterset 

343class RackTypeFilterSet(PrimaryModelFilterSet): 

344 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

345 queryset=Manufacturer.objects.all(), 

346 distinct=False, 

347 label=_('Manufacturer (ID)'), 

348 ) 

349 manufacturer = django_filters.ModelMultipleChoiceFilter( 

350 field_name='manufacturer__slug', 

351 queryset=Manufacturer.objects.all(), 

352 distinct=False, 

353 to_field_name='slug', 

354 label=_('Manufacturer (slug)'), 

355 ) 

356 form_factor = django_filters.MultipleChoiceFilter( 

357 choices=RackFormFactorChoices, 

358 distinct=False, 

359 ) 

360 width = django_filters.MultipleChoiceFilter( 

361 choices=RackWidthChoices, 

362 distinct=False, 

363 ) 

364 cooling_capability = django_filters.MultipleChoiceFilter( 

365 choices=RackCoolingCapabilityChoices, 

366 distinct=False, 

367 ) 

368 

369 class Meta: 

370 model = RackType 

371 fields = ( 

372 'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_height', 

373 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'cooling_capacity', 

374 'description', 

375 

376 # Counters 

377 'rack_count', 

378 ) 

379 

380 def search(self, queryset, name, value): 

381 if not value.strip(): 

382 return queryset 

383 return queryset.filter( 

384 Q(model__icontains=value) | 

385 Q(description__icontains=value) | 

386 Q(comments__icontains=value) 

387 ) 

388 

389 

390@register_filterset 

391class RackFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet): 

392 region_id = TreeNodeMultipleChoiceFilter( 

393 queryset=Region.objects.all(), 

394 field_name='site__region', 

395 lookup_expr='in', 

396 label=_('Region (ID)'), 

397 ) 

398 region = TreeNodeMultipleChoiceFilter( 

399 queryset=Region.objects.all(), 

400 field_name='site__region', 

401 lookup_expr='in', 

402 to_field_name='slug', 

403 label=_('Region (slug)'), 

404 ) 

405 site_group_id = TreeNodeMultipleChoiceFilter( 

406 queryset=SiteGroup.objects.all(), 

407 field_name='site__group', 

408 lookup_expr='in', 

409 label=_('Site group (ID)'), 

410 ) 

411 site_group = TreeNodeMultipleChoiceFilter( 

412 queryset=SiteGroup.objects.all(), 

413 field_name='site__group', 

414 lookup_expr='in', 

415 to_field_name='slug', 

416 label=_('Site group (slug)'), 

417 ) 

418 site_id = django_filters.ModelMultipleChoiceFilter( 

419 queryset=Site.objects.all(), 

420 distinct=False, 

421 label=_('Site (ID)'), 

422 ) 

423 site = django_filters.ModelMultipleChoiceFilter( 

424 field_name='site__slug', 

425 queryset=Site.objects.all(), 

426 distinct=False, 

427 to_field_name='slug', 

428 label=_('Site (slug)'), 

429 ) 

430 location_id = TreeNodeMultipleChoiceFilter( 

431 queryset=Location.objects.all(), 

432 field_name='location', 

433 lookup_expr='in', 

434 label=_('Location (ID)'), 

435 ) 

436 location = TreeNodeMultipleChoiceFilter( 

437 queryset=Location.objects.all(), 

438 field_name='location', 

439 lookup_expr='in', 

440 to_field_name='slug', 

441 label=_('Location (slug)'), 

442 ) 

443 group_id = django_filters.ModelMultipleChoiceFilter( 

444 queryset=RackGroup.objects.all(), 

445 distinct=False, 

446 label=_('Group (ID)'), 

447 ) 

448 group = django_filters.ModelMultipleChoiceFilter( 

449 field_name='group__slug', 

450 queryset=RackGroup.objects.all(), 

451 distinct=False, 

452 to_field_name='slug', 

453 label=_('Group (slug)'), 

454 ) 

455 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

456 field_name='rack_type__manufacturer', 

457 queryset=Manufacturer.objects.all(), 

458 distinct=False, 

459 label=_('Manufacturer (ID)'), 

460 ) 

461 manufacturer = django_filters.ModelMultipleChoiceFilter( 

462 field_name='rack_type__manufacturer__slug', 

463 queryset=Manufacturer.objects.all(), 

464 distinct=False, 

465 to_field_name='slug', 

466 label=_('Manufacturer (slug)'), 

467 ) 

468 rack_type = django_filters.ModelMultipleChoiceFilter( 

469 field_name='rack_type__slug', 

470 queryset=RackType.objects.all(), 

471 distinct=False, 

472 to_field_name='slug', 

473 label=_('Rack type (slug)'), 

474 ) 

475 rack_type_id = django_filters.ModelMultipleChoiceFilter( 

476 queryset=RackType.objects.all(), 

477 distinct=False, 

478 label=_('Rack type (ID)'), 

479 ) 

480 status = django_filters.MultipleChoiceFilter( 

481 choices=RackStatusChoices, 

482 distinct=False, 

483 null_value=None 

484 ) 

485 form_factor = django_filters.MultipleChoiceFilter( 

486 choices=RackFormFactorChoices, 

487 distinct=False, 

488 ) 

489 width = django_filters.MultipleChoiceFilter( 

490 choices=RackWidthChoices, 

491 distinct=False, 

492 ) 

493 role_id = django_filters.ModelMultipleChoiceFilter( 

494 queryset=RackRole.objects.all(), 

495 distinct=False, 

496 label=_('Role (ID)'), 

497 ) 

498 role = django_filters.ModelMultipleChoiceFilter( 

499 field_name='role__slug', 

500 queryset=RackRole.objects.all(), 

501 distinct=False, 

502 to_field_name='slug', 

503 label=_('Role (slug)'), 

504 ) 

505 serial = MultiValueCharFilter( 

506 lookup_expr='iexact' 

507 ) 

508 

509 cooling_capability = django_filters.MultipleChoiceFilter( 

510 choices=RackCoolingCapabilityChoices, 

511 distinct=False, 

512 ) 

513 

514 class Meta: 

515 model = Rack 

516 fields = ( 

517 'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 

518 'outer_height', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'cooling_capacity', 

519 'weight', 'max_weight', 'weight_unit', 'description', 

520 ) 

521 

522 def search(self, queryset, name, value): 

523 if not value.strip(): 

524 return queryset 

525 return queryset.filter( 

526 Q(name__icontains=value) | 

527 Q(facility_id__icontains=value) | 

528 Q(serial__icontains=value.strip()) | 

529 Q(asset_tag__icontains=value.strip()) | 

530 Q(description__icontains=value) | 

531 Q(comments__icontains=value) 

532 ) 

533 

534 

535@register_filterset 

536class RackReservationFilterSet(PrimaryModelFilterSet, TenancyFilterSet): 

537 rack_id = django_filters.ModelMultipleChoiceFilter( 

538 queryset=Rack.objects.all(), 

539 distinct=False, 

540 label=_('Rack (ID)'), 

541 ) 

542 site_id = django_filters.ModelMultipleChoiceFilter( 

543 field_name='rack__site', 

544 queryset=Site.objects.all(), 

545 distinct=False, 

546 label=_('Site (ID)'), 

547 ) 

548 site = django_filters.ModelMultipleChoiceFilter( 

549 field_name='rack__site__slug', 

550 queryset=Site.objects.all(), 

551 distinct=False, 

552 to_field_name='slug', 

553 label=_('Site (slug)'), 

554 ) 

555 region_id = TreeNodeMultipleChoiceFilter( 

556 queryset=Region.objects.all(), 

557 field_name='rack__site__region', 

558 lookup_expr='in', 

559 label=_('Region (ID)'), 

560 ) 

561 region = TreeNodeMultipleChoiceFilter( 

562 queryset=Region.objects.all(), 

563 field_name='rack__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='rack__site__group', 

571 lookup_expr='in', 

572 label=_('Site group (ID)'), 

573 ) 

574 site_group = TreeNodeMultipleChoiceFilter( 

575 queryset=SiteGroup.objects.all(), 

576 field_name='rack__site__group', 

577 lookup_expr='in', 

578 to_field_name='slug', 

579 label=_('Site group (slug)'), 

580 ) 

581 location_id = TreeNodeMultipleChoiceFilter( 

582 queryset=Location.objects.all(), 

583 field_name='rack__location', 

584 lookup_expr='in', 

585 label=_('Location (ID)'), 

586 ) 

587 location = TreeNodeMultipleChoiceFilter( 

588 queryset=Location.objects.all(), 

589 field_name='rack__location', 

590 lookup_expr='in', 

591 to_field_name='slug', 

592 label=_('Location (slug)'), 

593 ) 

594 group_id = django_filters.ModelMultipleChoiceFilter( 

595 queryset=RackGroup.objects.all(), 

596 field_name='rack__group', 

597 distinct=False, 

598 label=_('Group (ID)'), 

599 ) 

600 group = django_filters.ModelMultipleChoiceFilter( 

601 field_name='rack__group__slug', 

602 queryset=RackGroup.objects.all(), 

603 distinct=False, 

604 to_field_name='slug', 

605 label=_('Group (slug)'), 

606 ) 

607 status = django_filters.MultipleChoiceFilter( 

608 choices=RackReservationStatusChoices, 

609 distinct=False, 

610 null_value=None 

611 ) 

612 user_id = django_filters.ModelMultipleChoiceFilter( 

613 queryset=User.objects.all(), 

614 distinct=False, 

615 label=_('User (ID)'), 

616 ) 

617 user = django_filters.ModelMultipleChoiceFilter( 

618 field_name='user__username', 

619 queryset=User.objects.all(), 

620 distinct=False, 

621 to_field_name='username', 

622 label=_('User (name)'), 

623 ) 

624 unit = NumericArrayFilter( 

625 field_name='units', 

626 lookup_expr='contains' 

627 ) 

628 unit_count_min = django_filters.NumberFilter( 

629 field_name='unit_count', 

630 lookup_expr='gte', 

631 label=_('Minimum unit count'), 

632 ) 

633 unit_count_max = django_filters.NumberFilter( 

634 field_name='unit_count', 

635 lookup_expr='lte', 

636 label=_('Maximum unit count'), 

637 ) 

638 

639 class Meta: 

640 model = RackReservation 

641 fields = ('id', 'created', 'description') 

642 

643 def filter_queryset(self, queryset): 

644 # Annotate unit_count here so unit_count_min/unit_count_max filters can reference it. 

645 # When called from the list view the queryset is already annotated; Django silently 

646 # overwrites a duplicate annotation with the same expression, so this is safe. 

647 queryset = queryset.annotate( 

648 unit_count=Func('units', function='CARDINALITY', output_field=IntegerField()) 

649 ) 

650 return super().filter_queryset(queryset) 

651 

652 def search(self, queryset, name, value): 

653 if not value.strip(): 

654 return queryset 

655 return queryset.filter( 

656 Q(rack__name__icontains=value) | 

657 Q(rack__facility_id__icontains=value) | 

658 Q(user__username__icontains=value) | 

659 Q(description__icontains=value) 

660 ) 

661 

662 

663@register_filterset 

664class ManufacturerFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet): 

665 

666 class Meta: 

667 model = Manufacturer 

668 fields = ('id', 'name', 'slug', 'description') 

669 

670 

671@register_filterset 

672class DeviceTypeFilterSet(PrimaryModelFilterSet): 

673 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

674 queryset=Manufacturer.objects.all(), 

675 distinct=False, 

676 label=_('Manufacturer (ID)'), 

677 ) 

678 manufacturer = django_filters.ModelMultipleChoiceFilter( 

679 field_name='manufacturer__slug', 

680 queryset=Manufacturer.objects.all(), 

681 distinct=False, 

682 to_field_name='slug', 

683 label=_('Manufacturer (slug)'), 

684 ) 

685 default_platform_id = TreeNodeMultipleChoiceFilter( 

686 queryset=Platform.objects.all(), 

687 field_name='default_platform', 

688 lookup_expr='in', 

689 label=_('Default platform (ID)'), 

690 ) 

691 default_platform = TreeNodeMultipleChoiceFilter( 

692 queryset=Platform.objects.all(), 

693 field_name='default_platform', 

694 to_field_name='slug', 

695 lookup_expr='in', 

696 label=_('Default platform (slug)'), 

697 ) 

698 has_front_image = django_filters.BooleanFilter( 

699 label=_('Has a front image'), 

700 method='_has_front_image' 

701 ) 

702 has_rear_image = django_filters.BooleanFilter( 

703 label=_('Has a rear image'), 

704 method='_has_rear_image' 

705 ) 

706 console_ports = django_filters.BooleanFilter( 

707 method='_console_ports', 

708 label=_('Has console ports'), 

709 ) 

710 console_server_ports = django_filters.BooleanFilter( 

711 method='_console_server_ports', 

712 label=_('Has console server ports'), 

713 ) 

714 power_ports = django_filters.BooleanFilter( 

715 method='_power_ports', 

716 label=_('Has power ports'), 

717 ) 

718 power_outlets = django_filters.BooleanFilter( 

719 method='_power_outlets', 

720 label=_('Has power outlets'), 

721 ) 

722 interfaces = django_filters.BooleanFilter( 

723 method='_interfaces', 

724 label=_('Has interfaces'), 

725 ) 

726 pass_through_ports = django_filters.BooleanFilter( 

727 method='_pass_through_ports', 

728 label=_('Has pass-through ports'), 

729 ) 

730 module_bays = django_filters.BooleanFilter( 

731 method='_module_bays', 

732 label=_('Has module bays'), 

733 ) 

734 device_bays = django_filters.BooleanFilter( 

735 method='_device_bays', 

736 label=_('Has device bays'), 

737 ) 

738 inventory_items = django_filters.BooleanFilter( 

739 method='_inventory_items', 

740 label=_('Has inventory items'), 

741 ) 

742 

743 class Meta: 

744 model = DeviceType 

745 fields = ( 

746 'id', 'model', 'slug', 'part_number', 'u_height', 'exclude_from_utilization', 'is_full_depth', 

747 'subdevice_role', 'airflow', 'cooling_method', 'weight', 'weight_unit', 'end_of_life', 'description', 

748 

749 # Counters 

750 'console_port_template_count', 

751 'console_server_port_template_count', 

752 'power_port_template_count', 

753 'power_outlet_template_count', 

754 'cooling_intake_template_count', 

755 'cooling_outflow_template_count', 

756 'interface_template_count', 

757 'front_port_template_count', 

758 'rear_port_template_count', 

759 'device_bay_template_count', 

760 'module_bay_template_count', 

761 'inventory_item_template_count', 

762 'device_count', 

763 ) 

764 

765 def search(self, queryset, name, value): 

766 if not value.strip(): 

767 return queryset 

768 return queryset.filter( 

769 Q(manufacturer__name__icontains=value) | 

770 Q(model__icontains=value) | 

771 Q(part_number__icontains=value) | 

772 Q(description__icontains=value) | 

773 Q(comments__icontains=value) 

774 ) 

775 

776 def _has_front_image(self, queryset, name, value): 

777 if value: 

778 return queryset.exclude(front_image='') 

779 return queryset.filter(front_image='') 

780 

781 def _has_rear_image(self, queryset, name, value): 

782 if value: 

783 return queryset.exclude(rear_image='') 

784 return queryset.filter(rear_image='') 

785 

786 def _console_ports(self, queryset, name, value): 

787 return queryset.exclude(consoleporttemplates__isnull=value) 

788 

789 def _console_server_ports(self, queryset, name, value): 

790 return queryset.exclude(consoleserverporttemplates__isnull=value) 

791 

792 def _power_ports(self, queryset, name, value): 

793 return queryset.exclude(powerporttemplates__isnull=value) 

794 

795 def _power_outlets(self, queryset, name, value): 

796 return queryset.exclude(poweroutlettemplates__isnull=value) 

797 

798 def _interfaces(self, queryset, name, value): 

799 return queryset.exclude(interfacetemplates__isnull=value) 

800 

801 def _pass_through_ports(self, queryset, name, value): 

802 return queryset.exclude( 

803 frontporttemplates__isnull=value, 

804 rearporttemplates__isnull=value 

805 ) 

806 

807 def _module_bays(self, queryset, name, value): 

808 return queryset.exclude(modulebaytemplates__isnull=value) 

809 

810 def _device_bays(self, queryset, name, value): 

811 return queryset.exclude(devicebaytemplates__isnull=value) 

812 

813 def _inventory_items(self, queryset, name, value): 

814 return queryset.exclude(inventoryitemtemplates__isnull=value) 

815 

816 

817@register_filterset 

818class ModuleBayTypeFilterSet(PrimaryModelFilterSet): 

819 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

820 queryset=Manufacturer.objects.all(), 

821 distinct=False, 

822 label=_('Manufacturer (ID)'), 

823 ) 

824 manufacturer = django_filters.ModelMultipleChoiceFilter( 

825 field_name='manufacturer__slug', 

826 queryset=Manufacturer.objects.all(), 

827 distinct=False, 

828 to_field_name='slug', 

829 label=_('Manufacturer (slug)'), 

830 ) 

831 module_type_id = django_filters.ModelMultipleChoiceFilter( 

832 field_name='module_types', 

833 queryset=ModuleType.objects.all(), 

834 label=_('Module type (ID)'), 

835 ) 

836 module_bay_template_id = django_filters.ModelMultipleChoiceFilter( 

837 field_name='module_bay_templates', 

838 queryset=ModuleBayTemplate.objects.all(), 

839 label=_('Module bay template (ID)'), 

840 ) 

841 module_bay_id = django_filters.ModelMultipleChoiceFilter( 

842 field_name='module_bays', 

843 queryset=ModuleBay.objects.all(), 

844 label=_('Module bay (ID)'), 

845 ) 

846 

847 class Meta: 

848 model = ModuleBayType 

849 fields = ('id', 'name', 'slug', 'color', 'description') 

850 

851 def search(self, queryset, name, value): 

852 if not value.strip(): 

853 return queryset 

854 return queryset.filter( 

855 Q(name__icontains=value) | 

856 Q(slug__icontains=value) | 

857 Q(description__icontains=value) | 

858 Q(comments__icontains=value) 

859 ) 

860 

861 

862@register_filterset 

863class ModuleTypeProfileFilterSet(PrimaryModelFilterSet): 

864 

865 class Meta: 

866 model = ModuleTypeProfile 

867 fields = ('id', 'name', 'description') 

868 

869 def search(self, queryset, name, value): 

870 if not value.strip(): 

871 return queryset 

872 return queryset.filter( 

873 Q(name__icontains=value) | 

874 Q(description__icontains=value) | 

875 Q(comments__icontains=value) 

876 ) 

877 

878 

879@register_filterset 

880class ModuleTypeFilterSet(AttributeFiltersMixin, PrimaryModelFilterSet): 

881 profile_id = django_filters.ModelMultipleChoiceFilter( 

882 queryset=ModuleTypeProfile.objects.all(), 

883 distinct=False, 

884 label=_('Profile (ID)'), 

885 ) 

886 profile = django_filters.ModelMultipleChoiceFilter( 

887 field_name='profile__name', 

888 queryset=ModuleTypeProfile.objects.all(), 

889 distinct=False, 

890 to_field_name='name', 

891 label=_('Profile (name)'), 

892 ) 

893 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

894 queryset=Manufacturer.objects.all(), 

895 distinct=False, 

896 label=_('Manufacturer (ID)'), 

897 ) 

898 manufacturer = django_filters.ModelMultipleChoiceFilter( 

899 field_name='manufacturer__slug', 

900 queryset=Manufacturer.objects.all(), 

901 distinct=False, 

902 to_field_name='slug', 

903 label=_('Manufacturer (slug)'), 

904 ) 

905 module_bay_type_id = django_filters.ModelMultipleChoiceFilter( 

906 field_name='module_bay_types', 

907 queryset=ModuleBayType.objects.all(), 

908 distinct=False, 

909 label=_('Module bay type (ID)'), 

910 ) 

911 module_bay_type = django_filters.ModelMultipleChoiceFilter( 

912 field_name='module_bay_types__slug', 

913 queryset=ModuleBayType.objects.all(), 

914 distinct=False, 

915 to_field_name='slug', 

916 label=_('Module bay type (slug)'), 

917 ) 

918 console_ports = django_filters.BooleanFilter( 

919 method='_console_ports', 

920 label=_('Has console ports'), 

921 ) 

922 console_server_ports = django_filters.BooleanFilter( 

923 method='_console_server_ports', 

924 label=_('Has console server ports'), 

925 ) 

926 power_ports = django_filters.BooleanFilter( 

927 method='_power_ports', 

928 label=_('Has power ports'), 

929 ) 

930 power_outlets = django_filters.BooleanFilter( 

931 method='_power_outlets', 

932 label=_('Has power outlets'), 

933 ) 

934 interfaces = django_filters.BooleanFilter( 

935 method='_interfaces', 

936 label=_('Has interfaces'), 

937 ) 

938 pass_through_ports = django_filters.BooleanFilter( 

939 method='_pass_through_ports', 

940 label=_('Has pass-through ports'), 

941 ) 

942 module_bays = django_filters.BooleanFilter( 

943 method='_module_bays', 

944 label=_('Has module bays'), 

945 ) 

946 

947 class Meta: 

948 model = ModuleType 

949 fields = ( 

950 'id', 'model', 'part_number', 'airflow', 'cooling_method', 'weight', 'weight_unit', 'end_of_life', 

951 'description', 

952 

953 # Counters 

954 'console_port_template_count', 

955 'console_server_port_template_count', 

956 'power_port_template_count', 

957 'power_outlet_template_count', 

958 'cooling_intake_template_count', 

959 'cooling_outflow_template_count', 

960 'interface_template_count', 

961 'front_port_template_count', 

962 'rear_port_template_count', 

963 'module_bay_template_count', 

964 'module_count', 

965 ) 

966 

967 def search(self, queryset, name, value): 

968 if not value.strip(): 

969 return queryset 

970 return queryset.filter( 

971 Q(manufacturer__name__icontains=value) | 

972 Q(model__icontains=value) | 

973 Q(part_number__icontains=value) | 

974 Q(description__icontains=value) | 

975 Q(comments__icontains=value) 

976 ) 

977 

978 def _console_ports(self, queryset, name, value): 

979 return queryset.exclude(consoleporttemplates__isnull=value) 

980 

981 def _console_server_ports(self, queryset, name, value): 

982 return queryset.exclude(consoleserverporttemplates__isnull=value) 

983 

984 def _power_ports(self, queryset, name, value): 

985 return queryset.exclude(powerporttemplates__isnull=value) 

986 

987 def _power_outlets(self, queryset, name, value): 

988 return queryset.exclude(poweroutlettemplates__isnull=value) 

989 

990 def _interfaces(self, queryset, name, value): 

991 return queryset.exclude(interfacetemplates__isnull=value) 

992 

993 def _pass_through_ports(self, queryset, name, value): 

994 return queryset.exclude( 

995 frontporttemplates__isnull=value, 

996 rearporttemplates__isnull=value 

997 ) 

998 

999 def _module_bays(self, queryset, name, value): 

1000 return queryset.exclude(modulebaytemplates__isnull=value) 

1001 

1002 

1003class DeviceTypeComponentFilterSet(django_filters.FilterSet): 

1004 q = django_filters.CharFilter( 

1005 method='search', 

1006 label=_('Search'), 

1007 ) 

1008 device_type_id = django_filters.ModelMultipleChoiceFilter( 

1009 queryset=DeviceType.objects.all(), 

1010 distinct=False, 

1011 field_name='device_type_id', 

1012 label=_('Device type (ID)'), 

1013 ) 

1014 

1015 def search(self, queryset, name, value): 

1016 if not value.strip(): 

1017 return queryset 

1018 return queryset.filter( 

1019 Q(name__icontains=value) | 

1020 Q(description__icontains=value) 

1021 ) 

1022 

1023 

1024class ModularDeviceTypeComponentFilterSet(DeviceTypeComponentFilterSet): 

1025 module_type_id = django_filters.ModelMultipleChoiceFilter( 

1026 queryset=ModuleType.objects.all(), 

1027 distinct=False, 

1028 field_name='module_type_id', 

1029 label=_('Module type (ID)'), 

1030 ) 

1031 

1032 

1033@register_filterset 

1034class ConsolePortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1035 

1036 class Meta: 

1037 model = ConsolePortTemplate 

1038 fields = ('id', 'name', 'label', 'type', 'description') 

1039 

1040 

1041@register_filterset 

1042class ConsoleServerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1043 

1044 class Meta: 

1045 model = ConsoleServerPortTemplate 

1046 fields = ('id', 'name', 'label', 'type', 'description') 

1047 

1048 

1049@register_filterset 

1050class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1051 

1052 class Meta: 

1053 model = PowerPortTemplate 

1054 fields = ('id', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description') 

1055 

1056 

1057@register_filterset 

1058class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1059 feed_leg = django_filters.MultipleChoiceFilter( 

1060 choices=PowerOutletFeedLegChoices, 

1061 distinct=False, 

1062 null_value=None 

1063 ) 

1064 power_port_id = django_filters.ModelMultipleChoiceFilter( 

1065 queryset=PowerPortTemplate.objects.all(), 

1066 distinct=False, 

1067 label=_('Power port (ID)'), 

1068 ) 

1069 

1070 class Meta: 

1071 model = PowerOutletTemplate 

1072 fields = ('id', 'name', 'label', 'type', 'color', 'feed_leg', 'description') 

1073 

1074 

1075@register_filterset 

1076class CoolingIntakeTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1077 type = django_filters.MultipleChoiceFilter( 

1078 choices=CoolingConnectorTypeChoices, 

1079 distinct=False, 

1080 null_value=None 

1081 ) 

1082 diameter_unit = django_filters.MultipleChoiceFilter( 

1083 choices=DiameterUnitChoices, 

1084 distinct=False, 

1085 null_value=None 

1086 ) 

1087 max_flow_unit = django_filters.MultipleChoiceFilter( 

1088 choices=FlowRateUnitChoices, 

1089 distinct=False, 

1090 null_value=None 

1091 ) 

1092 

1093 class Meta: 

1094 model = CoolingIntakeTemplate 

1095 fields = ( 

1096 'id', 'name', 'label', 'diameter', 'max_flow', 'description', 

1097 ) 

1098 

1099 

1100@register_filterset 

1101class CoolingOutflowTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1102 type = django_filters.MultipleChoiceFilter( 

1103 choices=CoolingConnectorTypeChoices, 

1104 distinct=False, 

1105 null_value=None 

1106 ) 

1107 diameter_unit = django_filters.MultipleChoiceFilter( 

1108 choices=DiameterUnitChoices, 

1109 distinct=False, 

1110 null_value=None 

1111 ) 

1112 cooling_intake_id = django_filters.ModelMultipleChoiceFilter( 

1113 field_name='cooling_intake', 

1114 queryset=CoolingIntakeTemplate.objects.all(), 

1115 distinct=False, 

1116 label=_('Cooling intake (ID)'), 

1117 ) 

1118 

1119 class Meta: 

1120 model = CoolingOutflowTemplate 

1121 fields = ('id', 'name', 'label', 'diameter', 'description') 

1122 

1123 

1124@register_filterset 

1125class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1126 type = django_filters.MultipleChoiceFilter( 

1127 choices=InterfaceTypeChoices, 

1128 distinct=False, 

1129 null_value=None 

1130 ) 

1131 parent_id = django_filters.ModelMultipleChoiceFilter( 

1132 field_name='parent', 

1133 queryset=InterfaceTemplate.objects.all(), 

1134 distinct=False, 

1135 ) 

1136 bridge_id = django_filters.ModelMultipleChoiceFilter( 

1137 field_name='bridge', 

1138 queryset=InterfaceTemplate.objects.all(), 

1139 distinct=False, 

1140 ) 

1141 poe_mode = django_filters.MultipleChoiceFilter( 

1142 choices=InterfacePoEModeChoices, 

1143 distinct=False, 

1144 ) 

1145 poe_type = django_filters.MultipleChoiceFilter( 

1146 choices=InterfacePoETypeChoices, 

1147 distinct=False, 

1148 ) 

1149 rf_role = django_filters.MultipleChoiceFilter( 

1150 choices=WirelessRoleChoices, 

1151 distinct=False, 

1152 ) 

1153 

1154 class Meta: 

1155 model = InterfaceTemplate 

1156 fields = ('id', 'name', 'label', 'type', 'channels', 'channel_id', 'enabled', 'mgmt_only', 'description') 

1157 

1158 

1159@register_filterset 

1160class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1161 type = django_filters.MultipleChoiceFilter( 

1162 choices=PortTypeChoices, 

1163 distinct=False, 

1164 null_value=None 

1165 ) 

1166 rear_port_id = django_filters.ModelMultipleChoiceFilter( 

1167 field_name='mappings__rear_port', 

1168 queryset=RearPortTemplate.objects.all(), 

1169 to_field_name='rear_port', 

1170 label=_('Rear port (ID)'), 

1171 ) 

1172 

1173 class Meta: 

1174 model = FrontPortTemplate 

1175 fields = ('id', 'name', 'label', 'type', 'color', 'positions', 'description') 

1176 

1177 

1178@register_filterset 

1179class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1180 type = django_filters.MultipleChoiceFilter( 

1181 choices=PortTypeChoices, 

1182 distinct=False, 

1183 null_value=None 

1184 ) 

1185 front_port_id = django_filters.ModelMultipleChoiceFilter( 

1186 field_name='mappings__front_port', 

1187 queryset=FrontPort.objects.all(), 

1188 to_field_name='front_port', 

1189 label=_('Front port (ID)'), 

1190 ) 

1191 

1192 class Meta: 

1193 model = RearPortTemplate 

1194 fields = ('id', 'name', 'label', 'type', 'color', 'positions', 'description') 

1195 

1196 

1197@register_filterset 

1198class ModuleBayTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): 

1199 module_bay_type_id = django_filters.ModelMultipleChoiceFilter( 

1200 field_name='module_bay_types', 

1201 queryset=ModuleBayType.objects.all(), 

1202 distinct=False, 

1203 label=_('Module bay type (ID)'), 

1204 ) 

1205 module_bay_type = django_filters.ModelMultipleChoiceFilter( 

1206 field_name='module_bay_types__slug', 

1207 queryset=ModuleBayType.objects.all(), 

1208 distinct=False, 

1209 to_field_name='slug', 

1210 label=_('Module bay type (slug)'), 

1211 ) 

1212 

1213 class Meta: 

1214 model = ModuleBayTemplate 

1215 fields = ('id', 'name', 'label', 'position', 'enabled', 'description') 

1216 

1217 

1218@register_filterset 

1219class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet): 

1220 

1221 class Meta: 

1222 model = DeviceBayTemplate 

1223 fields = ('id', 'name', 'label', 'enabled', 'description') 

1224 

1225 

1226@register_filterset 

1227class InventoryItemTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet): 

1228 parent_id = django_filters.ModelMultipleChoiceFilter( 

1229 queryset=InventoryItemTemplate.objects.all(), 

1230 distinct=False, 

1231 label=_('Parent inventory item (ID)'), 

1232 ) 

1233 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

1234 queryset=Manufacturer.objects.all(), 

1235 distinct=False, 

1236 label=_('Manufacturer (ID)'), 

1237 ) 

1238 manufacturer = django_filters.ModelMultipleChoiceFilter( 

1239 field_name='manufacturer__slug', 

1240 queryset=Manufacturer.objects.all(), 

1241 distinct=False, 

1242 to_field_name='slug', 

1243 label=_('Manufacturer (slug)'), 

1244 ) 

1245 role_id = django_filters.ModelMultipleChoiceFilter( 

1246 queryset=InventoryItemRole.objects.all(), 

1247 distinct=False, 

1248 label=_('Role (ID)'), 

1249 ) 

1250 role = django_filters.ModelMultipleChoiceFilter( 

1251 field_name='role__slug', 

1252 queryset=InventoryItemRole.objects.all(), 

1253 distinct=False, 

1254 to_field_name='slug', 

1255 label=_('Role (slug)'), 

1256 ) 

1257 component_type = MultiValueContentTypeFilter() 

1258 component_id = MultiValueNumberFilter() 

1259 

1260 class Meta: 

1261 model = InventoryItemTemplate 

1262 fields = ('id', 'name', 'label', 'part_id', 'description') 

1263 

1264 def search(self, queryset, name, value): 

1265 if not value.strip(): 

1266 return queryset 

1267 qs_filter = ( 

1268 Q(name__icontains=value) | 

1269 Q(part_id__icontains=value) | 

1270 Q(description__icontains=value) 

1271 ) 

1272 return queryset.filter(qs_filter) 

1273 

1274 

1275@register_filterset 

1276class DeviceRoleFilterSet(NestedGroupModelFilterSet): 

1277 config_template_id = django_filters.ModelMultipleChoiceFilter( 

1278 queryset=ConfigTemplate.objects.all(), 

1279 distinct=False, 

1280 label=_('Config template (ID)'), 

1281 ) 

1282 parent_id = django_filters.ModelMultipleChoiceFilter( 

1283 queryset=DeviceRole.objects.all(), 

1284 distinct=False, 

1285 label=_('Parent device role (ID)'), 

1286 ) 

1287 parent = django_filters.ModelMultipleChoiceFilter( 

1288 field_name='parent__slug', 

1289 queryset=DeviceRole.objects.all(), 

1290 distinct=False, 

1291 to_field_name='slug', 

1292 label=_('Parent device role (slug)'), 

1293 ) 

1294 ancestor_id = TreeNodeMultipleChoiceFilter( 

1295 queryset=DeviceRole.objects.all(), 

1296 field_name='parent', 

1297 lookup_expr='in', 

1298 label=_('Parent device role (ID)'), 

1299 ) 

1300 ancestor = TreeNodeMultipleChoiceFilter( 

1301 queryset=DeviceRole.objects.all(), 

1302 field_name='parent', 

1303 lookup_expr='in', 

1304 to_field_name='slug', 

1305 label=_('Parent device role (slug)'), 

1306 ) 

1307 

1308 class Meta: 

1309 model = DeviceRole 

1310 fields = ('id', 'name', 'slug', 'color', 'vm_role', 'description') 

1311 

1312 

1313@register_filterset 

1314class PlatformFilterSet(NestedGroupModelFilterSet): 

1315 parent_id = django_filters.ModelMultipleChoiceFilter( 

1316 queryset=Platform.objects.all(), 

1317 distinct=False, 

1318 label=_('Immediate parent platform (ID)'), 

1319 ) 

1320 parent = django_filters.ModelMultipleChoiceFilter( 

1321 field_name='parent__slug', 

1322 queryset=Platform.objects.all(), 

1323 distinct=False, 

1324 to_field_name='slug', 

1325 label=_('Immediate parent platform (slug)'), 

1326 ) 

1327 ancestor_id = TreeNodeMultipleChoiceFilter( 

1328 queryset=Platform.objects.all(), 

1329 field_name='parent', 

1330 lookup_expr='in', 

1331 label=_('Parent platform (ID)'), 

1332 ) 

1333 ancestor = TreeNodeMultipleChoiceFilter( 

1334 queryset=Platform.objects.all(), 

1335 field_name='parent', 

1336 lookup_expr='in', 

1337 to_field_name='slug', 

1338 label=_('Parent platform (slug)'), 

1339 ) 

1340 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

1341 field_name='manufacturer', 

1342 queryset=Manufacturer.objects.all(), 

1343 distinct=False, 

1344 label=_('Manufacturer (ID)'), 

1345 ) 

1346 manufacturer = django_filters.ModelMultipleChoiceFilter( 

1347 field_name='manufacturer__slug', 

1348 queryset=Manufacturer.objects.all(), 

1349 distinct=False, 

1350 to_field_name='slug', 

1351 label=_('Manufacturer (slug)'), 

1352 ) 

1353 available_for_device_type = django_filters.ModelChoiceFilter( 

1354 queryset=DeviceType.objects.all(), 

1355 method='get_for_device_type' 

1356 ) 

1357 config_template_id = django_filters.ModelMultipleChoiceFilter( 

1358 queryset=ConfigTemplate.objects.all(), 

1359 distinct=False, 

1360 label=_('Config template (ID)'), 

1361 ) 

1362 

1363 class Meta: 

1364 model = Platform 

1365 fields = ('id', 'name', 'slug', 'description') 

1366 

1367 @extend_schema_field(OpenApiTypes.STR) 

1368 def get_for_device_type(self, queryset, name, value): 

1369 """ 

1370 Return all Platforms available for a specific manufacturer based on device type and Platforms not assigned any 

1371 manufacturer 

1372 """ 

1373 return queryset.filter(Q(manufacturer=None) | Q(manufacturer__device_types=value)) 

1374 

1375 

1376@register_filterset 

1377class DeviceFilterSet( 

1378 PrimaryModelFilterSet, 

1379 TenancyFilterSet, 

1380 ContactModelFilterSet, 

1381 LocalConfigContextFilterSet, 

1382 PrimaryIPFilterSet, 

1383): 

1384 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

1385 field_name='device_type__manufacturer', 

1386 queryset=Manufacturer.objects.all(), 

1387 distinct=False, 

1388 label=_('Manufacturer (ID)'), 

1389 ) 

1390 manufacturer = django_filters.ModelMultipleChoiceFilter( 

1391 field_name='device_type__manufacturer__slug', 

1392 queryset=Manufacturer.objects.all(), 

1393 distinct=False, 

1394 to_field_name='slug', 

1395 label=_('Manufacturer (slug)'), 

1396 ) 

1397 device_type = django_filters.ModelMultipleChoiceFilter( 

1398 field_name='device_type__slug', 

1399 queryset=DeviceType.objects.all(), 

1400 distinct=False, 

1401 to_field_name='slug', 

1402 label=_('Device type (slug)'), 

1403 ) 

1404 device_type_id = django_filters.ModelMultipleChoiceFilter( 

1405 queryset=DeviceType.objects.all(), 

1406 distinct=False, 

1407 label=_('Device type (ID)'), 

1408 ) 

1409 role_id = TreeNodeMultipleChoiceFilter( 

1410 field_name='role', 

1411 queryset=DeviceRole.objects.all(), 

1412 lookup_expr='in', 

1413 label=_('Role (ID)'), 

1414 ) 

1415 role = TreeNodeMultipleChoiceFilter( 

1416 queryset=DeviceRole.objects.all(), 

1417 field_name='role', 

1418 lookup_expr='in', 

1419 to_field_name='slug', 

1420 label=_('Role (slug)'), 

1421 ) 

1422 parent_device_id = django_filters.ModelMultipleChoiceFilter( 

1423 field_name='parent_bay__device', 

1424 queryset=Device.objects.all(), 

1425 label=_('Parent Device (ID)'), 

1426 ) 

1427 platform_id = TreeNodeMultipleChoiceFilter( 

1428 queryset=Platform.objects.all(), 

1429 field_name='platform', 

1430 lookup_expr='in', 

1431 label=_('Platform (ID)'), 

1432 ) 

1433 platform = TreeNodeMultipleChoiceFilter( 

1434 field_name='platform', 

1435 queryset=Platform.objects.all(), 

1436 to_field_name='slug', 

1437 lookup_expr='in', 

1438 label=_('Platform (slug)'), 

1439 ) 

1440 region_id = TreeNodeMultipleChoiceFilter( 

1441 queryset=Region.objects.all(), 

1442 field_name='site__region', 

1443 lookup_expr='in', 

1444 label=_('Region (ID)'), 

1445 ) 

1446 region = TreeNodeMultipleChoiceFilter( 

1447 queryset=Region.objects.all(), 

1448 field_name='site__region', 

1449 lookup_expr='in', 

1450 to_field_name='slug', 

1451 label=_('Region (slug)'), 

1452 ) 

1453 site_group_id = TreeNodeMultipleChoiceFilter( 

1454 queryset=SiteGroup.objects.all(), 

1455 field_name='site__group', 

1456 lookup_expr='in', 

1457 label=_('Site group (ID)'), 

1458 ) 

1459 site_group = TreeNodeMultipleChoiceFilter( 

1460 queryset=SiteGroup.objects.all(), 

1461 field_name='site__group', 

1462 lookup_expr='in', 

1463 to_field_name='slug', 

1464 label=_('Site group (slug)'), 

1465 ) 

1466 site_id = django_filters.ModelMultipleChoiceFilter( 

1467 queryset=Site.objects.all(), 

1468 distinct=False, 

1469 label=_('Site (ID)'), 

1470 ) 

1471 site = django_filters.ModelMultipleChoiceFilter( 

1472 field_name='site__slug', 

1473 queryset=Site.objects.all(), 

1474 distinct=False, 

1475 to_field_name='slug', 

1476 label=_('Site name (slug)'), 

1477 ) 

1478 location_id = TreeNodeMultipleChoiceFilter( 

1479 queryset=Location.objects.all(), 

1480 field_name='location', 

1481 lookup_expr='in', 

1482 label=_('Location (ID)'), 

1483 ) 

1484 location = TreeNodeMultipleChoiceFilter( 

1485 queryset=Location.objects.all(), 

1486 field_name='location', 

1487 lookup_expr='in', 

1488 to_field_name='slug', 

1489 label=_('Location (slug)'), 

1490 ) 

1491 rack_id = django_filters.ModelMultipleChoiceFilter( 

1492 field_name='rack', 

1493 queryset=Rack.objects.all(), 

1494 distinct=False, 

1495 label=_('Rack (ID)'), 

1496 ) 

1497 parent_bay_id = django_filters.ModelMultipleChoiceFilter( 

1498 field_name='parent_bay', 

1499 queryset=DeviceBay.objects.all(), 

1500 label=_('Parent bay (ID)'), 

1501 ) 

1502 cluster_id = django_filters.ModelMultipleChoiceFilter( 

1503 queryset=Cluster.objects.all(), 

1504 distinct=False, 

1505 label=_('VM cluster (ID)'), 

1506 ) 

1507 cluster_group = django_filters.ModelMultipleChoiceFilter( 

1508 field_name='cluster__group__slug', 

1509 queryset=ClusterGroup.objects.all(), 

1510 distinct=False, 

1511 to_field_name='slug', 

1512 label=_('Cluster group (slug)'), 

1513 ) 

1514 cluster_group_id = django_filters.ModelMultipleChoiceFilter( 

1515 field_name='cluster__group', 

1516 queryset=ClusterGroup.objects.all(), 

1517 distinct=False, 

1518 label=_('Cluster group (ID)'), 

1519 ) 

1520 model = django_filters.ModelMultipleChoiceFilter( 

1521 field_name='device_type__slug', 

1522 queryset=DeviceType.objects.all(), 

1523 distinct=False, 

1524 to_field_name='slug', 

1525 label=_('Device model (slug)'), 

1526 ) 

1527 name = MultiValueCharFilter( 

1528 lookup_expr='iexact' 

1529 ) 

1530 status = django_filters.MultipleChoiceFilter( 

1531 choices=DeviceStatusChoices, 

1532 distinct=False, 

1533 null_value=None 

1534 ) 

1535 is_full_depth = django_filters.BooleanFilter( 

1536 field_name='device_type__is_full_depth', 

1537 label=_('Is full depth'), 

1538 ) 

1539 mac_address = MultiValueMACAddressFilter( 

1540 field_name='interfaces__mac_addresses__mac_address', 

1541 label=_('MAC address'), 

1542 ) 

1543 serial = MultiValueCharFilter( 

1544 lookup_expr='iexact' 

1545 ) 

1546 has_primary_ip = django_filters.BooleanFilter( 

1547 method='_has_primary_ip', 

1548 label=_('Has a primary IP'), 

1549 ) 

1550 has_oob_ip = django_filters.BooleanFilter( 

1551 method='_has_oob_ip', 

1552 label=_('Has an out-of-band IP'), 

1553 ) 

1554 virtual_chassis_id = django_filters.ModelMultipleChoiceFilter( 

1555 field_name='virtual_chassis', 

1556 queryset=VirtualChassis.objects.all(), 

1557 distinct=False, 

1558 label=_('Virtual chassis (ID)'), 

1559 ) 

1560 virtual_chassis_member = django_filters.BooleanFilter( 

1561 method='_virtual_chassis_member', 

1562 label=_('Is a virtual chassis member') 

1563 ) 

1564 config_template_id = django_filters.ModelMultipleChoiceFilter( 

1565 queryset=ConfigTemplate.objects.all(), 

1566 distinct=False, 

1567 label=_('Config template (ID)'), 

1568 ) 

1569 console_ports = django_filters.BooleanFilter( 

1570 method='_console_ports', 

1571 label=_('Has console ports'), 

1572 ) 

1573 console_server_ports = django_filters.BooleanFilter( 

1574 method='_console_server_ports', 

1575 label=_('Has console server ports'), 

1576 ) 

1577 power_ports = django_filters.BooleanFilter( 

1578 method='_power_ports', 

1579 label=_('Has power ports'), 

1580 ) 

1581 power_outlets = django_filters.BooleanFilter( 

1582 method='_power_outlets', 

1583 label=_('Has power outlets'), 

1584 ) 

1585 interfaces = django_filters.BooleanFilter( 

1586 method='_interfaces', 

1587 label=_('Has interfaces'), 

1588 ) 

1589 pass_through_ports = django_filters.BooleanFilter( 

1590 method='_pass_through_ports', 

1591 label=_('Has pass-through ports'), 

1592 ) 

1593 module_bays = django_filters.BooleanFilter( 

1594 method='_module_bays', 

1595 label=_('Has module bays'), 

1596 ) 

1597 device_bays = django_filters.BooleanFilter( 

1598 method='_device_bays', 

1599 label=_('Has device bays'), 

1600 ) 

1601 oob_ip_id = django_filters.ModelMultipleChoiceFilter( 

1602 field_name='oob_ip', 

1603 queryset=IPAddress.objects.all(), 

1604 distinct=False, 

1605 label=_('OOB IP (ID)'), 

1606 ) 

1607 has_virtual_device_context = django_filters.BooleanFilter( 

1608 method='_has_virtual_device_context', 

1609 label=_('Has virtual device context'), 

1610 ) 

1611 

1612 class Meta: 

1613 model = Device 

1614 fields = ( 

1615 'id', 'asset_tag', 'face', 'position', 'latitude', 'longitude', 'airflow', 'cooling_method', 'vc_position', 

1616 'vc_priority', 'description', 

1617 

1618 # Counters 

1619 'console_port_count', 

1620 'console_server_port_count', 

1621 'power_port_count', 

1622 'power_outlet_count', 

1623 'cooling_intake_count', 

1624 'cooling_outflow_count', 

1625 'interface_count', 

1626 'front_port_count', 

1627 'rear_port_count', 

1628 'device_bay_count', 

1629 'module_bay_count', 

1630 'inventory_item_count', 

1631 ) 

1632 

1633 def search(self, queryset, name, value): 

1634 if not value.strip(): 

1635 return queryset 

1636 qs_filter = ( 

1637 Q(name__icontains=value) | 

1638 Q(virtual_chassis__name__icontains=value) | 

1639 Q(serial__icontains=value.strip()) | 

1640 Q(asset_tag__icontains=value.strip()) | 

1641 Q(description__icontains=value.strip()) | 

1642 Q(comments__icontains=value) 

1643 ) 

1644 # If the given value looks like an IP address, look for primary IPv4/IPv6 assignments 

1645 try: 

1646 ipaddress = netaddr.IPNetwork(value) 

1647 if ipaddress.version == 4: 

1648 qs_filter |= Q(primary_ip4__address__host__inet=ipaddress.ip) 

1649 elif ipaddress.version == 6: 

1650 qs_filter |= Q(primary_ip6__address__host__inet=ipaddress.ip) 

1651 except (AddrFormatError, ValueError): 

1652 pass 

1653 return queryset.filter(qs_filter) 

1654 

1655 def _has_primary_ip(self, queryset, name, value): 

1656 params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False) 

1657 if value: 

1658 return queryset.filter(params) 

1659 return queryset.exclude(params) 

1660 

1661 def _has_oob_ip(self, queryset, name, value): 

1662 params = Q(oob_ip__isnull=False) 

1663 if value: 

1664 return queryset.filter(params) 

1665 return queryset.exclude(params) 

1666 

1667 def _virtual_chassis_member(self, queryset, name, value): 

1668 return queryset.exclude(virtual_chassis__isnull=value) 

1669 

1670 def _console_ports(self, queryset, name, value): 

1671 return queryset.exclude(consoleports__isnull=value) 

1672 

1673 def _console_server_ports(self, queryset, name, value): 

1674 return queryset.exclude(consoleserverports__isnull=value) 

1675 

1676 def _power_ports(self, queryset, name, value): 

1677 return queryset.exclude(powerports__isnull=value) 

1678 

1679 def _power_outlets(self, queryset, name, value): 

1680 return queryset.exclude(poweroutlets__isnull=value) 

1681 

1682 def _interfaces(self, queryset, name, value): 

1683 return queryset.exclude(interfaces__isnull=value) 

1684 

1685 def _pass_through_ports(self, queryset, name, value): 

1686 return queryset.exclude( 

1687 frontports__isnull=value, 

1688 rearports__isnull=value 

1689 ) 

1690 

1691 def _module_bays(self, queryset, name, value): 

1692 return queryset.exclude(modulebays__isnull=value) 

1693 

1694 def _device_bays(self, queryset, name, value): 

1695 return queryset.exclude(devicebays__isnull=value) 

1696 

1697 def _has_virtual_device_context(self, queryset, name, value): 

1698 params = Q(vdcs__isnull=False) 

1699 if value: 

1700 return queryset.filter(params).distinct() 

1701 return queryset.exclude(params) 

1702 

1703 

1704@register_filterset 

1705class VirtualDeviceContextFilterSet(PrimaryModelFilterSet, TenancyFilterSet, PrimaryIPFilterSet): 

1706 device_id = django_filters.ModelMultipleChoiceFilter( 

1707 field_name='device', 

1708 queryset=Device.objects.all(), 

1709 distinct=False, 

1710 label=_('VDC (ID)') 

1711 ) 

1712 device = django_filters.ModelMultipleChoiceFilter( 

1713 field_name='device', 

1714 queryset=Device.objects.all(), 

1715 distinct=False, 

1716 label=_('Device model') 

1717 ) 

1718 interface_id = django_filters.ModelMultipleChoiceFilter( 

1719 field_name='interfaces', 

1720 queryset=Interface.objects.all(), 

1721 label=_('Interface (ID)') 

1722 ) 

1723 status = django_filters.MultipleChoiceFilter( 

1724 choices=VirtualDeviceContextStatusChoices, 

1725 distinct=False, 

1726 ) 

1727 has_primary_ip = django_filters.BooleanFilter( 

1728 method='_has_primary_ip', 

1729 label=_('Has a primary IP') 

1730 ) 

1731 

1732 class Meta: 

1733 model = VirtualDeviceContext 

1734 fields = ('id', 'device', 'name', 'identifier', 'description') 

1735 

1736 def search(self, queryset, name, value): 

1737 if not value.strip(): 

1738 return queryset 

1739 

1740 qs_filter = ( 

1741 Q(name__icontains=value) | 

1742 Q(description__icontains=value) 

1743 ) 

1744 try: 

1745 qs_filter |= Q(identifier=int(value)) 

1746 except ValueError: 

1747 pass 

1748 return queryset.filter(qs_filter).distinct() 

1749 

1750 def _has_primary_ip(self, queryset, name, value): 

1751 params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False) 

1752 if value: 

1753 return queryset.filter(params) 

1754 return queryset.exclude(params) 

1755 

1756 

1757@register_filterset 

1758class ModuleFilterSet(PrimaryModelFilterSet): 

1759 profile_id = django_filters.ModelMultipleChoiceFilter( 

1760 field_name='module_type__profile', 

1761 queryset=ModuleTypeProfile.objects.all(), 

1762 distinct=False, 

1763 label=_('Profile (ID)'), 

1764 ) 

1765 profile = django_filters.ModelMultipleChoiceFilter( 

1766 field_name='module_type__profile__name', 

1767 queryset=ModuleTypeProfile.objects.all(), 

1768 distinct=False, 

1769 to_field_name='name', 

1770 label=_('Profile (name)'), 

1771 ) 

1772 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

1773 field_name='module_type__manufacturer', 

1774 queryset=Manufacturer.objects.all(), 

1775 distinct=False, 

1776 label=_('Manufacturer (ID)'), 

1777 ) 

1778 manufacturer = django_filters.ModelMultipleChoiceFilter( 

1779 field_name='module_type__manufacturer__slug', 

1780 queryset=Manufacturer.objects.all(), 

1781 distinct=False, 

1782 to_field_name='slug', 

1783 label=_('Manufacturer (slug)'), 

1784 ) 

1785 module_type_id = django_filters.ModelMultipleChoiceFilter( 

1786 field_name='module_type', 

1787 queryset=ModuleType.objects.all(), 

1788 distinct=False, 

1789 label=_('Module type (ID)'), 

1790 ) 

1791 module_type = django_filters.ModelMultipleChoiceFilter( 

1792 field_name='module_type__model', 

1793 queryset=ModuleType.objects.all(), 

1794 distinct=False, 

1795 to_field_name='model', 

1796 label=_('Module type (model)'), 

1797 ) 

1798 module_bay_id = TreeNodeMultipleChoiceFilter( 

1799 queryset=ModuleBay.objects.all(), 

1800 field_name='module_bay', 

1801 lookup_expr='in', 

1802 label=_('Module bay (ID)'), 

1803 ) 

1804 region_id = TreeNodeMultipleChoiceFilter( 

1805 queryset=Region.objects.all(), 

1806 field_name='device__site__region', 

1807 lookup_expr='in', 

1808 label=_('Region (ID)'), 

1809 ) 

1810 region = TreeNodeMultipleChoiceFilter( 

1811 queryset=Region.objects.all(), 

1812 field_name='device__site__region', 

1813 lookup_expr='in', 

1814 to_field_name='slug', 

1815 label=_('Region (slug)'), 

1816 ) 

1817 site_group_id = TreeNodeMultipleChoiceFilter( 

1818 queryset=SiteGroup.objects.all(), 

1819 field_name='device__site__group', 

1820 lookup_expr='in', 

1821 label=_('Site group (ID)'), 

1822 ) 

1823 site_group = TreeNodeMultipleChoiceFilter( 

1824 queryset=SiteGroup.objects.all(), 

1825 field_name='device__site__group', 

1826 lookup_expr='in', 

1827 to_field_name='slug', 

1828 label=_('Site group (slug)'), 

1829 ) 

1830 site_id = django_filters.ModelMultipleChoiceFilter( 

1831 field_name='device__site', 

1832 queryset=Site.objects.all(), 

1833 distinct=False, 

1834 label=_('Site (ID)'), 

1835 ) 

1836 site = django_filters.ModelMultipleChoiceFilter( 

1837 field_name='device__site__slug', 

1838 queryset=Site.objects.all(), 

1839 distinct=False, 

1840 to_field_name='slug', 

1841 label=_('Site name (slug)'), 

1842 ) 

1843 location_id = django_filters.ModelMultipleChoiceFilter( 

1844 field_name='device__location', 

1845 queryset=Location.objects.all(), 

1846 distinct=False, 

1847 label=_('Location (ID)'), 

1848 ) 

1849 location = django_filters.ModelMultipleChoiceFilter( 

1850 field_name='device__location__slug', 

1851 queryset=Location.objects.all(), 

1852 distinct=False, 

1853 to_field_name='slug', 

1854 label=_('Location (slug)'), 

1855 ) 

1856 rack_id = django_filters.ModelMultipleChoiceFilter( 

1857 field_name='device__rack', 

1858 queryset=Rack.objects.all(), 

1859 distinct=False, 

1860 label=_('Rack (ID)'), 

1861 ) 

1862 rack = django_filters.ModelMultipleChoiceFilter( 

1863 field_name='device__rack__name', 

1864 queryset=Rack.objects.all(), 

1865 distinct=False, 

1866 to_field_name='name', 

1867 label=_('Rack (name)'), 

1868 ) 

1869 device_id = django_filters.ModelMultipleChoiceFilter( 

1870 queryset=Device.objects.all(), 

1871 distinct=False, 

1872 label=_('Device (ID)'), 

1873 ) 

1874 device = django_filters.ModelMultipleChoiceFilter( 

1875 field_name='device__name', 

1876 queryset=Device.objects.all(), 

1877 distinct=False, 

1878 to_field_name='name', 

1879 label=_('Device (name)'), 

1880 ) 

1881 status = django_filters.MultipleChoiceFilter( 

1882 choices=ModuleStatusChoices, 

1883 distinct=False, 

1884 null_value=None 

1885 ) 

1886 serial = MultiValueCharFilter( 

1887 lookup_expr='iexact' 

1888 ) 

1889 

1890 class Meta: 

1891 model = Module 

1892 fields = ('id', 'status', 'asset_tag', 'description') 

1893 

1894 def search(self, queryset, name, value): 

1895 if not value.strip(): 

1896 return queryset 

1897 return queryset.filter( 

1898 Q(device__name__icontains=value.strip()) | 

1899 Q(serial__icontains=value.strip()) | 

1900 Q(asset_tag__icontains=value.strip()) | 

1901 Q(description__icontains=value) | 

1902 Q(comments__icontains=value) 

1903 ).distinct() 

1904 

1905 

1906class DeviceComponentFilterSet(OwnerFilterMixin, NetBoxModelFilterSet): 

1907 q = django_filters.CharFilter( 

1908 method='search', 

1909 label=_('Search'), 

1910 ) 

1911 region_id = TreeNodeMultipleChoiceFilter( 

1912 queryset=Region.objects.all(), 

1913 field_name='device__site__region', 

1914 lookup_expr='in', 

1915 label=_('Region (ID)'), 

1916 ) 

1917 region = TreeNodeMultipleChoiceFilter( 

1918 queryset=Region.objects.all(), 

1919 field_name='device__site__region', 

1920 lookup_expr='in', 

1921 to_field_name='slug', 

1922 label=_('Region (slug)'), 

1923 ) 

1924 site_group_id = TreeNodeMultipleChoiceFilter( 

1925 queryset=SiteGroup.objects.all(), 

1926 field_name='device__site__group', 

1927 lookup_expr='in', 

1928 label=_('Site group (ID)'), 

1929 ) 

1930 site_group = TreeNodeMultipleChoiceFilter( 

1931 queryset=SiteGroup.objects.all(), 

1932 field_name='device__site__group', 

1933 lookup_expr='in', 

1934 to_field_name='slug', 

1935 label=_('Site group (slug)'), 

1936 ) 

1937 site_id = django_filters.ModelMultipleChoiceFilter( 

1938 field_name='_site', 

1939 queryset=Site.objects.all(), 

1940 distinct=False, 

1941 label=_('Site (ID)'), 

1942 ) 

1943 site = django_filters.ModelMultipleChoiceFilter( 

1944 field_name='_site__slug', 

1945 queryset=Site.objects.all(), 

1946 distinct=False, 

1947 to_field_name='slug', 

1948 label=_('Site name (slug)'), 

1949 ) 

1950 location_id = django_filters.ModelMultipleChoiceFilter( 

1951 field_name='_location', 

1952 queryset=Location.objects.all(), 

1953 distinct=False, 

1954 label=_('Location (ID)'), 

1955 ) 

1956 location = django_filters.ModelMultipleChoiceFilter( 

1957 field_name='_location__slug', 

1958 queryset=Location.objects.all(), 

1959 distinct=False, 

1960 to_field_name='slug', 

1961 label=_('Location (slug)'), 

1962 ) 

1963 rack_id = django_filters.ModelMultipleChoiceFilter( 

1964 field_name='_rack', 

1965 queryset=Rack.objects.all(), 

1966 distinct=False, 

1967 label=_('Rack (ID)'), 

1968 ) 

1969 rack = django_filters.ModelMultipleChoiceFilter( 

1970 field_name='_rack__name', 

1971 queryset=Rack.objects.all(), 

1972 distinct=False, 

1973 to_field_name='name', 

1974 label=_('Rack (name)'), 

1975 ) 

1976 device_id = django_filters.ModelMultipleChoiceFilter( 

1977 queryset=Device.objects.all(), 

1978 distinct=False, 

1979 label=_('Device (ID)'), 

1980 ) 

1981 device = django_filters.ModelMultipleChoiceFilter( 

1982 field_name='device__name', 

1983 queryset=Device.objects.all(), 

1984 distinct=False, 

1985 to_field_name='name', 

1986 label=_('Device (name)'), 

1987 ) 

1988 device_type_id = django_filters.ModelMultipleChoiceFilter( 

1989 field_name='device__device_type', 

1990 queryset=DeviceType.objects.all(), 

1991 distinct=False, 

1992 label=_('Device type (ID)'), 

1993 ) 

1994 device_type = django_filters.ModelMultipleChoiceFilter( 

1995 field_name='device__device_type__model', 

1996 queryset=DeviceType.objects.all(), 

1997 distinct=False, 

1998 to_field_name='model', 

1999 label=_('Device type (model)'), 

2000 ) 

2001 device_role_id = django_filters.ModelMultipleChoiceFilter( 

2002 field_name='device__role', 

2003 queryset=DeviceRole.objects.all(), 

2004 distinct=False, 

2005 label=_('Device role (ID)'), 

2006 ) 

2007 device_role = django_filters.ModelMultipleChoiceFilter( 

2008 field_name='device__role__slug', 

2009 queryset=DeviceRole.objects.all(), 

2010 distinct=False, 

2011 to_field_name='slug', 

2012 label=_('Device role (slug)'), 

2013 ) 

2014 virtual_chassis_id = django_filters.ModelMultipleChoiceFilter( 

2015 field_name='device__virtual_chassis', 

2016 queryset=VirtualChassis.objects.all(), 

2017 distinct=False, 

2018 label=_('Virtual Chassis (ID)') 

2019 ) 

2020 virtual_chassis = django_filters.ModelMultipleChoiceFilter( 

2021 field_name='device__virtual_chassis__name', 

2022 queryset=VirtualChassis.objects.all(), 

2023 distinct=False, 

2024 to_field_name='name', 

2025 label=_('Virtual Chassis'), 

2026 ) 

2027 device_status = django_filters.MultipleChoiceFilter( 

2028 choices=DeviceStatusChoices, 

2029 distinct=False, 

2030 field_name='device__status', 

2031 ) 

2032 tenant_id = django_filters.ModelMultipleChoiceFilter( 

2033 field_name='device__tenant', 

2034 queryset=Tenant.objects.all(), 

2035 distinct=False, 

2036 label=_('Tenant (ID)'), 

2037 ) 

2038 tenant = django_filters.ModelMultipleChoiceFilter( 

2039 field_name='device__tenant__slug', 

2040 queryset=Tenant.objects.all(), 

2041 distinct=False, 

2042 to_field_name='slug', 

2043 label=_('Tenant (slug)'), 

2044 ) 

2045 

2046 def search(self, queryset, name, value): 

2047 if not value.strip(): 

2048 return queryset 

2049 return queryset.filter( 

2050 Q(name__icontains=value) | 

2051 Q(label__icontains=value) | 

2052 Q(description__icontains=value) 

2053 ) 

2054 

2055 

2056class ModularDeviceComponentFilterSet(DeviceComponentFilterSet): 

2057 """ 

2058 Extends DeviceComponentFilterSet to add a module_id filter for components 

2059 which can be associated with a particular module within a device. 

2060 """ 

2061 module_id = django_filters.ModelMultipleChoiceFilter( 

2062 queryset=Module.objects.all(), 

2063 distinct=False, 

2064 label=_('Module (ID)'), 

2065 ) 

2066 

2067 

2068class CabledObjectFilterSet(django_filters.FilterSet): 

2069 cable_id = django_filters.ModelMultipleChoiceFilter( 

2070 queryset=Cable.objects.all(), 

2071 distinct=False, 

2072 label=_('Cable (ID)'), 

2073 ) 

2074 cabled = django_filters.BooleanFilter( 

2075 field_name='cable', 

2076 lookup_expr='isnull', 

2077 exclude=True 

2078 ) 

2079 occupied = django_filters.BooleanFilter( 

2080 method='filter_occupied' 

2081 ) 

2082 

2083 def filter_occupied(self, queryset, name, value): 

2084 if value: 2084 ↛ 2086line 2084 didn't jump to line 2086 because the condition on line 2084 was always true

2085 return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True)) 

2086 return queryset.filter(cable__isnull=True, mark_connected=False) 

2087 

2088 

2089class PathEndpointFilterSet(django_filters.FilterSet): 

2090 connected = django_filters.BooleanFilter( 

2091 method='filter_connected' 

2092 ) 

2093 

2094 def filter_connected(self, queryset, name, value): 

2095 if value: 

2096 return queryset.filter(_path__is_active=True, _path__is_complete=True) 

2097 return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False) | Q(_path__is_complete=False)) 

2098 

2099 

2100@register_filterset 

2101class ConsolePortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet): 

2102 type = django_filters.MultipleChoiceFilter( 

2103 choices=ConsolePortTypeChoices, 

2104 distinct=False, 

2105 null_value=None 

2106 ) 

2107 

2108 class Meta: 

2109 model = ConsolePort 

2110 fields = ( 

2111 'id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end', 'cable_connector', 

2112 ) 

2113 

2114 

2115@register_filterset 

2116class ConsoleServerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet): 

2117 type = django_filters.MultipleChoiceFilter( 

2118 choices=ConsolePortTypeChoices, 

2119 distinct=False, 

2120 null_value=None 

2121 ) 

2122 

2123 class Meta: 

2124 model = ConsoleServerPort 

2125 fields = ( 

2126 'id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end', 'cable_connector', 

2127 ) 

2128 

2129 

2130@register_filterset 

2131class PowerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet): 

2132 type = django_filters.MultipleChoiceFilter( 

2133 choices=PowerPortTypeChoices, 

2134 distinct=False, 

2135 null_value=None 

2136 ) 

2137 

2138 class Meta: 

2139 model = PowerPort 

2140 fields = ( 

2141 'id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable_end', 

2142 'cable_connector', 

2143 ) 

2144 

2145 

2146@register_filterset 

2147class PowerOutletFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet): 

2148 type = django_filters.MultipleChoiceFilter( 

2149 choices=PowerOutletTypeChoices, 

2150 distinct=False, 

2151 null_value=None 

2152 ) 

2153 feed_leg = django_filters.MultipleChoiceFilter( 

2154 choices=PowerOutletFeedLegChoices, 

2155 distinct=False, 

2156 null_value=None 

2157 ) 

2158 power_port_id = django_filters.ModelMultipleChoiceFilter( 

2159 queryset=PowerPort.objects.all(), 

2160 distinct=False, 

2161 label=_('Power port (ID)'), 

2162 ) 

2163 status = django_filters.MultipleChoiceFilter( 

2164 choices=PowerOutletStatusChoices, 

2165 distinct=False, 

2166 null_value=None 

2167 ) 

2168 

2169 class Meta: 

2170 model = PowerOutlet 

2171 fields = ( 

2172 'id', 'name', 'status', 'label', 'feed_leg', 'description', 'color', 'mark_connected', 'cable_end', 

2173 'cable_connector', 

2174 ) 

2175 

2176 

2177@register_filterset 

2178class CoolingIntakeFilterSet(ModularDeviceComponentFilterSet): 

2179 type = django_filters.MultipleChoiceFilter( 

2180 choices=CoolingConnectorTypeChoices, 

2181 distinct=False, 

2182 null_value=None 

2183 ) 

2184 diameter_unit = django_filters.MultipleChoiceFilter( 

2185 choices=DiameterUnitChoices, 

2186 distinct=False, 

2187 null_value=None 

2188 ) 

2189 max_flow_unit = django_filters.MultipleChoiceFilter( 

2190 choices=FlowRateUnitChoices, 

2191 distinct=False, 

2192 null_value=None 

2193 ) 

2194 cooling_outflow_id = django_filters.ModelMultipleChoiceFilter( 

2195 queryset=CoolingOutflow.objects.all(), 

2196 field_name='cooling_outflow', 

2197 distinct=False, 

2198 label=_('Cooling outflow (ID)'), 

2199 ) 

2200 

2201 class Meta: 

2202 model = CoolingIntake 

2203 fields = ( 

2204 'id', 'name', 'label', 'diameter', 'max_flow', 'description', 

2205 ) 

2206 

2207 

2208@register_filterset 

2209class CoolingOutflowFilterSet(ModularDeviceComponentFilterSet): 

2210 type = django_filters.MultipleChoiceFilter( 

2211 choices=CoolingConnectorTypeChoices, 

2212 distinct=False, 

2213 null_value=None 

2214 ) 

2215 diameter_unit = django_filters.MultipleChoiceFilter( 

2216 choices=DiameterUnitChoices, 

2217 distinct=False, 

2218 null_value=None 

2219 ) 

2220 cooling_intake_id = django_filters.ModelMultipleChoiceFilter( 

2221 field_name='cooling_intake', 

2222 queryset=CoolingIntake.objects.all(), 

2223 distinct=False, 

2224 label=_('Cooling intake (ID)'), 

2225 ) 

2226 

2227 class Meta: 

2228 model = CoolingOutflow 

2229 fields = ( 

2230 'id', 'name', 'label', 'diameter', 'description', 

2231 ) 

2232 

2233 

2234@register_filterset 

2235class MACAddressFilterSet(PrimaryModelFilterSet): 

2236 mac_address = MultiValueMACAddressFilter() 

2237 assigned_object_type = MultiValueContentTypeFilter() 

2238 device = MultiValueCharFilter( 

2239 method='filter_device', 

2240 field_name='name', 

2241 label=_('Device (name)'), 

2242 ) 

2243 device_id = MultiValueNumberFilter( 

2244 method='filter_device', 

2245 field_name='pk', 

2246 label=_('Device (ID)'), 

2247 ) 

2248 virtual_machine = MultiValueCharFilter( 

2249 method='filter_virtual_machine', 

2250 field_name='name', 

2251 label=_('Virtual machine (name)'), 

2252 ) 

2253 virtual_machine_id = MultiValueNumberFilter( 

2254 method='filter_virtual_machine', 

2255 field_name='pk', 

2256 label=_('Virtual machine (ID)'), 

2257 ) 

2258 interface = django_filters.ModelMultipleChoiceFilter( 

2259 field_name='interface__name', 

2260 queryset=Interface.objects.all(), 

2261 to_field_name='name', 

2262 label=_('Interface (name)'), 

2263 ) 

2264 interface_id = django_filters.ModelMultipleChoiceFilter( 

2265 field_name='interface', 

2266 queryset=Interface.objects.all(), 

2267 label=_('Interface (ID)'), 

2268 ) 

2269 vminterface = django_filters.ModelMultipleChoiceFilter( 

2270 field_name='vminterface__name', 

2271 queryset=VMInterface.objects.all(), 

2272 to_field_name='name', 

2273 label=_('VM interface (name)'), 

2274 ) 

2275 vminterface_id = django_filters.ModelMultipleChoiceFilter( 

2276 field_name='vminterface', 

2277 queryset=VMInterface.objects.all(), 

2278 label=_('VM interface (ID)'), 

2279 ) 

2280 assigned = django_filters.BooleanFilter( 

2281 method='filter_assigned', 

2282 label=_('Is assigned'), 

2283 ) 

2284 primary = django_filters.BooleanFilter( 

2285 method='filter_primary', 

2286 label=_('Is primary'), 

2287 ) 

2288 

2289 class Meta: 

2290 model = MACAddress 

2291 fields = ('id', 'description', 'assigned_object_type', 'assigned_object_id') 

2292 

2293 def search(self, queryset, name, value): 

2294 if not value.strip(): 

2295 return queryset 

2296 qs_filter = ( 

2297 Q(mac_address__icontains=value) | 

2298 Q(description__icontains=value) 

2299 ) 

2300 return queryset.filter(qs_filter) 

2301 

2302 def filter_device(self, queryset, name, value): 

2303 devices = Device.objects.filter(**{f'{name}__in': value}) 

2304 if not devices.exists(): 

2305 return queryset.none() 

2306 interface_ids = [] 

2307 for device in devices: 

2308 interface_ids.extend(device.vc_interfaces().values_list('id', flat=True)) 

2309 return queryset.filter( 

2310 interface__in=interface_ids 

2311 ) 

2312 

2313 def filter_virtual_machine(self, queryset, name, value): 

2314 virtual_machines = VirtualMachine.objects.filter(**{f'{name}__in': value}) 

2315 if not virtual_machines.exists(): 

2316 return queryset.none() 

2317 interface_ids = [] 

2318 for vm in virtual_machines: 

2319 interface_ids.extend(vm.interfaces.values_list('id', flat=True)) 

2320 return queryset.filter( 

2321 vminterface__in=interface_ids 

2322 ) 

2323 

2324 def filter_assigned(self, queryset, name, value): 

2325 params = { 

2326 'assigned_object_type__isnull': True, 

2327 'assigned_object_id__isnull': True, 

2328 } 

2329 if value: 2329 ↛ 2330line 2329 didn't jump to line 2330 because the condition on line 2329 was never true

2330 return queryset.exclude(**params) 

2331 return queryset.filter(**params) 

2332 

2333 def filter_primary(self, queryset, name, value): 

2334 interface_mac_ids = Interface.objects.filter(primary_mac_address_id__isnull=False).values_list( 

2335 'primary_mac_address_id', flat=True 

2336 ) 

2337 vminterface_mac_ids = VMInterface.objects.filter(primary_mac_address_id__isnull=False).values_list( 

2338 'primary_mac_address_id', flat=True 

2339 ) 

2340 query = Q(pk__in=interface_mac_ids) | Q(pk__in=vminterface_mac_ids) 

2341 if value: 

2342 return queryset.filter(query) 

2343 return queryset.exclude(query) 

2344 

2345 

2346class CommonInterfaceFilterSet(django_filters.FilterSet): 

2347 mode = django_filters.MultipleChoiceFilter( 

2348 choices=InterfaceModeChoices, 

2349 distinct=False, 

2350 label=_('802.1Q Mode') 

2351 ) 

2352 vlan_id = django_filters.CharFilter( 

2353 method='filter_vlan_id', 

2354 label=_('Assigned VLAN') 

2355 ) 

2356 vlan = django_filters.CharFilter( 

2357 method='filter_vlan', 

2358 label=_('Assigned VID') 

2359 ) 

2360 vrf_id = django_filters.ModelMultipleChoiceFilter( 

2361 field_name='vrf', 

2362 queryset=VRF.objects.all(), 

2363 distinct=False, 

2364 label=_('VRF'), 

2365 ) 

2366 vrf = django_filters.ModelMultipleChoiceFilter( 

2367 field_name='vrf__rd', 

2368 queryset=VRF.objects.all(), 

2369 distinct=False, 

2370 to_field_name='rd', 

2371 label=_('VRF (RD)'), 

2372 ) 

2373 l2vpn_id = django_filters.ModelMultipleChoiceFilter( 

2374 field_name='l2vpn_terminations__l2vpn', 

2375 queryset=L2VPN.objects.all(), 

2376 label=_('L2VPN (ID)'), 

2377 ) 

2378 l2vpn = django_filters.ModelMultipleChoiceFilter( 

2379 field_name='l2vpn_terminations__l2vpn__identifier', 

2380 queryset=L2VPN.objects.all(), 

2381 to_field_name='identifier', 

2382 label=_('L2VPN'), 

2383 ) 

2384 vlan_translation_policy_id = django_filters.ModelMultipleChoiceFilter( 

2385 field_name='vlan_translation_policy', 

2386 queryset=VLANTranslationPolicy.objects.all(), 

2387 distinct=False, 

2388 label=_('VLAN Translation Policy (ID)'), 

2389 ) 

2390 vlan_translation_policy = django_filters.ModelMultipleChoiceFilter( 

2391 field_name='vlan_translation_policy__name', 

2392 queryset=VLANTranslationPolicy.objects.all(), 

2393 distinct=False, 

2394 to_field_name='name', 

2395 label=_('VLAN Translation Policy'), 

2396 ) 

2397 

2398 def filter_vlan_id(self, queryset, name, value): 

2399 value = value.strip() 

2400 if not value: 

2401 return queryset 

2402 return queryset.filter( 

2403 Q(untagged_vlan_id=value) | 

2404 Q(tagged_vlans=value) | 

2405 Q(qinq_svlan=value) 

2406 ) 

2407 

2408 def filter_vlan(self, queryset, name, value): 

2409 value = value.strip() 

2410 if not value: 

2411 return queryset 

2412 return queryset.filter( 

2413 Q(untagged_vlan_id__vid=value) | 

2414 Q(tagged_vlans__vid=value) | 

2415 Q(qinq_svlan__vid=value) 

2416 ) 

2417 

2418 

2419@register_filterset 

2420class InterfaceFilterSet( 

2421 ModularDeviceComponentFilterSet, 

2422 CabledObjectFilterSet, 

2423 PathEndpointFilterSet, 

2424 CommonInterfaceFilterSet 

2425): 

2426 virtual_chassis_member_or_master = MultiValueCharFilter( 

2427 method='filter_virtual_chassis_member_or_master', 

2428 field_name='name', 

2429 label=_('Virtual Chassis Interfaces for Device when device is master') 

2430 ) 

2431 virtual_chassis_member_or_master_id = MultiValueNumberFilter( 

2432 method='filter_virtual_chassis_member_or_master', 

2433 field_name='pk', 

2434 label=_('Virtual Chassis Interfaces for Device when device is master (ID)') 

2435 ) 

2436 virtual_chassis_member = MultiValueCharFilter( 

2437 method='filter_virtual_chassis_member', 

2438 field_name='name', 

2439 label=_('Virtual Chassis Interfaces for Device') 

2440 ) 

2441 virtual_chassis_member_id = MultiValueNumberFilter( 

2442 method='filter_virtual_chassis_member', 

2443 field_name='pk', 

2444 label=_('Virtual Chassis Interfaces for Device (ID)') 

2445 ) 

2446 kind = django_filters.CharFilter( 

2447 method='filter_kind', 

2448 label=_('Kind of interface'), 

2449 ) 

2450 parent_id = django_filters.ModelMultipleChoiceFilter( 

2451 field_name='parent', 

2452 queryset=Interface.objects.all(), 

2453 distinct=False, 

2454 label=_('Parent interface (ID)'), 

2455 ) 

2456 bridge_id = django_filters.ModelMultipleChoiceFilter( 

2457 field_name='bridge', 

2458 queryset=Interface.objects.all(), 

2459 distinct=False, 

2460 label=_('Bridged interface (ID)'), 

2461 ) 

2462 lag_id = django_filters.ModelMultipleChoiceFilter( 

2463 field_name='lag', 

2464 queryset=Interface.objects.all(), 

2465 distinct=False, 

2466 label=_('LAG interface (ID)'), 

2467 ) 

2468 speed = MultiValueBigNumberFilter(min_value=0) 

2469 duplex = django_filters.MultipleChoiceFilter( 

2470 choices=InterfaceDuplexChoices, 

2471 distinct=False, 

2472 ) 

2473 mac_address = MultiValueMACAddressFilter( 

2474 field_name='mac_addresses__mac_address', 

2475 label=_('MAC Address') 

2476 ) 

2477 primary_mac_address_id = django_filters.ModelMultipleChoiceFilter( 

2478 field_name='primary_mac_address', 

2479 queryset=MACAddress.objects.all(), 

2480 distinct=False, 

2481 label=_('Primary MAC address (ID)'), 

2482 ) 

2483 primary_mac_address = django_filters.ModelMultipleChoiceFilter( 

2484 field_name='primary_mac_address__mac_address', 

2485 queryset=MACAddress.objects.all(), 

2486 distinct=False, 

2487 to_field_name='mac_address', 

2488 label=_('Primary MAC address'), 

2489 ) 

2490 wwn = MultiValueWWNFilter() 

2491 poe_mode = django_filters.MultipleChoiceFilter( 

2492 choices=InterfacePoEModeChoices, 

2493 distinct=False, 

2494 ) 

2495 poe_type = django_filters.MultipleChoiceFilter( 

2496 choices=InterfacePoETypeChoices, 

2497 distinct=False, 

2498 ) 

2499 type = django_filters.MultipleChoiceFilter( 

2500 choices=InterfaceTypeChoices, 

2501 distinct=False, 

2502 null_value=None 

2503 ) 

2504 rf_role = django_filters.MultipleChoiceFilter( 

2505 choices=WirelessRoleChoices, 

2506 distinct=False, 

2507 ) 

2508 rf_channel = django_filters.MultipleChoiceFilter( 

2509 choices=WirelessChannelChoices, 

2510 distinct=False, 

2511 ) 

2512 vdc_id = django_filters.ModelMultipleChoiceFilter( 

2513 field_name='vdcs', 

2514 queryset=VirtualDeviceContext.objects.all(), 

2515 label=_('Virtual Device Context') 

2516 ) 

2517 vdc_identifier = django_filters.ModelMultipleChoiceFilter( 

2518 field_name='vdcs__identifier', 

2519 queryset=VirtualDeviceContext.objects.all(), 

2520 to_field_name='identifier', 

2521 label=_('Virtual Device Context (Identifier)') 

2522 ) 

2523 vdc = django_filters.ModelMultipleChoiceFilter( 

2524 field_name='vdcs__name', 

2525 queryset=VirtualDeviceContext.objects.all(), 

2526 to_field_name='name', 

2527 label=_('Virtual Device Context') 

2528 ) 

2529 wireless_lan_id = django_filters.ModelMultipleChoiceFilter( 

2530 field_name='wireless_lans', 

2531 queryset=WirelessLAN.objects.all(), 

2532 label=_('Wireless LAN') 

2533 ) 

2534 wireless_link_id = django_filters.ModelMultipleChoiceFilter( 

2535 queryset=WirelessLink.objects.all(), 

2536 distinct=False, 

2537 label=_('Wireless link') 

2538 ) 

2539 virtual_circuit_id = django_filters.ModelMultipleChoiceFilter( 

2540 field_name='virtual_circuit_termination__virtual_circuit', 

2541 queryset=VirtualCircuit.objects.all(), 

2542 label=_('Virtual circuit (ID)'), 

2543 ) 

2544 virtual_circuit_termination_id = django_filters.ModelMultipleChoiceFilter( 

2545 field_name='virtual_circuit_termination', 

2546 queryset=VirtualCircuitTermination.objects.all(), 

2547 label=_('Virtual circuit termination (ID)'), 

2548 ) 

2549 

2550 class Meta: 

2551 model = Interface 

2552 fields = ( 

2553 'id', 'name', 'label', 'type', 'channels', 'channel_id', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 

2554 'poe_type', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 

2555 'description', 'mark_connected', 'cable_id', 'cable_end', 'cable_connector', 

2556 ) 

2557 

2558 def filter_virtual_chassis_member_or_master(self, queryset, name, value): 

2559 return self.filter_virtual_chassis_member(queryset, name, value, if_master=True) 

2560 

2561 def filter_virtual_chassis_member(self, queryset, name, value, if_master=False): 

2562 try: 

2563 vc_interface_ids = [] 

2564 for device in Device.objects.filter(**{f'{name}__in': value}): 

2565 vc_interface_ids.extend(device.vc_interfaces(if_master=if_master).values_list('id', flat=True)) 

2566 return queryset.filter(pk__in=vc_interface_ids) 

2567 except Device.DoesNotExist: 

2568 return queryset.none() 

2569 

2570 def filter_kind(self, queryset, name, value): 

2571 value = value.strip().lower() 

2572 return { 

2573 # A channel subinterface is excluded even if its type is otherwise connectable: it derives its cable 

2574 # from its channelized parent and cannot be cabled directly (matches Interface.is_wired). 

2575 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES).filter(channel_id__isnull=True), 

2576 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES), 

2577 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES), 

2578 }.get(value, queryset.none()) 

2579 

2580 # Override the method on CabledObjectFilterSet to also check for wireless links 

2581 def filter_occupied(self, queryset, name, value): 

2582 if value: 

2583 return queryset.filter( 

2584 Q(cable__isnull=False) | 

2585 Q(wireless_link__isnull=False) | 

2586 Q(mark_connected=True) 

2587 ) 

2588 return queryset.filter( 

2589 cable__isnull=True, 

2590 wireless_link__isnull=True, 

2591 mark_connected=False 

2592 ) 

2593 

2594 

2595@register_filterset 

2596class FrontPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet): 

2597 type = django_filters.MultipleChoiceFilter( 

2598 choices=PortTypeChoices, 

2599 distinct=False, 

2600 null_value=None 

2601 ) 

2602 rear_port_id = django_filters.ModelMultipleChoiceFilter( 

2603 field_name='mappings__rear_port', 

2604 queryset=RearPort.objects.all(), 

2605 to_field_name='rear_port', 

2606 label=_('Rear port (ID)'), 

2607 ) 

2608 

2609 class Meta: 

2610 model = FrontPort 

2611 fields = ( 

2612 'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end', 

2613 'cable_connector', 

2614 ) 

2615 

2616 

2617@register_filterset 

2618class RearPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet): 

2619 type = django_filters.MultipleChoiceFilter( 

2620 choices=PortTypeChoices, 

2621 distinct=False, 

2622 null_value=None 

2623 ) 

2624 front_port_id = django_filters.ModelMultipleChoiceFilter( 

2625 field_name='mappings__front_port', 

2626 queryset=FrontPort.objects.all(), 

2627 to_field_name='front_port', 

2628 label=_('Front port (ID)'), 

2629 ) 

2630 

2631 class Meta: 

2632 model = RearPort 

2633 fields = ( 

2634 'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end', 

2635 'cable_connector', 

2636 ) 

2637 

2638 

2639@register_filterset 

2640class ModuleBayFilterSet(ModularDeviceComponentFilterSet): 

2641 parent_id = django_filters.ModelMultipleChoiceFilter( 

2642 queryset=ModuleBay.objects.all(), 

2643 distinct=False, 

2644 label=_('Parent module bay (ID)'), 

2645 ) 

2646 installed_module_id = django_filters.ModelMultipleChoiceFilter( 

2647 field_name='installed_module', 

2648 queryset=ModuleBay.objects.all(), 

2649 label=_('Installed module (ID)'), 

2650 ) 

2651 module_bay_type_id = django_filters.ModelMultipleChoiceFilter( 

2652 field_name='module_bay_types', 

2653 queryset=ModuleBayType.objects.all(), 

2654 distinct=False, 

2655 label=_('Module bay type (ID)'), 

2656 ) 

2657 module_bay_type = django_filters.ModelMultipleChoiceFilter( 

2658 field_name='module_bay_types__slug', 

2659 queryset=ModuleBayType.objects.all(), 

2660 distinct=False, 

2661 to_field_name='slug', 

2662 label=_('Module bay type (slug)'), 

2663 ) 

2664 

2665 class Meta: 

2666 model = ModuleBay 

2667 fields = ('id', 'name', 'label', 'position', 'enabled', 'description') 

2668 

2669 

2670@register_filterset 

2671class DeviceBayFilterSet(DeviceComponentFilterSet): 

2672 installed_device_id = django_filters.ModelMultipleChoiceFilter( 

2673 queryset=Device.objects.all(), 

2674 distinct=False, 

2675 label=_('Installed device (ID)'), 

2676 ) 

2677 installed_device = django_filters.ModelMultipleChoiceFilter( 

2678 field_name='installed_device__name', 

2679 queryset=Device.objects.all(), 

2680 distinct=False, 

2681 to_field_name='name', 

2682 label=_('Installed device (name)'), 

2683 ) 

2684 

2685 class Meta: 

2686 model = DeviceBay 

2687 fields = ('id', 'name', 'label', 'enabled', 'description') 

2688 

2689 

2690@register_filterset 

2691class InventoryItemFilterSet(DeviceComponentFilterSet): 

2692 parent_id = django_filters.ModelMultipleChoiceFilter( 

2693 queryset=InventoryItem.objects.all(), 

2694 distinct=False, 

2695 label=_('Parent inventory item (ID)'), 

2696 ) 

2697 manufacturer_id = django_filters.ModelMultipleChoiceFilter( 

2698 queryset=Manufacturer.objects.all(), 

2699 distinct=False, 

2700 label=_('Manufacturer (ID)'), 

2701 ) 

2702 manufacturer = django_filters.ModelMultipleChoiceFilter( 

2703 field_name='manufacturer__slug', 

2704 queryset=Manufacturer.objects.all(), 

2705 distinct=False, 

2706 to_field_name='slug', 

2707 label=_('Manufacturer (slug)'), 

2708 ) 

2709 role_id = django_filters.ModelMultipleChoiceFilter( 

2710 queryset=InventoryItemRole.objects.all(), 

2711 distinct=False, 

2712 label=_('Role (ID)'), 

2713 ) 

2714 role = django_filters.ModelMultipleChoiceFilter( 

2715 field_name='role__slug', 

2716 queryset=InventoryItemRole.objects.all(), 

2717 distinct=False, 

2718 to_field_name='slug', 

2719 label=_('Role (slug)'), 

2720 ) 

2721 component_type = MultiValueContentTypeFilter() 

2722 component_id = MultiValueNumberFilter() 

2723 serial = MultiValueCharFilter( 

2724 lookup_expr='iexact' 

2725 ) 

2726 status = django_filters.MultipleChoiceFilter( 

2727 choices=InventoryItemStatusChoices, 

2728 distinct=False, 

2729 null_value=None 

2730 ) 

2731 

2732 class Meta: 

2733 model = InventoryItem 

2734 fields = ('id', 'name', 'label', 'part_id', 'asset_tag', 'status', 'description', 'discovered') 

2735 

2736 def search(self, queryset, name, value): 

2737 if not value.strip(): 

2738 return queryset 

2739 qs_filter = ( 

2740 Q(name__icontains=value) | 

2741 Q(part_id__icontains=value) | 

2742 Q(serial__icontains=value) | 

2743 Q(asset_tag__icontains=value) | 

2744 Q(description__icontains=value) 

2745 ) 

2746 return queryset.filter(qs_filter) 

2747 

2748 

2749@register_filterset 

2750class InventoryItemRoleFilterSet(OrganizationalModelFilterSet): 

2751 

2752 class Meta: 

2753 model = InventoryItemRole 

2754 fields = ('id', 'name', 'slug', 'color', 'description') 

2755 

2756 

2757@register_filterset 

2758class VirtualChassisFilterSet(PrimaryModelFilterSet): 

2759 master_id = django_filters.ModelMultipleChoiceFilter( 

2760 queryset=Device.objects.all(), 

2761 distinct=False, 

2762 label=_('Master (ID)'), 

2763 ) 

2764 master = django_filters.ModelMultipleChoiceFilter( 

2765 field_name='master__name', 

2766 queryset=Device.objects.all(), 

2767 distinct=False, 

2768 to_field_name='name', 

2769 label=_('Master (name)'), 

2770 ) 

2771 region_id = TreeNodeMultipleChoiceFilter( 

2772 queryset=Region.objects.all(), 

2773 field_name='master__site__region', 

2774 lookup_expr='in', 

2775 label=_('Region (ID)'), 

2776 ) 

2777 region = TreeNodeMultipleChoiceFilter( 

2778 queryset=Region.objects.all(), 

2779 field_name='master__site__region', 

2780 lookup_expr='in', 

2781 to_field_name='slug', 

2782 label=_('Region (slug)'), 

2783 ) 

2784 site_group_id = TreeNodeMultipleChoiceFilter( 

2785 queryset=SiteGroup.objects.all(), 

2786 field_name='master__site__group', 

2787 lookup_expr='in', 

2788 label=_('Site group (ID)'), 

2789 ) 

2790 site_group = TreeNodeMultipleChoiceFilter( 

2791 queryset=SiteGroup.objects.all(), 

2792 field_name='master__site__group', 

2793 lookup_expr='in', 

2794 to_field_name='slug', 

2795 label=_('Site group (slug)'), 

2796 ) 

2797 site_id = django_filters.ModelMultipleChoiceFilter( 

2798 field_name='master__site', 

2799 queryset=Site.objects.all(), 

2800 distinct=False, 

2801 label=_('Site (ID)'), 

2802 ) 

2803 site = django_filters.ModelMultipleChoiceFilter( 

2804 field_name='master__site__slug', 

2805 queryset=Site.objects.all(), 

2806 distinct=False, 

2807 to_field_name='slug', 

2808 label=_('Site name (slug)'), 

2809 ) 

2810 tenant_id = django_filters.ModelMultipleChoiceFilter( 

2811 field_name='master__tenant', 

2812 queryset=Tenant.objects.all(), 

2813 distinct=False, 

2814 label=_('Tenant (ID)'), 

2815 ) 

2816 tenant = django_filters.ModelMultipleChoiceFilter( 

2817 field_name='master__tenant__slug', 

2818 queryset=Tenant.objects.all(), 

2819 distinct=False, 

2820 to_field_name='slug', 

2821 label=_('Tenant (slug)'), 

2822 ) 

2823 

2824 class Meta: 

2825 model = VirtualChassis 

2826 fields = ('id', 'domain', 'name', 'description', 'member_count') 

2827 

2828 def search(self, queryset, name, value): 

2829 if not value.strip(): 

2830 return queryset 

2831 qs_filter = ( 

2832 Q(name__icontains=value) | 

2833 Q(description__icontains=value) | 

2834 Q(members__name__icontains=value) | 

2835 Q(domain__icontains=value) 

2836 ) 

2837 return queryset.filter(qs_filter).distinct() 

2838 

2839 

2840@register_filterset 

2841class CableBundleFilterSet(PrimaryModelFilterSet): 

2842 

2843 class Meta: 

2844 model = CableBundle 

2845 fields = ('id', 'name', 'description') 

2846 

2847 def search(self, queryset, name, value): 

2848 if not value.strip(): 

2849 return queryset 

2850 return queryset.filter( 

2851 Q(name__icontains=value) | 

2852 Q(description__icontains=value) | 

2853 Q(comments__icontains=value) 

2854 ) 

2855 

2856 

2857@register_filterset 

2858class CableFilterSet(TenancyFilterSet, PrimaryModelFilterSet): 

2859 termination_a_type = MultiValueContentTypeFilter( 

2860 field_name='terminations__termination_type' 

2861 ) 

2862 termination_a_id = MultiValueNumberFilter( 

2863 method='filter_by_cable_end_a', 

2864 field_name='terminations__termination_id' 

2865 ) 

2866 termination_b_type = MultiValueContentTypeFilter( 

2867 field_name='terminations__termination_type' 

2868 ) 

2869 termination_b_id = MultiValueNumberFilter( 

2870 method='filter_by_cable_end_b', 

2871 field_name='terminations__termination_id' 

2872 ) 

2873 unterminated = django_filters.BooleanFilter( 

2874 method='_unterminated', 

2875 label=_('Unterminated'), 

2876 ) 

2877 bundle_id = django_filters.ModelMultipleChoiceFilter( 

2878 queryset=CableBundle.objects.all(), 

2879 label=_('Cable bundle (ID)'), 

2880 ) 

2881 bundle = django_filters.ModelMultipleChoiceFilter( 

2882 field_name='bundle__name', 

2883 queryset=CableBundle.objects.all(), 

2884 to_field_name='name', 

2885 label=_('Cable bundle (name)'), 

2886 ) 

2887 type = django_filters.MultipleChoiceFilter( 

2888 choices=CableTypeChoices, 

2889 distinct=False, 

2890 ) 

2891 status = django_filters.MultipleChoiceFilter( 

2892 choices=LinkStatusChoices, 

2893 distinct=False, 

2894 ) 

2895 profile = django_filters.MultipleChoiceFilter( 

2896 choices=CableProfileChoices, 

2897 distinct=False, 

2898 ) 

2899 color = django_filters.MultipleChoiceFilter( 

2900 choices=ColorChoices, 

2901 distinct=False, 

2902 ) 

2903 device_id = MultiValueNumberFilter( 

2904 method='filter_by_termination' 

2905 ) 

2906 device = MultiValueCharFilter( 

2907 method='filter_by_termination', 

2908 field_name='device__name' 

2909 ) 

2910 rack_id = MultiValueNumberFilter( 

2911 method='filter_by_termination', 

2912 field_name='rack_id' 

2913 ) 

2914 rack = MultiValueCharFilter( 

2915 method='filter_by_termination', 

2916 field_name='rack__name' 

2917 ) 

2918 location_id = MultiValueNumberFilter( 

2919 method='filter_by_termination', 

2920 field_name='location_id' 

2921 ) 

2922 location = MultiValueCharFilter( 

2923 method='filter_by_termination', 

2924 field_name='location__name' 

2925 ) 

2926 site_id = MultiValueNumberFilter( 

2927 method='filter_by_termination', 

2928 field_name='site_id' 

2929 ) 

2930 site = MultiValueCharFilter( 

2931 method='filter_by_termination', 

2932 field_name='site__slug' 

2933 ) 

2934 

2935 # Termination object filters 

2936 consoleport_id = MultiValueNumberFilter( 

2937 method='filter_by_consoleport' 

2938 ) 

2939 consoleserverport_id = MultiValueNumberFilter( 

2940 method='filter_by_consoleserverport' 

2941 ) 

2942 powerport_id = MultiValueNumberFilter( 

2943 method='filter_by_powerport' 

2944 ) 

2945 poweroutlet_id = MultiValueNumberFilter( 

2946 method='filter_by_poweroutlet' 

2947 ) 

2948 interface_id = MultiValueNumberFilter( 

2949 method='filter_by_interface' 

2950 ) 

2951 frontport_id = MultiValueNumberFilter( 

2952 method='filter_by_frontport' 

2953 ) 

2954 rearport_id = MultiValueNumberFilter( 

2955 method='filter_by_rearport' 

2956 ) 

2957 powerfeed_id = MultiValueNumberFilter( 

2958 method='filter_by_powerfeed' 

2959 ) 

2960 circuittermination_id = MultiValueNumberFilter( 

2961 method='filter_by_circuittermination' 

2962 ) 

2963 

2964 class Meta: 

2965 model = Cable 

2966 fields = ('id', 'label', 'length', 'length_unit', 'description') 

2967 

2968 def search(self, queryset, name, value): 

2969 if not value.strip(): 

2970 return queryset 

2971 qs_filter = ( 

2972 Q(label__icontains=value) | 

2973 Q(description__icontains=value) 

2974 ) 

2975 return queryset.filter(qs_filter) 

2976 

2977 def filter_by_termination(self, queryset, name, value): 

2978 # Filter by a related object cached on CableTermination. Note the underscore preceding the field name. 

2979 # Supported objects: device, rack, location, site 

2980 return queryset.filter(**{f'terminations___{name}__in': value}).distinct() 

2981 

2982 def filter_by_cable_end(self, queryset, name, value, side): 

2983 # Filter by termination id and cable_end type 

2984 return queryset.filter(**{f'{name}__in': value, 'terminations__cable_end': side}).distinct() 

2985 

2986 def filter_by_cable_end_a(self, queryset, name, value): 

2987 # Filter by termination id and cable_end type 

2988 return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_A) 

2989 

2990 def filter_by_cable_end_b(self, queryset, name, value): 

2991 # Filter by termination id and cable_end type 

2992 return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_B) 

2993 

2994 def _unterminated(self, queryset, name, value): 

2995 if value: 

2996 terminated_ids = ( 

2997 queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A) 

2998 .filter(terminations__cable_end=CableEndChoices.SIDE_B) 

2999 .values("id") 

3000 ) 

3001 return queryset.exclude(id__in=terminated_ids) 

3002 return queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A).filter( 

3003 terminations__cable_end=CableEndChoices.SIDE_B 

3004 ) 

3005 

3006 def filter_by_termination_object(self, queryset, model, value): 

3007 # Filter by specific termination object(s) 

3008 content_type = ContentType.objects.get_for_model(model) 

3009 cable_ids = CableTermination.objects.filter( 

3010 termination_type=content_type, 

3011 termination_id__in=value 

3012 ).values_list('cable', flat=True) 

3013 return queryset.filter(pk__in=cable_ids) 

3014 

3015 def filter_by_consoleport(self, queryset, name, value): 

3016 return self.filter_by_termination_object(queryset, ConsolePort, value) 

3017 

3018 def filter_by_consoleserverport(self, queryset, name, value): 

3019 return self.filter_by_termination_object(queryset, ConsoleServerPort, value) 

3020 

3021 def filter_by_powerport(self, queryset, name, value): 

3022 return self.filter_by_termination_object(queryset, PowerPort, value) 

3023 

3024 def filter_by_poweroutlet(self, queryset, name, value): 

3025 return self.filter_by_termination_object(queryset, PowerOutlet, value) 

3026 

3027 def filter_by_interface(self, queryset, name, value): 

3028 return self.filter_by_termination_object(queryset, Interface, value) 

3029 

3030 def filter_by_frontport(self, queryset, name, value): 

3031 return self.filter_by_termination_object(queryset, FrontPort, value) 

3032 

3033 def filter_by_rearport(self, queryset, name, value): 

3034 return self.filter_by_termination_object(queryset, RearPort, value) 

3035 

3036 def filter_by_powerfeed(self, queryset, name, value): 

3037 return self.filter_by_termination_object(queryset, PowerFeed, value) 

3038 

3039 def filter_by_circuittermination(self, queryset, name, value): 

3040 return self.filter_by_termination_object(queryset, CircuitTermination, value) 

3041 

3042 

3043@register_filterset 

3044class CableTerminationFilterSet(ChangeLoggedModelFilterSet): 

3045 cable_id = django_filters.ModelMultipleChoiceFilter( 

3046 queryset=Cable.objects.all(), 

3047 distinct=False, 

3048 label=_('Cable (ID)'), 

3049 ) 

3050 termination_type = MultiValueContentTypeFilter() 

3051 

3052 # Termination object filters 

3053 consoleport_id = MultiValueNumberFilter( 

3054 method='filter_by_consoleport' 

3055 ) 

3056 consoleserverport_id = MultiValueNumberFilter( 

3057 method='filter_by_consoleserverport' 

3058 ) 

3059 powerport_id = MultiValueNumberFilter( 

3060 method='filter_by_powerport' 

3061 ) 

3062 poweroutlet_id = MultiValueNumberFilter( 

3063 method='filter_by_poweroutlet' 

3064 ) 

3065 interface_id = MultiValueNumberFilter( 

3066 method='filter_by_interface' 

3067 ) 

3068 frontport_id = MultiValueNumberFilter( 

3069 method='filter_by_frontport' 

3070 ) 

3071 rearport_id = MultiValueNumberFilter( 

3072 method='filter_by_rearport' 

3073 ) 

3074 powerfeed_id = MultiValueNumberFilter( 

3075 method='filter_by_powerfeed' 

3076 ) 

3077 circuittermination_id = MultiValueNumberFilter( 

3078 method='filter_by_circuittermination' 

3079 ) 

3080 

3081 class Meta: 

3082 model = CableTermination 

3083 fields = ('id', 'cable', 'cable_end', 'termination_type', 'termination_id') 

3084 

3085 def filter_by_termination_object(self, queryset, model, value): 

3086 content_type = ContentType.objects.get_for_model(model) 

3087 return queryset.filter(termination_type=content_type, termination_id__in=value) 

3088 

3089 def filter_by_consoleport(self, queryset, name, value): 

3090 return self.filter_by_termination_object(queryset, ConsolePort, value) 

3091 

3092 def filter_by_consoleserverport(self, queryset, name, value): 

3093 return self.filter_by_termination_object(queryset, ConsoleServerPort, value) 

3094 

3095 def filter_by_powerport(self, queryset, name, value): 

3096 return self.filter_by_termination_object(queryset, PowerPort, value) 

3097 

3098 def filter_by_poweroutlet(self, queryset, name, value): 

3099 return self.filter_by_termination_object(queryset, PowerOutlet, value) 

3100 

3101 def filter_by_interface(self, queryset, name, value): 

3102 return self.filter_by_termination_object(queryset, Interface, value) 

3103 

3104 def filter_by_frontport(self, queryset, name, value): 

3105 return self.filter_by_termination_object(queryset, FrontPort, value) 

3106 

3107 def filter_by_rearport(self, queryset, name, value): 

3108 return self.filter_by_termination_object(queryset, RearPort, value) 

3109 

3110 def filter_by_powerfeed(self, queryset, name, value): 

3111 return self.filter_by_termination_object(queryset, PowerFeed, value) 

3112 

3113 def filter_by_circuittermination(self, queryset, name, value): 

3114 return self.filter_by_termination_object(queryset, CircuitTermination, value) 

3115 

3116 

3117@register_filterset 

3118class PowerPanelFilterSet(PrimaryModelFilterSet, ContactModelFilterSet): 

3119 region_id = TreeNodeMultipleChoiceFilter( 

3120 queryset=Region.objects.all(), 

3121 field_name='site__region', 

3122 lookup_expr='in', 

3123 label=_('Region (ID)'), 

3124 ) 

3125 region = TreeNodeMultipleChoiceFilter( 

3126 queryset=Region.objects.all(), 

3127 field_name='site__region', 

3128 lookup_expr='in', 

3129 to_field_name='slug', 

3130 label=_('Region (slug)'), 

3131 ) 

3132 site_group_id = TreeNodeMultipleChoiceFilter( 

3133 queryset=SiteGroup.objects.all(), 

3134 field_name='site__group', 

3135 lookup_expr='in', 

3136 label=_('Site group (ID)'), 

3137 ) 

3138 site_group = TreeNodeMultipleChoiceFilter( 

3139 queryset=SiteGroup.objects.all(), 

3140 field_name='site__group', 

3141 lookup_expr='in', 

3142 to_field_name='slug', 

3143 label=_('Site group (slug)'), 

3144 ) 

3145 site_id = django_filters.ModelMultipleChoiceFilter( 

3146 queryset=Site.objects.all(), 

3147 distinct=False, 

3148 label=_('Site (ID)'), 

3149 ) 

3150 site = django_filters.ModelMultipleChoiceFilter( 

3151 field_name='site__slug', 

3152 queryset=Site.objects.all(), 

3153 distinct=False, 

3154 to_field_name='slug', 

3155 label=_('Site name (slug)'), 

3156 ) 

3157 location_id = TreeNodeMultipleChoiceFilter( 

3158 queryset=Location.objects.all(), 

3159 field_name='location', 

3160 lookup_expr='in', 

3161 label=_('Location (ID)'), 

3162 ) 

3163 

3164 class Meta: 

3165 model = PowerPanel 

3166 fields = ('id', 'name', 'description') 

3167 

3168 def search(self, queryset, name, value): 

3169 if not value.strip(): 

3170 return queryset 

3171 qs_filter = ( 

3172 Q(name__icontains=value) | 

3173 Q(description__icontains=value) 

3174 ) 

3175 return queryset.filter(qs_filter) 

3176 

3177 

3178@register_filterset 

3179class PowerFeedFilterSet(PrimaryModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, TenancyFilterSet): 

3180 region_id = TreeNodeMultipleChoiceFilter( 

3181 queryset=Region.objects.all(), 

3182 field_name='power_panel__site__region', 

3183 lookup_expr='in', 

3184 label=_('Region (ID)'), 

3185 ) 

3186 region = TreeNodeMultipleChoiceFilter( 

3187 queryset=Region.objects.all(), 

3188 field_name='power_panel__site__region', 

3189 lookup_expr='in', 

3190 to_field_name='slug', 

3191 label=_('Region (slug)'), 

3192 ) 

3193 site_group_id = TreeNodeMultipleChoiceFilter( 

3194 queryset=SiteGroup.objects.all(), 

3195 field_name='power_panel__site__group', 

3196 lookup_expr='in', 

3197 label=_('Site group (ID)'), 

3198 ) 

3199 site_group = TreeNodeMultipleChoiceFilter( 

3200 queryset=SiteGroup.objects.all(), 

3201 field_name='power_panel__site__group', 

3202 lookup_expr='in', 

3203 to_field_name='slug', 

3204 label=_('Site group (slug)'), 

3205 ) 

3206 site_id = django_filters.ModelMultipleChoiceFilter( 

3207 field_name='power_panel__site', 

3208 queryset=Site.objects.all(), 

3209 distinct=False, 

3210 label=_('Site (ID)'), 

3211 ) 

3212 site = django_filters.ModelMultipleChoiceFilter( 

3213 field_name='power_panel__site__slug', 

3214 queryset=Site.objects.all(), 

3215 distinct=False, 

3216 to_field_name='slug', 

3217 label=_('Site name (slug)'), 

3218 ) 

3219 power_panel_id = django_filters.ModelMultipleChoiceFilter( 

3220 queryset=PowerPanel.objects.all(), 

3221 distinct=False, 

3222 label=_('Power panel (ID)'), 

3223 ) 

3224 rack_id = django_filters.ModelMultipleChoiceFilter( 

3225 field_name='rack', 

3226 queryset=Rack.objects.all(), 

3227 distinct=False, 

3228 label=_('Rack (ID)'), 

3229 ) 

3230 status = django_filters.MultipleChoiceFilter( 

3231 choices=PowerFeedStatusChoices, 

3232 distinct=False, 

3233 null_value=None 

3234 ) 

3235 

3236 class Meta: 

3237 model = PowerFeed 

3238 fields = ( 

3239 'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 

3240 'available_power', 'mark_connected', 'cable_end', 'cable_connector', 'description', 

3241 ) 

3242 

3243 def search(self, queryset, name, value): 

3244 if not value.strip(): 

3245 return queryset 

3246 qs_filter = ( 

3247 Q(name__icontains=value) | 

3248 Q(description__icontains=value) | 

3249 Q(power_panel__name__icontains=value) | 

3250 Q(comments__icontains=value) 

3251 ) 

3252 return queryset.filter(qs_filter) 

3253 

3254 

3255@register_filterset 

3256class CoolingSourceFilterSet(PrimaryModelFilterSet, ContactModelFilterSet): 

3257 region_id = TreeNodeMultipleChoiceFilter( 

3258 queryset=Region.objects.all(), 

3259 field_name='site__region', 

3260 lookup_expr='in', 

3261 label=_('Region (ID)'), 

3262 ) 

3263 region = TreeNodeMultipleChoiceFilter( 

3264 queryset=Region.objects.all(), 

3265 field_name='site__region', 

3266 lookup_expr='in', 

3267 to_field_name='slug', 

3268 label=_('Region (slug)'), 

3269 ) 

3270 site_group_id = TreeNodeMultipleChoiceFilter( 

3271 queryset=SiteGroup.objects.all(), 

3272 field_name='site__group', 

3273 lookup_expr='in', 

3274 label=_('Site group (ID)'), 

3275 ) 

3276 site_group = TreeNodeMultipleChoiceFilter( 

3277 queryset=SiteGroup.objects.all(), 

3278 field_name='site__group', 

3279 lookup_expr='in', 

3280 to_field_name='slug', 

3281 label=_('Site group (slug)'), 

3282 ) 

3283 site_id = django_filters.ModelMultipleChoiceFilter( 

3284 queryset=Site.objects.all(), 

3285 distinct=False, 

3286 label=_('Site (ID)'), 

3287 ) 

3288 site = django_filters.ModelMultipleChoiceFilter( 

3289 field_name='site__slug', 

3290 queryset=Site.objects.all(), 

3291 distinct=False, 

3292 to_field_name='slug', 

3293 label=_('Site name (slug)'), 

3294 ) 

3295 location_id = TreeNodeMultipleChoiceFilter( 

3296 queryset=Location.objects.all(), 

3297 field_name='location', 

3298 lookup_expr='in', 

3299 label=_('Location (ID)'), 

3300 ) 

3301 location = TreeNodeMultipleChoiceFilter( 

3302 queryset=Location.objects.all(), 

3303 field_name='location', 

3304 lookup_expr='in', 

3305 to_field_name='slug', 

3306 label=_('Location (slug)'), 

3307 ) 

3308 type = django_filters.MultipleChoiceFilter( 

3309 choices=CoolingSourceTypeChoices, 

3310 distinct=False, 

3311 null_value=None 

3312 ) 

3313 status = django_filters.MultipleChoiceFilter( 

3314 choices=CoolingSourceStatusChoices, 

3315 distinct=False, 

3316 null_value=None 

3317 ) 

3318 fluid_type = django_filters.MultipleChoiceFilter( 

3319 choices=FluidTypeChoices, 

3320 distinct=False, 

3321 null_value=None 

3322 ) 

3323 

3324 class Meta: 

3325 model = CoolingSource 

3326 fields = ( 

3327 'id', 'name', 'cooling_capacity', 'description', 

3328 ) 

3329 

3330 def search(self, queryset, name, value): 

3331 if not value.strip(): 

3332 return queryset 

3333 qs_filter = ( 

3334 Q(name__icontains=value) | 

3335 Q(description__icontains=value) | 

3336 Q(comments__icontains=value) 

3337 ) 

3338 return queryset.filter(qs_filter) 

3339 

3340 

3341@register_filterset 

3342class CoolingFeedFilterSet(PrimaryModelFilterSet, TenancyFilterSet): 

3343 region_id = TreeNodeMultipleChoiceFilter( 

3344 queryset=Region.objects.all(), 

3345 field_name='cooling_source__site__region', 

3346 lookup_expr='in', 

3347 label=_('Region (ID)'), 

3348 ) 

3349 region = TreeNodeMultipleChoiceFilter( 

3350 queryset=Region.objects.all(), 

3351 field_name='cooling_source__site__region', 

3352 lookup_expr='in', 

3353 to_field_name='slug', 

3354 label=_('Region (slug)'), 

3355 ) 

3356 site_group_id = TreeNodeMultipleChoiceFilter( 

3357 queryset=SiteGroup.objects.all(), 

3358 field_name='cooling_source__site__group', 

3359 lookup_expr='in', 

3360 label=_('Site group (ID)'), 

3361 ) 

3362 site_group = TreeNodeMultipleChoiceFilter( 

3363 queryset=SiteGroup.objects.all(), 

3364 field_name='cooling_source__site__group', 

3365 lookup_expr='in', 

3366 to_field_name='slug', 

3367 label=_('Site group (slug)'), 

3368 ) 

3369 site_id = django_filters.ModelMultipleChoiceFilter( 

3370 field_name='cooling_source__site', 

3371 queryset=Site.objects.all(), 

3372 distinct=False, 

3373 label=_('Site (ID)'), 

3374 ) 

3375 site = django_filters.ModelMultipleChoiceFilter( 

3376 field_name='cooling_source__site__slug', 

3377 queryset=Site.objects.all(), 

3378 distinct=False, 

3379 to_field_name='slug', 

3380 label=_('Site name (slug)'), 

3381 ) 

3382 cooling_source_id = django_filters.ModelMultipleChoiceFilter( 

3383 queryset=CoolingSource.objects.all(), 

3384 distinct=False, 

3385 label=_('Cooling source (ID)'), 

3386 ) 

3387 rack_id = django_filters.ModelMultipleChoiceFilter( 

3388 field_name='rack', 

3389 queryset=Rack.objects.all(), 

3390 distinct=False, 

3391 label=_('Rack (ID)'), 

3392 ) 

3393 status = django_filters.MultipleChoiceFilter( 

3394 choices=CoolingFeedStatusChoices, 

3395 distinct=False, 

3396 null_value=None 

3397 ) 

3398 max_flow_unit = django_filters.MultipleChoiceFilter( 

3399 choices=FlowRateUnitChoices, 

3400 distinct=False, 

3401 null_value=None 

3402 ) 

3403 

3404 class Meta: 

3405 model = CoolingFeed 

3406 fields = ( 

3407 'id', 'name', 'cooling_capacity', 'max_flow', 'description', 

3408 ) 

3409 

3410 def search(self, queryset, name, value): 

3411 if not value.strip(): 

3412 return queryset 

3413 qs_filter = ( 

3414 Q(name__icontains=value) | 

3415 Q(description__icontains=value) | 

3416 Q(cooling_source__name__icontains=value) | 

3417 Q(comments__icontains=value) 

3418 ) 

3419 return queryset.filter(qs_filter) 

3420 

3421 

3422# 

3423# Connection filter sets 

3424# 

3425 

3426class ConnectionFilterSet(BaseFilterSet): 

3427 q = django_filters.CharFilter( 

3428 method='search', 

3429 label=_('Search'), 

3430 ) 

3431 site_id = MultiValueNumberFilter( 

3432 method='filter_connections', 

3433 field_name='device__site_id' 

3434 ) 

3435 site = MultiValueCharFilter( 

3436 method='filter_connections', 

3437 field_name='device__site__slug' 

3438 ) 

3439 device_id = MultiValueNumberFilter( 

3440 method='filter_connections', 

3441 field_name='device_id' 

3442 ) 

3443 device = MultiValueCharFilter( 

3444 method='filter_connections', 

3445 field_name='device__name' 

3446 ) 

3447 

3448 def filter_connections(self, queryset, name, value): 

3449 if not value: 

3450 return queryset 

3451 return queryset.filter(**{f'{name}__in': value}) 

3452 

3453 def search(self, queryset, name, value): 

3454 if not value.strip(): 

3455 return queryset 

3456 qs_filter = ( 

3457 Q(device__name__icontains=value) | 

3458 Q(cable__label__icontains=value) 

3459 ) 

3460 return queryset.filter(qs_filter) 

3461 

3462 

3463class ConsoleConnectionFilterSet(ConnectionFilterSet): 

3464 

3465 class Meta: 

3466 model = ConsolePort 

3467 fields = ('name',) 

3468 

3469 

3470class PowerConnectionFilterSet(ConnectionFilterSet): 

3471 

3472 class Meta: 

3473 model = PowerPort 

3474 fields = ('name',) 

3475 

3476 

3477class InterfaceConnectionFilterSet(ConnectionFilterSet): 

3478 

3479 class Meta: 

3480 model = Interface 

3481 fields = tuple()