mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-16 03:55:41 +00:00
User Setting To Search Notes (#9393)
* add search notes and tie user search settings to checkboxes in search drawer * add user setting to optionally search the notes of objects * add search filter test * add PR link * add limit parameter * typo, meant to check part result * resolve api_version.py conflict * don't use search_whole and search_regex together --------- Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
@ -582,6 +582,7 @@ class APISearchViewSerializer(serializers.Serializer):
|
||||
search = serializers.CharField()
|
||||
search_regex = serializers.BooleanField(default=False, required=False)
|
||||
search_whole = serializers.BooleanField(default=False, required=False)
|
||||
search_notes = serializers.BooleanField(default=False, required=False)
|
||||
limit = serializers.IntegerField(default=1, required=False)
|
||||
offset = serializers.IntegerField(default=0, required=False)
|
||||
|
||||
@ -643,6 +644,7 @@ class APISearchView(GenericAPIView):
|
||||
'search': '',
|
||||
'search_regex': False,
|
||||
'search_whole': False,
|
||||
'search_notes': False,
|
||||
'limit': 1,
|
||||
'offset': 0,
|
||||
}
|
||||
|
@ -1,12 +1,15 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 331
|
||||
INVENTREE_API_VERSION = 332
|
||||
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
v332 - 2025-04-02 : https://github.com/inventree/InvenTree/pull/9393
|
||||
- Adds 'search_notes' parameter to all searchable API endpoints
|
||||
|
||||
v331 - 2025-04-01 : https://github.com/inventree/InvenTree/pull/9437
|
||||
- Set correct types on various formerly-string PK fields as well permissions
|
||||
- Include metadata request and response types
|
||||
|
@ -32,14 +32,23 @@ class InvenTreeSearchFilter(filters.SearchFilter):
|
||||
"""Return a set of search fields for the request, adjusted based on request params.
|
||||
|
||||
The following query params are available to 'augment' the search (in decreasing order of priority)
|
||||
- search_notes: If True, 'notes' is added to the search_fields if it isn't already present
|
||||
- search_regex: If True, search is performed on 'regex' comparison
|
||||
"""
|
||||
regex = InvenTree.helpers.str2bool(
|
||||
request.query_params.get('search_regex', False)
|
||||
search_notes = InvenTree.helpers.str2bool(
|
||||
request.query_params.get('search_notes', False)
|
||||
)
|
||||
|
||||
search_fields = super().get_search_fields(view, request)
|
||||
|
||||
if search_notes and 'notes' not in search_fields:
|
||||
# don't modify existing list, create a new object so further queries aren't affected
|
||||
search_fields = [*search_fields, 'notes']
|
||||
|
||||
regex = InvenTree.helpers.str2bool(
|
||||
request.query_params.get('search_regex', False)
|
||||
)
|
||||
|
||||
fields = []
|
||||
|
||||
if search_fields:
|
||||
|
@ -297,6 +297,7 @@ class SearchTests(InvenTreeAPITestCase):
|
||||
'stock',
|
||||
'order',
|
||||
'sales_order',
|
||||
'build',
|
||||
]
|
||||
roles = ['build.view', 'part.view']
|
||||
|
||||
@ -353,6 +354,82 @@ class SearchTests(InvenTreeAPITestCase):
|
||||
self.assertNotIn('stockitem', response.data)
|
||||
self.assertNotIn('build', response.data)
|
||||
|
||||
def test_search_filters(self):
|
||||
"""Test that the regex, whole word, and notes filters are handled correctly."""
|
||||
SEARCH_TERM = 'some note'
|
||||
RE_SEARCH_TERM = 'some (.*) note'
|
||||
|
||||
response = self.post(
|
||||
reverse('api-search'),
|
||||
{'search': SEARCH_TERM, 'limit': 10, 'part': {}, 'build': {}},
|
||||
expected_code=200,
|
||||
)
|
||||
# No build or part results
|
||||
self.assertEqual(response.data['build']['count'], 0)
|
||||
self.assertEqual(response.data['part']['count'], 0)
|
||||
|
||||
# add the search_notes param
|
||||
response = self.post(
|
||||
reverse('api-search'),
|
||||
{
|
||||
'search': SEARCH_TERM,
|
||||
'limit': 10,
|
||||
'search_notes': True,
|
||||
'part': {},
|
||||
'build': {},
|
||||
},
|
||||
expected_code=200,
|
||||
)
|
||||
# now should have some build results
|
||||
self.assertEqual(response.data['build']['count'], 4)
|
||||
|
||||
# use the regex term
|
||||
response = self.post(
|
||||
reverse('api-search'),
|
||||
{
|
||||
'search': RE_SEARCH_TERM,
|
||||
'limit': 10,
|
||||
'search_notes': True,
|
||||
'part': {},
|
||||
'build': {},
|
||||
},
|
||||
expected_code=200,
|
||||
)
|
||||
# No results again
|
||||
self.assertEqual(response.data['build']['count'], 0)
|
||||
|
||||
# add the regex_search param
|
||||
response = self.post(
|
||||
reverse('api-search'),
|
||||
{
|
||||
'search': RE_SEARCH_TERM,
|
||||
'limit': 10,
|
||||
'search_notes': True,
|
||||
'search_regex': True,
|
||||
'part': {},
|
||||
'build': {},
|
||||
},
|
||||
expected_code=200,
|
||||
)
|
||||
# we get our results back!
|
||||
self.assertEqual(response.data['build']['count'], 4)
|
||||
|
||||
# add the search_whole param
|
||||
response = self.post(
|
||||
reverse('api-search'),
|
||||
{
|
||||
'search': RE_SEARCH_TERM,
|
||||
'limit': 10,
|
||||
'search_notes': True,
|
||||
'search_whole': True,
|
||||
'part': {},
|
||||
'build': {},
|
||||
},
|
||||
expected_code=200,
|
||||
)
|
||||
# No results again
|
||||
self.assertEqual(response.data['build']['count'], 0)
|
||||
|
||||
def test_permissions(self):
|
||||
"""Test that users with insufficient permissions are handled correctly."""
|
||||
# First, remove all roles
|
||||
|
@ -165,6 +165,14 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
|
||||
'default': False,
|
||||
'validator': bool,
|
||||
},
|
||||
'SEARCH_NOTES': {
|
||||
'name': _('Search Notes'),
|
||||
'description': _(
|
||||
"Search queries return results for matches from the item's notes"
|
||||
),
|
||||
'default': False,
|
||||
'validator': bool,
|
||||
},
|
||||
'PART_SHOW_QUANTITY_IN_FORMS': {
|
||||
'name': _('Show Quantity in Forms'),
|
||||
'description': _('Display available part quantity in some forms'),
|
||||
|
Reference in New Issue
Block a user