Further fixes for default API values

- Account for callable defaults
- Extra check in is_valid()
This commit is contained in:
Oliver Walters 2021-06-27 00:01:40 +10:00
parent a0390f0821
commit ae1a1e139f
3 changed files with 77 additions and 3 deletions

View File

@ -18,6 +18,7 @@ class InvenTreeAPITestCase(APITestCase):
email = 'test@testing.com' email = 'test@testing.com'
superuser = False superuser = False
is_staff = True
auto_login = True auto_login = True
# Set list of roles automatically associated with the user # Set list of roles automatically associated with the user
@ -40,7 +41,11 @@ class InvenTreeAPITestCase(APITestCase):
if self.superuser: if self.superuser:
self.user.is_superuser = True self.user.is_superuser = True
self.user.save()
if self.is_staff:
self.user.is_staff = True
self.user.save()
for role in self.roles: for role in self.roles:
self.assignRole(role) self.assignRole(role)

View File

@ -59,10 +59,47 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
for field_name, field in fields.fields.items(): for field_name, field in fields.fields.items():
if field.has_default(): if field.has_default():
initials[field_name] = field.default
value = field.default
# Account for callable functions
if callable(value):
value = value()
initials[field_name] = value
return initials return initials
def is_valid(self, raise_exception=False):
"""
Also override the is_valid() method, as in some cases get_initial() is not actually called.
"""
# Calling super().is_valid creates self._validated_data
valid = super().is_valid(raise_exception)
# Are we creating a new instance?
if self.instance is None:
ModelClass = self.Meta.model
fields = model_meta.get_field_info(ModelClass)
for field_name, field in fields.fields.items():
if field.has_default():
if field not in self._validated_data:
value = field.default
# Account for callable functions
if callable(value):
value = value()
self._validated_data[field_name] = value
return valid
def run_validation(self, data=empty): def run_validation(self, data=empty):
""" Perform serializer validation. """ Perform serializer validation.
In addition to running validators on the serializer fields, In addition to running validators on the serializer fields,

View File

@ -13,6 +13,7 @@ from InvenTree.status_codes import StockStatus
from part.models import Part, PartCategory from part.models import Part, PartCategory
from stock.models import StockItem from stock.models import StockItem
from company.models import Company from company.models import Company
from common.models import InvenTreeSetting
class PartAPITest(InvenTreeAPITestCase): class PartAPITest(InvenTreeAPITestCase):
@ -332,7 +333,38 @@ class PartAPITest(InvenTreeAPITestCase):
# Check that the un-specified fields have used correct default values # Check that the un-specified fields have used correct default values
self.assertTrue(data['active']) self.assertTrue(data['active'])
self.assertFalse(data['virtual']) self.assertFalse(data['virtual'])
self.assertTrue(data['purchaseable'])
# By default, parts are not purchaseable
self.assertFalse(data['purchaseable'])
# Set the default 'purchaseable' status to True
InvenTreeSetting.set_setting(
'PART_PURCHASEABLE',
True,
self.user
)
response = self.client.post(url, {
'name': 'all defaults',
'description': 'my test part 2',
'category': 1,
})
# Part should now be purchaseable by default
self.assertTrue(response.data['purchaseable'])
# "default" values should not be used if the value is specified
response = self.client.post(url, {
'name': 'all defaults',
'description': 'my test part 2',
'category': 1,
'active': False,
'purchaseable': False,
})
self.assertFalse(response.data['active'])
self.assertFalse(response.data['purchaseable'])
class PartDetailTests(InvenTreeAPITestCase): class PartDetailTests(InvenTreeAPITestCase):