mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #2869 from SchrodingersGat/ipn-validator-fix
Adds 'variant_of' filter back into Part API
This commit is contained in:
commit
2696f6bfbd
@ -4,11 +4,14 @@ InvenTree API version information
|
|||||||
|
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 40
|
INVENTREE_API_VERSION = 41
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||||
|
|
||||||
|
v41 -> 2022-04-26
|
||||||
|
- Fixes 'variant_of' filter for Part list endpoint
|
||||||
|
|
||||||
v40 -> 2022-04-19
|
v40 -> 2022-04-19
|
||||||
- Adds ability to filter StockItem list by "tracked" parameter
|
- Adds ability to filter StockItem list by "tracked" parameter
|
||||||
- This checks the serial number or batch code fields
|
- This checks the serial number or batch code fields
|
||||||
|
@ -1175,6 +1175,18 @@ class PartList(generics.ListCreateAPIView):
|
|||||||
except (ValueError, Part.DoesNotExist):
|
except (ValueError, Part.DoesNotExist):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Filter by 'variant_of'
|
||||||
|
# Note that this is subtly different from 'ancestor' filter (above)
|
||||||
|
variant_of = params.get('variant_of', None)
|
||||||
|
|
||||||
|
if variant_of is not None:
|
||||||
|
try:
|
||||||
|
template = Part.objects.get(pk=variant_of)
|
||||||
|
variants = template.get_children()
|
||||||
|
queryset = queryset.filter(pk__in=[v.pk for v in variants])
|
||||||
|
except (ValueError, Part.DoesNotExist):
|
||||||
|
pass
|
||||||
|
|
||||||
# Filter only parts which are in the "BOM" for a given part
|
# Filter only parts which are in the "BOM" for a given part
|
||||||
in_bom_for = params.get('in_bom_for', None)
|
in_bom_for = params.get('in_bom_for', None)
|
||||||
|
|
||||||
@ -1339,10 +1351,6 @@ class PartList(generics.ListCreateAPIView):
|
|||||||
filters.OrderingFilter,
|
filters.OrderingFilter,
|
||||||
]
|
]
|
||||||
|
|
||||||
filter_fields = [
|
|
||||||
'variant_of',
|
|
||||||
]
|
|
||||||
|
|
||||||
ordering_fields = [
|
ordering_fields = [
|
||||||
'name',
|
'name',
|
||||||
'creation_date',
|
'creation_date',
|
||||||
|
@ -177,6 +177,7 @@
|
|||||||
fields:
|
fields:
|
||||||
name: 'Green chair variant'
|
name: 'Green chair variant'
|
||||||
variant_of: 10003
|
variant_of: 10003
|
||||||
|
is_template: true
|
||||||
category: 7
|
category: 7
|
||||||
trackable: true
|
trackable: true
|
||||||
tree_id: 1
|
tree_id: 1
|
||||||
|
@ -567,6 +567,97 @@ class PartAPITest(InvenTreeAPITestCase):
|
|||||||
self.assertEqual(response.data['name'], name)
|
self.assertEqual(response.data['name'], name)
|
||||||
self.assertEqual(response.data['description'], description)
|
self.assertEqual(response.data['description'], description)
|
||||||
|
|
||||||
|
def test_template_filters(self):
|
||||||
|
"""
|
||||||
|
Unit tests for API filters related to template parts:
|
||||||
|
|
||||||
|
- variant_of : Return children of specified part
|
||||||
|
- ancestor : Return descendants of specified part
|
||||||
|
|
||||||
|
Uses the 'chair template' part (pk=10000)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Rebuild the MPTT structure before running these tests
|
||||||
|
Part.objects.rebuild()
|
||||||
|
|
||||||
|
url = reverse('api-part-list')
|
||||||
|
|
||||||
|
response = self.get(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
'variant_of': 10000,
|
||||||
|
},
|
||||||
|
expected_code=200
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3 direct children of template part
|
||||||
|
self.assertEqual(len(response.data), 3)
|
||||||
|
|
||||||
|
response = self.get(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
'ancestor': 10000,
|
||||||
|
},
|
||||||
|
expected_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4 total descendants
|
||||||
|
self.assertEqual(len(response.data), 4)
|
||||||
|
|
||||||
|
# Use the 'green chair' as our reference
|
||||||
|
response = self.get(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
'variant_of': 10003,
|
||||||
|
},
|
||||||
|
expected_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(response.data), 1)
|
||||||
|
|
||||||
|
response = self.get(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
'ancestor': 10003,
|
||||||
|
},
|
||||||
|
expected_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(response.data), 1)
|
||||||
|
|
||||||
|
# Add some more variants
|
||||||
|
|
||||||
|
p = Part.objects.get(pk=10004)
|
||||||
|
|
||||||
|
for i in range(100):
|
||||||
|
Part.objects.create(
|
||||||
|
name=f'Chair variant {i}',
|
||||||
|
description='A new chair variant',
|
||||||
|
variant_of=p,
|
||||||
|
)
|
||||||
|
|
||||||
|
# There should still be only one direct variant
|
||||||
|
response = self.get(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
'variant_of': 10003,
|
||||||
|
},
|
||||||
|
expected_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(response.data), 1)
|
||||||
|
|
||||||
|
# However, now should be 101 descendants
|
||||||
|
response = self.get(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
'ancestor': 10003,
|
||||||
|
},
|
||||||
|
expected_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(response.data), 101)
|
||||||
|
|
||||||
|
|
||||||
class PartDetailTests(InvenTreeAPITestCase):
|
class PartDetailTests(InvenTreeAPITestCase):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user