Coverage for ipam/forms/filtersets.py: 100%
170 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1from django import forms
2from django.utils.translation import gettext_lazy as _
4from dcim.models import Device, Location, Rack, RackGroup, Region, Site, SiteGroup
5from ipam.choices import *
6from ipam.constants import *
7from ipam.models import *
8from netbox.forms import NetBoxModelFilterSetForm, OrganizationalModelFilterSetForm, PrimaryModelFilterSetForm
9from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
10from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice
11from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, TagFilterField
12from utilities.forms.rendering import FieldSet
13from virtualization.models import Cluster, ClusterGroup, VirtualMachine
14from vpn.models import L2VPN
16__all__ = (
17 'ASNFilterForm',
18 'ASNRangeFilterForm',
19 'AggregateFilterForm',
20 'FHRPGroupFilterForm',
21 'IPAddressFilterForm',
22 'IPRangeFilterForm',
23 'PrefixFilterForm',
24 'RIRFilterForm',
25 'RoleFilterForm',
26 'RouteTargetFilterForm',
27 'ServiceFilterForm',
28 'ServiceTemplateFilterForm',
29 'VLANFilterForm',
30 'VLANGroupFilterForm',
31 'VLANTranslationPolicyFilterForm',
32 'VLANTranslationRuleFilterForm',
33 'VRFFilterForm',
34)
36PREFIX_MASK_LENGTH_CHOICES = add_blank_choice([
37 (i, i) for i in range(PREFIX_LENGTH_MIN, PREFIX_LENGTH_MAX + 1)
38])
40IPADDRESS_MASK_LENGTH_CHOICES = add_blank_choice([
41 (i, i) for i in range(IPADDRESS_MASK_LENGTH_MIN, IPADDRESS_MASK_LENGTH_MAX + 1)
42])
45class VRFFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm):
46 model = VRF
47 fieldsets = (
48 FieldSet('q', 'filter_id', 'tag'),
49 FieldSet('import_target_id', 'export_target_id', name=_('Route Targets')),
50 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
51 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
52 )
53 import_target_id = DynamicModelMultipleChoiceField(
54 queryset=RouteTarget.objects.all(),
55 required=False,
56 label=_('Import targets')
57 )
58 export_target_id = DynamicModelMultipleChoiceField(
59 queryset=RouteTarget.objects.all(),
60 required=False,
61 label=_('Export targets')
62 )
63 tag = TagFilterField(model)
66class RouteTargetFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm):
67 model = RouteTarget
68 fieldsets = (
69 FieldSet('q', 'filter_id', 'tag'),
70 FieldSet('importing_vrf_id', 'exporting_vrf_id', name=_('VRF')),
71 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
72 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
73 )
74 importing_vrf_id = DynamicModelMultipleChoiceField(
75 queryset=VRF.objects.all(),
76 required=False,
77 label=_('Imported by VRF')
78 )
79 exporting_vrf_id = DynamicModelMultipleChoiceField(
80 queryset=VRF.objects.all(),
81 required=False,
82 label=_('Exported by VRF')
83 )
84 tag = TagFilterField(model)
87class RIRFilterForm(OrganizationalModelFilterSetForm):
88 model = RIR
89 fieldsets = (
90 FieldSet('q', 'filter_id', 'tag'),
91 FieldSet('is_private', name=_('RIR')),
92 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
93 )
94 is_private = forms.NullBooleanField(
95 required=False,
96 label=_('Private'),
97 widget=forms.Select(
98 choices=BOOLEAN_WITH_BLANK_CHOICES
99 )
100 )
101 tag = TagFilterField(model)
104class AggregateFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm):
105 model = Aggregate
106 fieldsets = (
107 FieldSet('q', 'filter_id', 'tag'),
108 FieldSet('family', 'rir_id', name=_('Attributes')),
109 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
110 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
111 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
112 )
113 family = forms.ChoiceField(
114 required=False,
115 choices=add_blank_choice(IPAddressFamilyChoices),
116 label=_('Address family')
117 )
118 rir_id = DynamicModelMultipleChoiceField(
119 queryset=RIR.objects.all(),
120 required=False,
121 label=_('RIR')
122 )
123 tag = TagFilterField(model)
126class ASNRangeFilterForm(TenancyFilterForm, OrganizationalModelFilterSetForm):
127 model = ASNRange
128 fieldsets = (
129 FieldSet('q', 'filter_id', 'tag'),
130 FieldSet('rir_id', 'start', 'end', name=_('Range')),
131 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
132 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
133 )
134 rir_id = DynamicModelMultipleChoiceField(
135 queryset=RIR.objects.all(),
136 required=False,
137 label=_('RIR')
138 )
139 start = forms.IntegerField(
140 label=_('Start'),
141 required=False
142 )
143 end = forms.IntegerField(
144 label=_('End'),
145 required=False
146 )
147 tag = TagFilterField(model)
150class ASNFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm):
151 model = ASN
152 fieldsets = (
153 FieldSet('q', 'filter_id', 'tag'),
154 FieldSet('rir_id', 'role_id', 'site_group_id', 'site_id', name=_('Assignment')),
155 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
156 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
157 )
158 rir_id = DynamicModelMultipleChoiceField(
159 queryset=RIR.objects.all(),
160 required=False,
161 label=_('RIR')
162 )
163 role_id = DynamicModelMultipleChoiceField(
164 queryset=Role.objects.all(),
165 required=False,
166 label=_('Role')
167 )
168 site_group_id = DynamicModelMultipleChoiceField(
169 queryset=SiteGroup.objects.all(),
170 required=False,
171 label=_('Site group')
172 )
173 site_id = DynamicModelMultipleChoiceField(
174 queryset=Site.objects.all(),
175 required=False,
176 label=_('Site')
177 )
178 tag = TagFilterField(model)
181class RoleFilterForm(OrganizationalModelFilterSetForm):
182 model = Role
183 fieldsets = (
184 FieldSet('q', 'filter_id', 'tag'),
185 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
186 )
187 tag = TagFilterField(model)
190class PrefixFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm):
191 model = Prefix
192 fieldsets = (
193 FieldSet('q', 'filter_id', 'tag'),
194 FieldSet(
195 'within_include', 'family', 'status', 'role_id', 'mask_length', 'is_pool', 'mark_utilized',
196 name=_('Addressing')
197 ),
198 FieldSet('vlan_group_id', 'vlan_id', name=_('VLAN Assignment')),
199 FieldSet('vrf_id', 'present_in_vrf_id', name=_('VRF')),
200 FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Scope')),
201 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
202 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
203 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
204 )
205 mask_length__lte = forms.IntegerField(
206 widget=forms.HiddenInput()
207 )
208 within_include = forms.CharField(
209 required=False,
210 widget=forms.TextInput(
211 attrs={
212 'placeholder': 'Prefix',
213 }
214 ),
215 label=_('Search within')
216 )
217 family = forms.ChoiceField(
218 required=False,
219 choices=add_blank_choice(IPAddressFamilyChoices),
220 label=_('Address family')
221 )
222 mask_length = forms.MultipleChoiceField(
223 required=False,
224 choices=PREFIX_MASK_LENGTH_CHOICES,
225 label=_('Mask length')
226 )
227 vrf_id = DynamicModelMultipleChoiceField(
228 queryset=VRF.objects.all(),
229 required=False,
230 label=_('Assigned VRF'),
231 null_option='Global'
232 )
233 present_in_vrf_id = DynamicModelChoiceField(
234 queryset=VRF.objects.all(),
235 required=False,
236 label=_('Present in VRF')
237 )
238 status = forms.MultipleChoiceField(
239 label=_('Status'),
240 choices=PrefixStatusChoices,
241 required=False
242 )
243 region_id = DynamicModelMultipleChoiceField(
244 queryset=Region.objects.all(),
245 required=False,
246 label=_('Region')
247 )
248 site_group_id = DynamicModelMultipleChoiceField(
249 queryset=SiteGroup.objects.all(),
250 required=False,
251 label=_('Site group')
252 )
253 site_id = DynamicModelMultipleChoiceField(
254 queryset=Site.objects.all(),
255 required=False,
256 label=_('Site')
257 )
258 location_id = DynamicModelMultipleChoiceField(
259 queryset=Location.objects.all(),
260 required=False,
261 label=_('Location')
262 )
263 role_id = DynamicModelMultipleChoiceField(
264 queryset=Role.objects.all(),
265 required=False,
266 null_option='None',
267 label=_('Role')
268 )
269 is_pool = forms.NullBooleanField(
270 required=False,
271 label=_('Is a pool'),
272 widget=forms.Select(
273 choices=BOOLEAN_WITH_BLANK_CHOICES
274 )
275 )
276 mark_utilized = forms.NullBooleanField(
277 required=False,
278 label=_('Treat as fully utilized'),
279 widget=forms.Select(
280 choices=BOOLEAN_WITH_BLANK_CHOICES
281 )
282 )
283 vlan_group_id = DynamicModelMultipleChoiceField(
284 queryset=VLANGroup.objects.all(),
285 required=False,
286 label=_('VLAN Group'),
287 )
288 vlan_id = DynamicModelMultipleChoiceField(
289 queryset=VLAN.objects.all(),
290 required=False,
291 label=_('VLAN'),
292 )
294 tag = TagFilterField(model)
297class IPRangeFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm):
298 model = IPRange
299 fieldsets = (
300 FieldSet('q', 'filter_id', 'tag'),
301 FieldSet('family', 'vrf_id', 'status', 'role_id', 'mark_populated', 'mark_utilized', name=_('Attributes')),
302 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
303 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
304 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
305 )
306 family = forms.ChoiceField(
307 required=False,
308 choices=add_blank_choice(IPAddressFamilyChoices),
309 label=_('Address family')
310 )
311 vrf_id = DynamicModelMultipleChoiceField(
312 queryset=VRF.objects.all(),
313 required=False,
314 label=_('Assigned VRF'),
315 null_option='Global'
316 )
317 status = forms.MultipleChoiceField(
318 label=_('Status'),
319 choices=IPRangeStatusChoices,
320 required=False
321 )
322 role_id = DynamicModelMultipleChoiceField(
323 queryset=Role.objects.all(),
324 required=False,
325 null_option='None',
326 label=_('Role')
327 )
328 mark_populated = forms.NullBooleanField(
329 required=False,
330 label=_('Treat as populated'),
331 widget=forms.Select(
332 choices=BOOLEAN_WITH_BLANK_CHOICES
333 )
334 )
335 mark_utilized = forms.NullBooleanField(
336 required=False,
337 label=_('Treat as fully utilized'),
338 widget=forms.Select(
339 choices=BOOLEAN_WITH_BLANK_CHOICES
340 )
341 )
342 tag = TagFilterField(model)
345class IPAddressFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm):
346 model = IPAddress
347 fieldsets = (
348 FieldSet('q', 'filter_id', 'tag'),
349 FieldSet(
350 'parent', 'family', 'status', 'role', 'mask_length', 'assigned_to_interface', 'dns_name',
351 name=_('Attributes')
352 ),
353 FieldSet('vrf_id', 'present_in_vrf_id', name=_('VRF')),
354 FieldSet('device_id', 'virtual_machine_id', name=_('Device/VM')),
355 FieldSet('nat_inside_id', name=_('NAT')),
356 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
357 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
358 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
359 )
360 selector_fields = ('filter_id', 'q', 'region_id', 'group_id', 'parent', 'status', 'role')
361 parent = forms.CharField(
362 required=False,
363 widget=forms.TextInput(
364 attrs={
365 'placeholder': 'Prefix',
366 }
367 ),
368 label=_('Parent Prefix')
369 )
370 family = forms.ChoiceField(
371 required=False,
372 choices=add_blank_choice(IPAddressFamilyChoices),
373 label=_('Address family')
374 )
375 mask_length = forms.ChoiceField(
376 required=False,
377 choices=IPADDRESS_MASK_LENGTH_CHOICES,
378 label=_('Mask length')
379 )
380 vrf_id = DynamicModelMultipleChoiceField(
381 queryset=VRF.objects.all(),
382 required=False,
383 label=_('Assigned VRF'),
384 null_option='Global'
385 )
386 present_in_vrf_id = DynamicModelChoiceField(
387 queryset=VRF.objects.all(),
388 required=False,
389 label=_('Present in VRF')
390 )
391 device_id = DynamicModelMultipleChoiceField(
392 queryset=Device.objects.all(),
393 required=False,
394 label=_('Assigned Device'),
395 )
396 virtual_machine_id = DynamicModelMultipleChoiceField(
397 queryset=VirtualMachine.objects.all(),
398 required=False,
399 label=_('Assigned VM'),
400 )
401 nat_inside_id = DynamicModelMultipleChoiceField(
402 queryset=IPAddress.objects.all(),
403 required=False,
404 label=_('NAT inside'),
405 )
406 status = forms.MultipleChoiceField(
407 label=_('Status'),
408 choices=IPAddressStatusChoices,
409 required=False
410 )
411 role = forms.MultipleChoiceField(
412 label=_('Role'),
413 choices=IPAddressRoleChoices,
414 required=False
415 )
416 assigned_to_interface = forms.NullBooleanField(
417 required=False,
418 label=_('Assigned to an interface'),
419 widget=forms.Select(
420 choices=BOOLEAN_WITH_BLANK_CHOICES
421 )
422 )
423 dns_name = forms.CharField(
424 required=False,
425 label=_('DNS Name')
426 )
427 tag = TagFilterField(model)
430class FHRPGroupFilterForm(PrimaryModelFilterSetForm):
431 model = FHRPGroup
432 fieldsets = (
433 FieldSet('q', 'filter_id', 'tag'),
434 FieldSet('name', 'protocol', 'group_id', name=_('Attributes')),
435 FieldSet('auth_type', 'auth_key', name=_('Authentication')),
436 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
437 )
438 name = forms.CharField(
439 label=_('Name'),
440 required=False
441 )
442 protocol = forms.MultipleChoiceField(
443 label=_('Protocol'),
444 choices=FHRPGroupProtocolChoices,
445 required=False
446 )
447 group_id = forms.IntegerField(
448 min_value=0,
449 required=False,
450 label=_('Group ID')
451 )
452 auth_type = forms.MultipleChoiceField(
453 choices=FHRPGroupAuthTypeChoices,
454 required=False,
455 label=_('Authentication type')
456 )
457 auth_key = forms.CharField(
458 required=False,
459 label=_('Authentication key')
460 )
461 tag = TagFilterField(model)
464class VLANGroupFilterForm(TenancyFilterForm, OrganizationalModelFilterSetForm):
465 fieldsets = (
466 FieldSet('q', 'filter_id', 'tag'),
467 FieldSet('region', 'site_group', 'site', 'location', 'rack_group', 'rack', name=_('Location')),
468 FieldSet('cluster_group', 'cluster', name=_('Cluster')),
469 FieldSet('contains_vid', 'total_vlan_ids', name=_('VLANs')),
470 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
471 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
472 )
473 model = VLANGroup
474 region = DynamicModelMultipleChoiceField(
475 queryset=Region.objects.all(),
476 required=False,
477 label=_('Region')
478 )
479 site_group = DynamicModelMultipleChoiceField(
480 queryset=SiteGroup.objects.all(),
481 required=False,
482 label=_('Site group')
483 )
484 site = DynamicModelMultipleChoiceField(
485 queryset=Site.objects.all(),
486 required=False,
487 label=_('Site')
488 )
489 location = DynamicModelMultipleChoiceField(
490 queryset=Location.objects.all(),
491 required=False,
492 label=_('Location')
493 )
494 rack_group = DynamicModelMultipleChoiceField(
495 queryset=RackGroup.objects.all(),
496 required=False,
497 label=_('Rack group')
498 )
499 rack = DynamicModelMultipleChoiceField(
500 queryset=Rack.objects.all(),
501 required=False,
502 label=_('Rack')
503 )
504 cluster = DynamicModelMultipleChoiceField(
505 queryset=Cluster.objects.all(),
506 required=False,
507 label=_('Cluster')
508 )
509 cluster_group = DynamicModelMultipleChoiceField(
510 queryset=ClusterGroup.objects.all(),
511 required=False,
512 label=_('Cluster group')
513 )
514 contains_vid = forms.IntegerField(
515 min_value=0,
516 required=False,
517 label=_('Contains VLAN ID')
518 )
519 total_vlan_ids = forms.IntegerField(
520 min_value=0,
521 required=False,
522 label=_('Total VLAN IDs')
523 )
525 tag = TagFilterField(model)
528class VLANTranslationPolicyFilterForm(PrimaryModelFilterSetForm):
529 model = VLANTranslationPolicy
530 fieldsets = (
531 FieldSet('q', 'filter_id', 'tag'),
532 FieldSet('name', name=_('Attributes')),
533 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
534 )
535 name = forms.CharField(
536 required=False,
537 label=_('Name')
538 )
539 tag = TagFilterField(model)
542class VLANTranslationRuleFilterForm(NetBoxModelFilterSetForm):
543 model = VLANTranslationRule
544 fieldsets = (
545 FieldSet('q', 'filter_id', 'tag'),
546 FieldSet('policy_id', 'local_vid', 'remote_vid', name=_('Attributes')),
547 )
548 tag = TagFilterField(model)
549 policy_id = DynamicModelMultipleChoiceField(
550 queryset=VLANTranslationPolicy.objects.all(),
551 required=False,
552 label=_('VLAN Translation Policy')
553 )
554 local_vid = forms.IntegerField(
555 min_value=1,
556 required=False,
557 label=_('Local VLAN ID')
558 )
559 remote_vid = forms.IntegerField(
560 min_value=1,
561 required=False,
562 label=_('Remote VLAN ID')
563 )
566class VLANFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm):
567 model = VLAN
568 fieldsets = (
569 FieldSet('q', 'filter_id', 'tag'),
570 FieldSet('region_id', 'site_group_id', 'site_id', 'related_to_site', name=_('Location')),
571 FieldSet('group_id', 'status', 'role_id', 'vid', 'l2vpn_id', name=_('Attributes')),
572 FieldSet('qinq_role', 'qinq_svlan_id', name=_('Q-in-Q/802.1ad')),
573 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
574 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
575 )
576 selector_fields = ('filter_id', 'q', 'group_id')
577 region_id = DynamicModelMultipleChoiceField(
578 queryset=Region.objects.all(),
579 required=False,
580 label=_('Region')
581 )
582 site_group_id = DynamicModelMultipleChoiceField(
583 queryset=SiteGroup.objects.all(),
584 required=False,
585 label=_('Site group')
586 )
587 site_id = DynamicModelMultipleChoiceField(
588 queryset=Site.objects.all(),
589 required=False,
590 null_option='None',
591 query_params={
592 'region': '$region'
593 },
594 label=_('Site')
595 )
596 related_to_site = DynamicModelMultipleChoiceField(
597 queryset=Site.objects.all(),
598 required=False,
599 label=_('Related to site')
600 )
601 group_id = DynamicModelMultipleChoiceField(
602 queryset=VLANGroup.objects.all(),
603 required=False,
604 null_option='None',
605 query_params={
606 'region': '$region'
607 },
608 label=_('VLAN group')
609 )
610 status = forms.MultipleChoiceField(
611 label=_('Status'),
612 choices=VLANStatusChoices,
613 required=False
614 )
615 role_id = DynamicModelMultipleChoiceField(
616 queryset=Role.objects.all(),
617 required=False,
618 null_option='None',
619 label=_('Role')
620 )
621 vid = forms.IntegerField(
622 required=False,
623 label=_('VLAN ID')
624 )
625 qinq_role = forms.MultipleChoiceField(
626 label=_('Q-in-Q role'),
627 choices=VLANQinQRoleChoices,
628 required=False
629 )
630 qinq_svlan_id = DynamicModelMultipleChoiceField(
631 queryset=VLAN.objects.all(),
632 required=False,
633 null_option='None',
634 label=_('Q-in-Q SVLAN')
635 )
636 l2vpn_id = DynamicModelMultipleChoiceField(
637 queryset=L2VPN.objects.all(),
638 required=False,
639 label=_('L2VPN')
640 )
641 tag = TagFilterField(model)
644class ServiceTemplateFilterForm(PrimaryModelFilterSetForm):
645 model = ServiceTemplate
646 fieldsets = (
647 FieldSet('q', 'filter_id', 'tag'),
648 FieldSet('port_mappings', 'protocol', 'port', name=_('Attributes')),
649 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
650 )
651 # A complete protocol/port pair, matched as a whole. Unlike `protocol` and `port` (which are
652 # correlated but independently specified), this is a single free-text value: an unknown protocol or
653 # malformed pair simply matches nothing, so no client-side validation is needed here.
654 port_mappings = forms.CharField(
655 label=_('Port mapping'),
656 required=False,
657 widget=forms.TextInput(
658 attrs={
659 'placeholder': 'e.g. tcp/80',
660 }
661 )
662 )
663 protocol = forms.MultipleChoiceField(
664 label=_('Protocol'),
665 choices=ServiceProtocolChoices,
666 required=False
667 )
668 port = forms.IntegerField(
669 label=_('Port'),
670 required=False,
671 )
672 tag = TagFilterField(model)
675class ServiceFilterForm(ContactModelFilterForm, ServiceTemplateFilterForm):
676 model = Service
677 fieldsets = (
678 FieldSet('q', 'filter_id', 'tag'),
679 FieldSet('port_mappings', 'protocol', 'port', name=_('Attributes')),
680 FieldSet('device_id', 'virtual_machine_id', 'fhrpgroup_id', name=_('Assignment')),
681 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')),
682 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
683 )
684 device_id = DynamicModelMultipleChoiceField(
685 queryset=Device.objects.all(),
686 required=False,
687 label=_('Device'),
688 )
689 virtual_machine_id = DynamicModelMultipleChoiceField(
690 queryset=VirtualMachine.objects.all(),
691 required=False,
692 label=_('Virtual Machine'),
693 )
694 fhrpgroup_id = DynamicModelMultipleChoiceField(
695 queryset=FHRPGroup.objects.all(),
696 required=False,
697 label=_('FHRP Group'),
698 )
699 tag = TagFilterField(model)