【问题标题】:Django Testing IntegrityError: duplicate key value violates unique constraint DETAIL: Key (project_id)=(1023044) already existsDjango Testing IntegrityError:重复的键值违反了唯一约束细节:键(project_id)=(1023044)已经存在
【发布时间】:2019-09-28 19:37:19
【问题描述】:

我无法在我的 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 停止抱怨。

所以,项目被创建了两次,但我不知道为什么以及在哪里。非常感谢任何帮助!

【问题讨论】:

    标签: django unit-testing django-testing


    【解决方案1】:

    事实证明,我已经使用了创建实例的信号,并且我再次在 setUpTestData 中创建了相同的实例。解决方案是避免创建重复的实例或简单地使用 get_or_create 而不是 create 或 mommy.make

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-20
      • 2020-03-27
      • 2015-03-01
      • 1970-01-01
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多