Coverage for circuits/filtersets.py: 72%

189 statements  

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

1import django_filters 

2from django.contrib.contenttypes.models import ContentType 

3from django.db.models import Q 

4from django.utils.translation import gettext as _ 

5 

6from dcim.filtersets import CabledObjectFilterSet 

7from dcim.models import Interface, Location, Region, Site, SiteGroup 

8from ipam.models import ASN 

9from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet 

10from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet 

11from utilities.filters import ( 

12 MultiValueCharFilter, 

13 MultiValueContentTypeFilter, 

14 MultiValueNumberFilter, 

15 TreeNodeMultipleChoiceFilter, 

16) 

17from utilities.filtersets import register_filterset 

18 

19from .choices import * 

20from .models import * 

21 

22__all__ = ( 

23 'CircuitFilterSet', 

24 'CircuitGroupAssignmentFilterSet', 

25 'CircuitGroupFilterSet', 

26 'CircuitTerminationFilterSet', 

27 'CircuitTypeFilterSet', 

28 'ProviderAccountFilterSet', 

29 'ProviderFilterSet', 

30 'ProviderNetworkFilterSet', 

31 'VirtualCircuitFilterSet', 

32 'VirtualCircuitTerminationFilterSet', 

33 'VirtualCircuitTypeFilterSet', 

34) 

35 

36 

37@register_filterset 

38class ProviderFilterSet(PrimaryModelFilterSet, ContactModelFilterSet): 

39 region_id = TreeNodeMultipleChoiceFilter( 

40 queryset=Region.objects.all(), 

41 field_name='circuits__terminations___region', 

42 lookup_expr='in', 

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

44 ) 

45 region = TreeNodeMultipleChoiceFilter( 

46 queryset=Region.objects.all(), 

47 field_name='circuits__terminations___region', 

48 lookup_expr='in', 

49 to_field_name='slug', 

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

51 ) 

52 site_group_id = TreeNodeMultipleChoiceFilter( 

53 queryset=SiteGroup.objects.all(), 

54 field_name='circuits__terminations___site_group', 

55 lookup_expr='in', 

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

57 ) 

58 site_group = TreeNodeMultipleChoiceFilter( 

59 queryset=SiteGroup.objects.all(), 

60 field_name='circuits__terminations___site_group', 

61 lookup_expr='in', 

62 to_field_name='slug', 

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

64 ) 

65 site_id = django_filters.ModelMultipleChoiceFilter( 

66 field_name='circuits__terminations___site', 

67 queryset=Site.objects.all(), 

68 label=_('Site'), 

69 ) 

70 site = django_filters.ModelMultipleChoiceFilter( 

71 field_name='circuits__terminations___site__slug', 

72 queryset=Site.objects.all(), 

73 to_field_name='slug', 

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

75 ) 

76 asn_id = django_filters.ModelMultipleChoiceFilter( 

77 field_name='asns', 

78 queryset=ASN.objects.all(), 

79 label=_('ASN (ID)'), 

80 ) 

81 asn = django_filters.ModelMultipleChoiceFilter( 

82 field_name='asns__asn', 

83 queryset=ASN.objects.all(), 

84 to_field_name='asn', 

85 label=_('ASN'), 

86 ) 

87 

88 class Meta: 

89 model = Provider 

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

91 

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

93 if not value.strip(): 

94 return queryset 

95 return queryset.filter( 

96 Q(name__icontains=value) | 

97 Q(description__icontains=value) | 

98 Q(comments__icontains=value) 

99 ) 

100 

101 

102@register_filterset 

103class ProviderAccountFilterSet(PrimaryModelFilterSet, ContactModelFilterSet): 

104 provider_id = django_filters.ModelMultipleChoiceFilter( 

105 queryset=Provider.objects.all(), 

106 distinct=False, 

107 label=_('Provider (ID)'), 

108 ) 

109 provider = django_filters.ModelMultipleChoiceFilter( 

110 field_name='provider__slug', 

111 queryset=Provider.objects.all(), 

112 distinct=False, 

113 to_field_name='slug', 

114 label=_('Provider (slug)'), 

115 ) 

116 

117 class Meta: 

118 model = ProviderAccount 

119 fields = ('id', 'name', 'account', 'description') 

120 

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

122 if not value.strip(): 

123 return queryset 

124 return queryset.filter( 

125 Q(name__icontains=value) | 

126 Q(description__icontains=value) | 

127 Q(account__icontains=value) | 

128 Q(comments__icontains=value) 

129 ).distinct() 

130 

131 

132@register_filterset 

133class ProviderNetworkFilterSet(PrimaryModelFilterSet): 

134 provider_id = django_filters.ModelMultipleChoiceFilter( 

135 queryset=Provider.objects.all(), 

136 distinct=False, 

137 label=_('Provider (ID)'), 

138 ) 

139 provider = django_filters.ModelMultipleChoiceFilter( 

140 field_name='provider__slug', 

141 queryset=Provider.objects.all(), 

142 distinct=False, 

143 to_field_name='slug', 

144 label=_('Provider (slug)'), 

145 ) 

146 

147 class Meta: 

148 model = ProviderNetwork 

149 fields = ('id', 'name', 'service_id', 'description') 

150 

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

152 if not value.strip(): 

153 return queryset 

154 return queryset.filter( 

155 Q(name__icontains=value) | 

156 Q(service_id__icontains=value) | 

157 Q(description__icontains=value) | 

158 Q(comments__icontains=value) 

159 ).distinct() 

160 

161 

162@register_filterset 

163class CircuitTypeFilterSet(OrganizationalModelFilterSet): 

164 

165 class Meta: 

166 model = CircuitType 

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

168 

169 

170@register_filterset 

171class CircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet): 

172 provider_id = django_filters.ModelMultipleChoiceFilter( 

173 queryset=Provider.objects.all(), 

174 distinct=False, 

175 label=_('Provider (ID)'), 

176 ) 

177 provider = django_filters.ModelMultipleChoiceFilter( 

178 field_name='provider__slug', 

179 queryset=Provider.objects.all(), 

180 distinct=False, 

181 to_field_name='slug', 

182 label=_('Provider (slug)'), 

183 ) 

184 provider_account_id = django_filters.ModelMultipleChoiceFilter( 

185 field_name='provider_account', 

186 queryset=ProviderAccount.objects.all(), 

187 distinct=False, 

188 label=_('Provider account (ID)'), 

189 ) 

190 provider_account = django_filters.ModelMultipleChoiceFilter( 

191 field_name='provider_account__account', 

192 queryset=Provider.objects.all(), 

193 distinct=False, 

194 to_field_name='account', 

195 label=_('Provider account (account)'), 

196 ) 

197 provider_network_id = django_filters.ModelMultipleChoiceFilter( 

198 field_name='terminations___provider_network', 

199 queryset=ProviderNetwork.objects.all(), 

200 label=_('Provider network (ID)'), 

201 ) 

202 type_id = django_filters.ModelMultipleChoiceFilter( 

203 queryset=CircuitType.objects.all(), 

204 distinct=False, 

205 label=_('Circuit type (ID)'), 

206 ) 

207 type = django_filters.ModelMultipleChoiceFilter( 

208 field_name='type__slug', 

209 queryset=CircuitType.objects.all(), 

210 distinct=False, 

211 to_field_name='slug', 

212 label=_('Circuit type (slug)'), 

213 ) 

214 status = django_filters.MultipleChoiceFilter( 

215 choices=CircuitStatusChoices, 

216 distinct=False, 

217 null_value=None 

218 ) 

219 region_id = TreeNodeMultipleChoiceFilter( 

220 queryset=Region.objects.all(), 

221 field_name='terminations___region', 

222 lookup_expr='in', 

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

224 ) 

225 region = TreeNodeMultipleChoiceFilter( 

226 queryset=Region.objects.all(), 

227 field_name='terminations___region', 

228 lookup_expr='in', 

229 to_field_name='slug', 

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

231 ) 

232 site_group_id = TreeNodeMultipleChoiceFilter( 

233 queryset=SiteGroup.objects.all(), 

234 field_name='terminations___site_group', 

235 lookup_expr='in', 

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

237 ) 

238 site_group = TreeNodeMultipleChoiceFilter( 

239 queryset=SiteGroup.objects.all(), 

240 field_name='terminations___site_group', 

241 lookup_expr='in', 

242 to_field_name='slug', 

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

244 ) 

245 site_id = django_filters.ModelMultipleChoiceFilter( 

246 field_name='terminations___site', 

247 queryset=Site.objects.all(), 

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

249 ) 

250 site = django_filters.ModelMultipleChoiceFilter( 

251 field_name='terminations___site__slug', 

252 queryset=Site.objects.all(), 

253 to_field_name='slug', 

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

255 ) 

256 location_id = django_filters.ModelMultipleChoiceFilter( 

257 field_name='terminations___location', 

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

259 queryset=Location.objects.all(), 

260 ) 

261 termination_a_id = django_filters.ModelMultipleChoiceFilter( 

262 queryset=CircuitTermination.objects.all(), 

263 distinct=False, 

264 label=_('Termination A (ID)'), 

265 ) 

266 termination_z_id = django_filters.ModelMultipleChoiceFilter( 

267 queryset=CircuitTermination.objects.all(), 

268 distinct=False, 

269 label=_('Termination A (ID)'), 

270 ) 

271 

272 class Meta: 

273 model = Circuit 

274 fields = ( 

275 'id', 'cid', 'description', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit', 

276 ) 

277 

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

279 if not value.strip(): 

280 return queryset 

281 return queryset.filter( 

282 Q(cid__icontains=value) | 

283 Q(terminations__xconnect_id__icontains=value) | 

284 Q(terminations__pp_info__icontains=value) | 

285 Q(terminations__description__icontains=value) | 

286 Q(description__icontains=value) | 

287 Q(comments__icontains=value) 

288 ).distinct() 

289 

290 

291@register_filterset 

292class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet): 

293 q = django_filters.CharFilter( 

294 method='search', 

295 label=_('Search'), 

296 ) 

297 circuit_id = django_filters.ModelMultipleChoiceFilter( 

298 queryset=Circuit.objects.all(), 

299 distinct=False, 

300 label=_('Circuit'), 

301 ) 

302 termination_type = MultiValueContentTypeFilter() 

303 region_id = TreeNodeMultipleChoiceFilter( 

304 queryset=Region.objects.all(), 

305 field_name='_region', 

306 lookup_expr='in', 

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

308 ) 

309 region = TreeNodeMultipleChoiceFilter( 

310 queryset=Region.objects.all(), 

311 field_name='_region', 

312 lookup_expr='in', 

313 to_field_name='slug', 

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

315 ) 

316 site_group_id = TreeNodeMultipleChoiceFilter( 

317 queryset=SiteGroup.objects.all(), 

318 field_name='_site_group', 

319 lookup_expr='in', 

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

321 ) 

322 site_group = TreeNodeMultipleChoiceFilter( 

323 queryset=SiteGroup.objects.all(), 

324 field_name='_site_group', 

325 lookup_expr='in', 

326 to_field_name='slug', 

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

328 ) 

329 site_id = django_filters.ModelMultipleChoiceFilter( 

330 queryset=Site.objects.all(), 

331 distinct=False, 

332 field_name='_site', 

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

334 ) 

335 site = django_filters.ModelMultipleChoiceFilter( 

336 field_name='_site__slug', 

337 queryset=Site.objects.all(), 

338 distinct=False, 

339 to_field_name='slug', 

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

341 ) 

342 location_id = TreeNodeMultipleChoiceFilter( 

343 queryset=Location.objects.all(), 

344 field_name='_location', 

345 lookup_expr='in', 

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

347 ) 

348 location = TreeNodeMultipleChoiceFilter( 

349 queryset=Location.objects.all(), 

350 field_name='_location', 

351 lookup_expr='in', 

352 to_field_name='slug', 

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

354 ) 

355 provider_network_id = django_filters.ModelMultipleChoiceFilter( 

356 queryset=ProviderNetwork.objects.all(), 

357 distinct=False, 

358 field_name='_provider_network', 

359 label=_('ProviderNetwork (ID)'), 

360 ) 

361 provider_id = django_filters.ModelMultipleChoiceFilter( 

362 field_name='circuit__provider_id', 

363 queryset=Provider.objects.all(), 

364 distinct=False, 

365 label=_('Provider (ID)'), 

366 ) 

367 provider = django_filters.ModelMultipleChoiceFilter( 

368 field_name='circuit__provider__slug', 

369 queryset=Provider.objects.all(), 

370 distinct=False, 

371 to_field_name='slug', 

372 label=_('Provider (slug)'), 

373 ) 

374 

375 class Meta: 

376 model = CircuitTermination 

377 fields = ( 

378 'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', 

379 'mark_connected', 'pp_info', 'cable_end', 'cable_connector', 

380 ) 

381 

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

383 if not value.strip(): 

384 return queryset 

385 return queryset.filter( 

386 Q(circuit__cid__icontains=value) | 

387 Q(xconnect_id__icontains=value) | 

388 Q(pp_info__icontains=value) | 

389 Q(description__icontains=value) 

390 ).distinct() 

391 

392 

393@register_filterset 

394class CircuitGroupFilterSet(OrganizationalModelFilterSet, TenancyFilterSet): 

395 

396 class Meta: 

397 model = CircuitGroup 

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

399 

400 

401@register_filterset 

402class CircuitGroupAssignmentFilterSet(NetBoxModelFilterSet): 

403 q = django_filters.CharFilter( 

404 method='search', 

405 label=_('Search'), 

406 ) 

407 member_type = MultiValueContentTypeFilter() 

408 member_type_id = django_filters.ModelMultipleChoiceFilter( 

409 field_name='member_type', 

410 queryset=ContentType.objects.all(), 

411 distinct=False, 

412 ) 

413 circuit = MultiValueCharFilter( 

414 method='filter_circuit', 

415 field_name='cid', 

416 label=_('Circuit (CID)'), 

417 ) 

418 circuit_id = MultiValueNumberFilter( 

419 method='filter_circuit', 

420 field_name='pk', 

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

422 ) 

423 virtual_circuit = MultiValueCharFilter( 

424 method='filter_virtual_circuit', 

425 field_name='cid', 

426 label=_('Virtual circuit (CID)'), 

427 ) 

428 virtual_circuit_id = MultiValueNumberFilter( 

429 method='filter_virtual_circuit', 

430 field_name='pk', 

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

432 ) 

433 provider = MultiValueCharFilter( 

434 method='filter_provider', 

435 field_name='slug', 

436 label=_('Provider (name)'), 

437 ) 

438 provider_id = MultiValueNumberFilter( 

439 method='filter_provider', 

440 field_name='pk', 

441 label=_('Provider (ID)'), 

442 ) 

443 group_id = django_filters.ModelMultipleChoiceFilter( 

444 queryset=CircuitGroup.objects.all(), 

445 distinct=False, 

446 label=_('Circuit group (ID)'), 

447 ) 

448 group = django_filters.ModelMultipleChoiceFilter( 

449 field_name='group__slug', 

450 queryset=CircuitGroup.objects.all(), 

451 distinct=False, 

452 to_field_name='slug', 

453 label=_('Circuit group (slug)'), 

454 ) 

455 

456 class Meta: 

457 model = CircuitGroupAssignment 

458 fields = ('id', 'member_type_id', 'member_id', 'priority') 

459 

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

461 if not value.strip(): 

462 return queryset 

463 return queryset.filter( 

464 Q(member__cid__icontains=value) | 

465 Q(group__name__icontains=value) 

466 ) 

467 

468 def filter_circuit(self, queryset, name, value): 

469 circuits = Circuit.objects.filter(**{f'{name}__in': value}) 

470 if not circuits.exists(): 

471 return queryset.none() 

472 return queryset.filter( 

473 Q( 

474 member_type=ContentType.objects.get_for_model(Circuit), 

475 member_id__in=circuits 

476 ) 

477 ) 

478 

479 def filter_virtual_circuit(self, queryset, name, value): 

480 virtual_circuits = VirtualCircuit.objects.filter(**{f'{name}__in': value}) 

481 if not virtual_circuits.exists(): 

482 return queryset.none() 

483 return queryset.filter( 

484 Q( 

485 member_type=ContentType.objects.get_for_model(VirtualCircuit), 

486 member_id__in=virtual_circuits 

487 ) 

488 ) 

489 

490 def filter_provider(self, queryset, name, value): 

491 providers = Provider.objects.filter(**{f'{name}__in': value}) 

492 if not providers.exists(): 

493 return queryset.none() 

494 circuits = Circuit.objects.filter(provider__in=providers) 

495 virtual_circuits = VirtualCircuit.objects.filter(provider_network__provider__in=providers) 

496 return queryset.filter( 

497 Q( 

498 member_type=ContentType.objects.get_for_model(Circuit), 

499 member_id__in=circuits 

500 ) | 

501 Q( 

502 member_type=ContentType.objects.get_for_model(VirtualCircuit), 

503 member_id__in=virtual_circuits 

504 ) 

505 ) 

506 

507 

508@register_filterset 

509class VirtualCircuitTypeFilterSet(OrganizationalModelFilterSet): 

510 

511 class Meta: 

512 model = VirtualCircuitType 

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

514 

515 

516@register_filterset 

517class VirtualCircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet): 

518 provider_id = django_filters.ModelMultipleChoiceFilter( 

519 field_name='provider_network__provider', 

520 queryset=Provider.objects.all(), 

521 distinct=False, 

522 label=_('Provider (ID)'), 

523 ) 

524 provider = django_filters.ModelMultipleChoiceFilter( 

525 field_name='provider_network__provider__slug', 

526 queryset=Provider.objects.all(), 

527 distinct=False, 

528 to_field_name='slug', 

529 label=_('Provider (slug)'), 

530 ) 

531 provider_account_id = django_filters.ModelMultipleChoiceFilter( 

532 field_name='provider_account', 

533 queryset=ProviderAccount.objects.all(), 

534 distinct=False, 

535 label=_('Provider account (ID)'), 

536 ) 

537 provider_account = django_filters.ModelMultipleChoiceFilter( 

538 field_name='provider_account__account', 

539 queryset=Provider.objects.all(), 

540 distinct=False, 

541 to_field_name='account', 

542 label=_('Provider account (account)'), 

543 ) 

544 provider_network_id = django_filters.ModelMultipleChoiceFilter( 

545 queryset=ProviderNetwork.objects.all(), 

546 distinct=False, 

547 label=_('Provider network (ID)'), 

548 ) 

549 type_id = django_filters.ModelMultipleChoiceFilter( 

550 queryset=VirtualCircuitType.objects.all(), 

551 distinct=False, 

552 label=_('Virtual circuit type (ID)'), 

553 ) 

554 type = django_filters.ModelMultipleChoiceFilter( 

555 field_name='type__slug', 

556 queryset=VirtualCircuitType.objects.all(), 

557 distinct=False, 

558 to_field_name='slug', 

559 label=_('Virtual circuit type (slug)'), 

560 ) 

561 status = django_filters.MultipleChoiceFilter( 

562 choices=CircuitStatusChoices, 

563 distinct=False, 

564 null_value=None 

565 ) 

566 

567 class Meta: 

568 model = VirtualCircuit 

569 fields = ('id', 'cid', 'description') 

570 

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

572 if not value.strip(): 

573 return queryset 

574 return queryset.filter( 

575 Q(cid__icontains=value) | 

576 Q(description__icontains=value) | 

577 Q(comments__icontains=value) 

578 ).distinct() 

579 

580 

581@register_filterset 

582class VirtualCircuitTerminationFilterSet(NetBoxModelFilterSet): 

583 q = django_filters.CharFilter( 

584 method='search', 

585 label=_('Search'), 

586 ) 

587 virtual_circuit_id = django_filters.ModelMultipleChoiceFilter( 

588 queryset=VirtualCircuit.objects.all(), 

589 distinct=False, 

590 label=_('Virtual circuit'), 

591 ) 

592 role = django_filters.MultipleChoiceFilter( 

593 choices=VirtualCircuitTerminationRoleChoices, 

594 distinct=False, 

595 null_value=None 

596 ) 

597 provider_id = django_filters.ModelMultipleChoiceFilter( 

598 field_name='virtual_circuit__provider_network__provider', 

599 queryset=Provider.objects.all(), 

600 distinct=False, 

601 label=_('Provider (ID)'), 

602 ) 

603 provider = django_filters.ModelMultipleChoiceFilter( 

604 field_name='virtual_circuit__provider_network__provider__slug', 

605 queryset=Provider.objects.all(), 

606 distinct=False, 

607 to_field_name='slug', 

608 label=_('Provider (slug)'), 

609 ) 

610 provider_account_id = django_filters.ModelMultipleChoiceFilter( 

611 field_name='virtual_circuit__provider_account', 

612 queryset=ProviderAccount.objects.all(), 

613 distinct=False, 

614 label=_('Provider account (ID)'), 

615 ) 

616 provider_account = django_filters.ModelMultipleChoiceFilter( 

617 field_name='virtual_circuit__provider_account__account', 

618 queryset=ProviderAccount.objects.all(), 

619 distinct=False, 

620 to_field_name='account', 

621 label=_('Provider account (account)'), 

622 ) 

623 provider_network_id = django_filters.ModelMultipleChoiceFilter( 

624 queryset=ProviderNetwork.objects.all(), 

625 distinct=False, 

626 field_name='virtual_circuit__provider_network', 

627 label=_('Provider network (ID)'), 

628 ) 

629 interface_id = django_filters.ModelMultipleChoiceFilter( 

630 queryset=Interface.objects.all(), 

631 distinct=False, 

632 field_name='interface', 

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

634 ) 

635 

636 class Meta: 

637 model = VirtualCircuitTermination 

638 fields = ('id', 'interface_id', 'description') 

639 

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

641 if not value.strip(): 

642 return queryset 

643 return queryset.filter( 

644 Q(virtual_circuit__cid__icontains=value) | 

645 Q(description__icontains=value) 

646 ).distinct()