1

I have not been able to resolve this IntegrityError issue in my Django's unittest. Here are my models:

class UserProfile(models.Model):
''' UserProfile to separate authentication and profile '''

    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, null = True, blank = True)
    # Note: first name and last name is in the custom User model
    first_name = models.CharField(max_length = 20, blank = True, null = True)
    last_name = models.CharField(max_length = 30, blank = True, null = True)
    address = models.CharField(max_length = 100, null=True, blank = True)  
    address_city = models.CharField(max_length = 30, null = True, blank = True)
    metropolitan = models.CharField(max_length = 30, null = True, blank = False)

class Municipality(models.Model):
    name = models.CharField(max_length = 50)
    abb = models.CharField(max_length = 5)
    date_created = models.DateTimeField(auto_now_add = True)
    date_modified = models.DateTimeField(auto_now = True)
    userprofile = models.ForeignKey('user_profile.UserProfile', blank = False, null = False, related_name = 'userprofile_municipalities', on_delete = models.CASCADE)


class Project(models.Model):
    name = models.CharField(max_length = 50)
    logo = models.ImageField(null=True, blank = True, width_field = 'logo_width', height_field = 'logo_height')
    logo_height = models.IntegerField(default = 40)
    logo_width = models.IntegerField(default = 40)

    date_created = models.DateTimeField(auto_now_add = True )
    date_modified = models.DateTimeField(auto_now = True )

    # RELATIONSHIPS:
    user_profiles = models.ManyToManyField('user_profile.UserProfile', through = 'ProjectAssociation', through_fields = ('project', 'user_profile' ), blank = True, related_name = 'user_projects')
    address = models.OneToOneField(Address, on_delete = models.PROTECT, null = True, blank = True)
    municipality = models.ForeignKey('development.Municipality', related_name = 'municipality_projects', null = False, blank = False)


class Job(models.Model):
    project = models.OneToOneField('project_profile.Project', blank = False, on_delete = models.CASCADE, related_name = 'job')
    ...

    date_modified = models.DateTimeField(auto_now_add = True)
    date_created = models.DateTimeField(auto_now = True)

class Invoice(models.Model):

    PO = models.CharField(max_length = 50, blank = False, null = False)  # e.g. Mixed Use Residential Commercial Rental Invoice
    invoice_type = models.CharField(max_length = 40)
    date_created = models.DateTimeField(auto_now = True)
    date_modified = models.DateTimeField(auto_now_add = True)

    job = models.ForeignKey(DevelopmentProject, related_name = 'job_invoices', blank = True, null = True, on_delete = models.CASCADE)
    Invoice_creator = models.ForeignKey('user_profile.UserProfile', related_name = 'created_invoices', blank = True, null = True, on_delete = models.SET_NULL)  # ModelForm to enforce If the Invoice creator's account is closed, the corresponding Invoices to be preserved
    Invoice_reviewer = models.ForeignKey('user_profile.UserProfile', related_name = 'reviewed_invoices', blank = True, null = True , on_delete = models.SET_NULL )  # The reviewer is not necessary, but 

    ...

In my unittest, I am getting integrity error message even when I try to explicitly assign unique id to the created instance:

class UpdateinvoiceTestCase(TestCase):
''' Unit Test for Updateinvoice View '''

    def setUp(self):
        self.factory = RequestFactory()

        # Create the dependencies
        self.userprofile = mommy.make('user_profile.UserProfile')
        print ('User profile: ', self.userprofile, ' - userprofile id: ', self.userprofile.id )

        self.municipality = mommy.make('development.municipality', userprofile = self.userprofile, _quantity=1)

        self.project = mommy.make('project_profile.Project', municipality = self.municipality[0], _quantity=2)
        self.job = mommy.make('development.Job', project = self.project[0] )

        # Create invoice
        self.invoice = mommy.make('development.invoice', job = self.job)

        # Passing the pk to create the url
        the_uri = reverse('development:update_invoice', args=(self.invoice.pk,))
        the_url = 'http://localhost:8000' + reverse('development:update_invoice', args=(self.invoice.pk,))

        # Creating a client:
        self.response = self.client.get(the_url, follow=True)

    def test_url(self):
        ''' Ensure that the url works '''
        self.assertEqual(self.response.status_code, 200)

I have made sure only one test is run using so there is no sharing of the data between different testcases that would throw Django off:

python manage.py test project.tests.test_views.UpdateViewTestCase

I get the the following error message:

IntegrityError: duplicate key value violates unique constraint "development_developmentproject_project_id_key" 
DETAIL:  Key (project_id)=(1) already exists

I also tried using mommy.make to create project, but I got the same error message. I also tried to specifically assign non-existent ids to the Project creation line, but could not convince Django to stop complaining.

So, Project is being created twice, but I cannot figure out why and where. Any help is much appreciated!

1 Answer 1

2

It turned out that I've used signals which created an instance already and I was creating the same instance in my setUpTestData again. The solution was to avoid creating a duplicate instance or simply use get_or_create instead of create or mommy.make

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this helped me. I was creating a related model automatically using a post_save signal, then accidentally trying to create it myself, causing the duplicate key error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.