Django Testing IntegrityError:重复的键值违反了唯一约束详细信息:键(project_id)=(1023044)已存在

时间:2019-09-28 19:37:19

标签: django unit-testing django-testing

我无法在Django的单元测试中解决此IntegrityError问题。这是我的模特:

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 

    ...

在单元测试中,即使尝试显式分配唯一ID给创建的实例,我也收到完整性错误消息:

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)

我确保只使用一种测试,因此在不同的测试用例之间不会共享数据,这会使Django失效:

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

我收到以下错误消息:

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

我也尝试使用mommy.make创建项目,但是得到了相同的错误消息。我还尝试专门为项目创建行分配不存在的ID,但无法说服Django停止抱怨。

因此,Project被创建了两次,但是我不知道原因和位置。任何帮助深表感谢!

1 个答案:

答案 0 :(得分:0)

事实证明,我使用的信号已经创建了一个实例,而我又在deleteRow(cardID) { fetch("/people/" + cardID, { method: "delete" }) .then(results => { //results.json(); const { cards } = this.state; const updatedCardList = cards.filter(card => card.id !== cardID); this.setState({ cards: updatedCardList }) }); 中创建了相同的实例。解决方案是避免创建重复的实例,或者只是使用setUpTestData而不是create或get_or_create