diff --git a/InvenTree/InvenTree/api_tester.py b/InvenTree/InvenTree/api_tester.py
index a803e6797f..1cbc62ec0a 100644
--- a/InvenTree/InvenTree/api_tester.py
+++ b/InvenTree/InvenTree/api_tester.py
@@ -18,6 +18,7 @@ class InvenTreeAPITestCase(APITestCase):
     email = 'test@testing.com'
 
     superuser = False
+    is_staff = True
     auto_login = True
 
     # Set list of roles automatically associated with the user
@@ -40,8 +41,12 @@ class InvenTreeAPITestCase(APITestCase):
 
         if self.superuser:
             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:
             self.assignRole(role)
 
diff --git a/InvenTree/InvenTree/serializers.py b/InvenTree/InvenTree/serializers.py
index 9e8e811b90..c00c9ef690 100644
--- a/InvenTree/InvenTree/serializers.py
+++ b/InvenTree/InvenTree/serializers.py
@@ -59,10 +59,47 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
             for field_name, field in fields.fields.items():
 
                 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
 
+    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):
         """ Perform serializer validation.
         In addition to running validators on the serializer fields,
diff --git a/InvenTree/part/test_api.py b/InvenTree/part/test_api.py
index 787c5d3f85..29df621914 100644
--- a/InvenTree/part/test_api.py
+++ b/InvenTree/part/test_api.py
@@ -13,6 +13,7 @@ from InvenTree.status_codes import StockStatus
 from part.models import Part, PartCategory
 from stock.models import StockItem
 from company.models import Company
+from common.models import InvenTreeSetting
 
 
 class PartAPITest(InvenTreeAPITestCase):
@@ -332,7 +333,38 @@ class PartAPITest(InvenTreeAPITestCase):
         # Check that the un-specified fields have used correct default values
         self.assertTrue(data['active'])
         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):