Coverage for netbox/forms/search.py: 57%
19 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
1import re
3from django import forms
4from django.utils.translation import gettext_lazy as _
6from netbox.search import LookupTypes
7from netbox.search.backends import search_backend
9LOOKUP_CHOICES = (
10 ('', _('Partial match')),
11 (LookupTypes.EXACT, _('Exact match')),
12 (LookupTypes.STARTSWITH, _('Starts with')),
13 (LookupTypes.ENDSWITH, _('Ends with')),
14 (LookupTypes.REGEX, _('Regex')),
15)
18class SearchForm(forms.Form):
19 q = forms.CharField(
20 label=_('Search'),
21 widget=forms.TextInput(
22 attrs={
23 'hx-get': '',
24 'hx-target': '#object_list',
25 'hx-trigger': 'keyup[target.value.length >= 3] changed delay:500ms',
26 }
27 )
28 )
29 obj_types = forms.MultipleChoiceField(
30 choices=[],
31 required=False,
32 label=_('Object type(s)')
33 )
34 lookup = forms.ChoiceField(
35 choices=LOOKUP_CHOICES,
36 initial=LookupTypes.PARTIAL,
37 required=False,
38 label=_('Lookup')
39 )
41 def __init__(self, *args, **kwargs):
42 super().__init__(*args, **kwargs)
44 self.fields['obj_types'].choices = search_backend.get_object_types()
46 def clean(self):
48 # Validate regular expressions
49 if self.cleaned_data['lookup'] == LookupTypes.REGEX:
50 try:
51 re.compile(self.cleaned_data['q'])
52 except re.error as e:
53 raise forms.ValidationError({
54 'q': f'Invalid regular expression: {e}'
55 })