diff --git a/InvenTree/InvenTree/conversion.py b/InvenTree/InvenTree/conversion.py
index 6067a4a071..e5a918a4b0 100644
--- a/InvenTree/InvenTree/conversion.py
+++ b/InvenTree/InvenTree/conversion.py
@@ -43,7 +43,7 @@ def convert_physical_value(value: str, unit: str = None):
         unit: Optional unit to convert to, and validate against
 
     Raises:
-        ValidationError: If the value is invalid
+        ValidationError: If the value is invalid or cannot be converted to the specified unit
 
     Returns:
         The converted quantity, in the specified units
diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py
index 7350195d0c..b204a7a9fa 100644
--- a/InvenTree/company/models.py
+++ b/InvenTree/company/models.py
@@ -2,6 +2,7 @@
 
 import os
 from datetime import datetime
+from decimal import Decimal
 
 from django.apps import apps
 from django.core.exceptions import ValidationError
@@ -477,10 +478,35 @@ class SupplierPart(MetadataMixin, InvenTreeBarcodeMixin, common.models.MetaMixin
         """
         super().clean()
 
+        self.pack_units = self.pack_units.strip()
+
+        # An empty 'pack_units' value is equivalent to '1'
+        if self.pack_units == '':
+            self.pack_units = '1'
+
         # Validate that the UOM is compatible with the base part
         if self.pack_units and self.part:
             try:
-                InvenTree.conversion.convert_physical_value(self.pack_units, self.part.units)
+                # Attempt conversion to specified unit
+                native_value = InvenTree.conversion.convert_physical_value(
+                    self.pack_units, self.part.units
+                )
+
+                # If part units are not provided, value must be dimensionless
+                if not self.part.units and native_value.units not in ['', 'dimensionless']:
+                    raise ValidationError({
+                        'pack_units': _("Pack units must be compatible with the base part units")
+                    })
+
+                # Native value must be greater than zero
+                if float(native_value.magnitude) <= 0:
+                    raise ValidationError({
+                        'pack_units': _("Pack units must be greater than zero")
+                    })
+
+                # Update native pack units value
+                self.pack_units_native = Decimal(native_value.magnitude)
+
             except ValidationError as e:
                 raise ValidationError({
                     'pack_units': e.messages
@@ -521,21 +547,23 @@ class SupplierPart(MetadataMixin, InvenTreeBarcodeMixin, common.models.MetaMixin
 
         super().save(*args, **kwargs)
 
-    part = models.ForeignKey('part.Part', on_delete=models.CASCADE,
-                             related_name='supplier_parts',
-                             verbose_name=_('Base Part'),
-                             limit_choices_to={
-                                 'purchaseable': True,
-                             },
-                             help_text=_('Select part'),
-                             )
+    part = models.ForeignKey(
+        'part.Part', on_delete=models.CASCADE,
+        related_name='supplier_parts',
+        verbose_name=_('Base Part'),
+        limit_choices_to={
+            'purchaseable': True,
+        },
+        help_text=_('Select part'),
+    )
 
-    supplier = models.ForeignKey(Company, on_delete=models.CASCADE,
-                                 related_name='supplied_parts',
-                                 limit_choices_to={'is_supplier': True},
-                                 verbose_name=_('Supplier'),
-                                 help_text=_('Select supplier'),
-                                 )
+    supplier = models.ForeignKey(
+        Company, on_delete=models.CASCADE,
+        related_name='supplied_parts',
+        limit_choices_to={'is_supplier': True},
+        verbose_name=_('Supplier'),
+        help_text=_('Select supplier'),
+    )
 
     SKU = models.CharField(
         max_length=100,
@@ -543,12 +571,13 @@ class SupplierPart(MetadataMixin, InvenTreeBarcodeMixin, common.models.MetaMixin
         help_text=_('Supplier stock keeping unit')
     )
 
-    manufacturer_part = models.ForeignKey(ManufacturerPart, on_delete=models.CASCADE,
-                                          blank=True, null=True,
-                                          related_name='supplier_parts',
-                                          verbose_name=_('Manufacturer Part'),
-                                          help_text=_('Select manufacturer part'),
-                                          )
+    manufacturer_part = models.ForeignKey(
+        ManufacturerPart, on_delete=models.CASCADE,
+        blank=True, null=True,
+        related_name='supplier_parts',
+        verbose_name=_('Manufacturer Part'),
+        help_text=_('Select manufacturer part'),
+    )
 
     link = InvenTreeURLField(
         blank=True, null=True,
diff --git a/InvenTree/company/templates/company/supplier_part.html b/InvenTree/company/templates/company/supplier_part.html
index 917b1ad2fe..86991d184f 100644
--- a/InvenTree/company/templates/company/supplier_part.html
+++ b/InvenTree/company/templates/company/supplier_part.html
@@ -165,8 +165,15 @@ src="{% static 'img/blank_image.png' %}"
         {% if part.pack_units %}
         <tr>
             <td><span class='fas fa-box'></span></td>
-            <td>{% trans "Units" %}</td>
-            <td>{% part.pack_units %} {% include "part/part_units.html" with part=part.part %}</td>
+            <td>
+                {% trans "Units" %}
+                {% if part.part.units %}
+                <span class='float-right'>
+                    <em>[ {% include "part/part_units.html" with part=part.part %}]</em>
+                </span>
+                {% endif %}
+            </td>
+            <td>{{ part.pack_units }}</td>
         </tr>
         {% endif %}
         {% if part.note %}
diff --git a/InvenTree/company/test_supplier_parts.py b/InvenTree/company/test_supplier_parts.py
new file mode 100644
index 0000000000..31c715808a
--- /dev/null
+++ b/InvenTree/company/test_supplier_parts.py
@@ -0,0 +1,114 @@
+"""Unit tests specific to the SupplierPart model"""
+
+from decimal import Decimal
+
+from django.core.exceptions import ValidationError
+
+from company.models import Company, SupplierPart
+from InvenTree.unit_test import InvenTreeTestCase
+from part.models import Part
+
+
+class SupplierPartPackUnitsTests(InvenTreeTestCase):
+    """Unit tests for the SupplierPart pack_units field"""
+
+    def test_pack_units_dimensionless(self):
+        """Test valid values for the 'pack_units' field"""
+
+        # Create a part without units (dimensionless)
+        part = Part.objects.create(name='Test Part', description='Test part description', component=True)
+
+        # Create a supplier (company)
+        company = Company.objects.create(name='Test Company', is_supplier=True)
+
+        # Create a supplier part for this part
+        sp = SupplierPart.objects.create(
+            part=part,
+            supplier=company,
+            SKU='TEST-SKU'
+        )
+
+        # All these values are valid for a dimensionless part
+        pass_tests = {
+            '': 1,
+            '1': 1,
+            '1.01': 1.01,
+            '12.000001': 12.000001,
+            '99.99': 99.99,
+        }
+
+        # All these values are invalid for a dimensionless part
+        fail_tests = [
+            '1.2m',
+            '-1',
+            '0',
+            '0.0',
+            '100 feet',
+            '0 amps'
+        ]
+
+        for test, expected in pass_tests.items():
+            sp.pack_units = test
+            sp.full_clean()
+            self.assertEqual(sp.pack_units_native, expected)
+
+        for test in fail_tests:
+            sp.pack_units = test
+            with self.assertRaises(ValidationError):
+                sp.full_clean()
+
+    def test_pack_units(self):
+        """Test pack_units for a part with a specified dimension"""
+
+        # Create a part with units 'm'
+        part = Part.objects.create(name='Test Part', description='Test part description', component=True, units='m')
+
+        # Create a supplier (company)
+        company = Company.objects.create(name='Test Company', is_supplier=True)
+
+        # Create a supplier part for this part
+        sp = SupplierPart.objects.create(
+            part=part,
+            supplier=company,
+            SKU='TEST-SKU'
+        )
+
+        # All these values are valid for a part with dimesion 'm'
+        pass_tests = {
+            '': 1,
+            '1': 1,
+            '1m': 1,
+            '1.01m': 1.01,
+            '1.01': 1.01,
+            '5 inches': 0.127,
+            '27 cm': 0.27,
+            '3km': 3000,
+            '14 feet': 4.2672,
+            '0.5 miles': 804.672,
+        }
+
+        # All these values are invalid for a part with dimension 'm'
+        # Either the values are invalid, or the units are incomaptible
+        fail_tests = [
+            '-1',
+            '-1m',
+            '0',
+            '0m',
+            '12 deg',
+            '57 amps',
+            '-12 oz',
+            '17 yaks',
+        ]
+
+        for test, expected in pass_tests.items():
+            sp.pack_units = test
+            sp.full_clean()
+            self.assertEqual(
+                round(Decimal(sp.pack_units_native), 10),
+                round(Decimal(str(expected)), 10)
+            )
+
+        for test in fail_tests:
+            sp.pack_units = test
+            with self.assertRaises(ValidationError):
+                sp.full_clean()
diff --git a/InvenTree/part/migrations/0109_auto_20230517_1048.py b/InvenTree/part/migrations/0109_auto_20230517_1048.py
index 9b7bfd8430..3067a37741 100644
--- a/InvenTree/part/migrations/0109_auto_20230517_1048.py
+++ b/InvenTree/part/migrations/0109_auto_20230517_1048.py
@@ -19,6 +19,10 @@ def update_template_units(apps, schema_editor):
 
     n_templates = PartParameterTemplate.objects.count()
 
+    if n_templates == 0:
+        # Escape early
+        return
+
     ureg = InvenTree.conversion.get_unit_registry()
 
     n_converted = 0
diff --git a/InvenTree/part/migrations/0111_auto_20230521_1350.py b/InvenTree/part/migrations/0111_auto_20230521_1350.py
index 41689200e2..10b1a66f69 100644
--- a/InvenTree/part/migrations/0111_auto_20230521_1350.py
+++ b/InvenTree/part/migrations/0111_auto_20230521_1350.py
@@ -20,6 +20,10 @@ def migrate_part_units(apps, schema_editor):
     parts = Part.objects.exclude(units=None).exclude(units='')
     n_parts = parts.count()
 
+    if n_parts == 0:
+        # Escape early
+        return
+
     ureg = InvenTree.conversion.get_unit_registry()
 
     invalid_units = set()