mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Fix constraint for address model (#5076)
* Fix constraint for address model - Do not handle at database level - Add a "validate_unique" method to the address model - Fixes https://github.com/inventree/InvenTree/issues/5070 * Remove unique constraint rule * Unit test fix - Adjust unit test around new code * Further unit test updates
This commit is contained in:
parent
b700b44c53
commit
303305e05f
@ -30,8 +30,4 @@ class Migration(migrations.Migration):
|
||||
('company', models.ForeignKey(help_text='Select company', on_delete=django.db.models.deletion.CASCADE, related_name='addresses', to='company.company', verbose_name='Company')),
|
||||
],
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='address',
|
||||
constraint=models.UniqueConstraint(condition=models.Q(('primary', True)), fields=('company',), name='one_primary_per_company'),
|
||||
),
|
||||
]
|
||||
|
@ -306,9 +306,6 @@ class Address(models.Model):
|
||||
|
||||
class Meta:
|
||||
"""Metaclass defines extra model options"""
|
||||
constraints = [
|
||||
UniqueConstraint(fields=['company'], condition=Q(primary=True), name='one_primary_per_company')
|
||||
]
|
||||
verbose_name_plural = "Addresses"
|
||||
|
||||
@staticmethod
|
||||
@ -316,6 +313,16 @@ class Address(models.Model):
|
||||
"""Return the API URL associated with the Contcat model"""
|
||||
return reverse('api-address-list')
|
||||
|
||||
def validate_unique(self, exclude=None):
|
||||
"""Ensure that only one primary address exists per company"""
|
||||
|
||||
super().validate_unique(exclude=exclude)
|
||||
|
||||
if self.primary:
|
||||
# Check that no other primary address exists for this company
|
||||
if Address.objects.filter(company=self.company, primary=True).exclude(pk=self.pk).exists():
|
||||
raise ValidationError({'primary': _('Company already has a primary address')})
|
||||
|
||||
company = models.ForeignKey(Company, related_name='addresses',
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_('Company'),
|
||||
|
@ -5,7 +5,6 @@ from decimal import Decimal
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import transaction
|
||||
from django.db.utils import IntegrityError
|
||||
from django.test import TestCase
|
||||
|
||||
from part.models import Part
|
||||
@ -199,17 +198,23 @@ class AddressTest(TestCase):
|
||||
c2 = Company.objects.create(name='Test Corp2.', description='We make stuff good')
|
||||
Address.objects.create(company=self.c, primary=True)
|
||||
Address.objects.create(company=self.c, primary=False)
|
||||
|
||||
self.assertEqual(Address.objects.count(), 2)
|
||||
|
||||
# Testing the constraint itself
|
||||
# Intentionally throwing exceptions breaks unit tests unless performed in an atomic block
|
||||
with transaction.atomic():
|
||||
self.assertRaises(IntegrityError, Address.objects.create, company=self.c, primary=True, confirm_primary=False)
|
||||
with self.assertRaises(ValidationError):
|
||||
addr = Address(company=self.c, primary=True, confirm_primary=False)
|
||||
addr.validate_unique()
|
||||
|
||||
Address.objects.create(company=c2, primary=True, line1="Hellothere", line2="generalkenobi")
|
||||
|
||||
with transaction.atomic():
|
||||
self.assertRaises(IntegrityError, Address.objects.create, company=c2, primary=True)
|
||||
with self.assertRaises(ValidationError):
|
||||
addr = Address(company=c2, primary=True, confirm_primary=False)
|
||||
addr.validate_unique()
|
||||
|
||||
self.assertEqual(Address.objects.count(), 3)
|
||||
|
||||
def test_first_address_is_primary(self):
|
||||
@ -219,7 +224,10 @@ class AddressTest(TestCase):
|
||||
|
||||
self.assertTrue(addr.primary)
|
||||
|
||||
self.assertRaises(IntegrityError, Address.objects.create, company=self.c, primary=True)
|
||||
# Create another address, which should error out if primary is not set to False
|
||||
with self.assertRaises(ValidationError):
|
||||
addr = Address(company=self.c, primary=True)
|
||||
addr.validate_unique()
|
||||
|
||||
def test_model_str(self):
|
||||
"""Test value of __str__"""
|
||||
|
Loading…
Reference in New Issue
Block a user