【问题标题】:IntegrityError UNIQUE constraint failed: POSTing to Django REST API, OneToOne FieldIntegrityError UNIQUE 约束失败:POSTing to Django REST API, OneToOne Field
【发布时间】:2019-05-27 18:06:25
【问题描述】:

我使用在 Angular 7 中开发的 web 应用程序作为前端发布到后端 Django REST API。基本上我有两个子类型FacturaAFacturaE 的超类型模型Factura,它们都通过OneToOneField 相关联。

有问题的模型如下所示:

class Factura(models.Model):
    fecha = models.DateField()
    contrato = models.ForeignKey(Contrato, related_name='facturas', on_delete=models.CASCADE)
    pagado = models.BooleanField(default=False)

def __str__(self):
    return 'Factura %s: %s - %s' % (self.id, self.fecha, self.contrato)

class FacturaE(models.Model):
    factura = models.OneToOneField(
        Factura,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    kwh = models.DecimalField(max_digits=100, decimal_places=2)
    monto = models.DecimalField(max_digits=100, decimal_places=2, null=True, blank=True)

    def save(self, *args, **kwargs):
        #calcula el monto
        if self._state.adding is True:
            self.monto = float(self.kwh) * 4.0588
            super().save(*args, **kwargs)
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = 'Factura Electrica'
        verbose_name_plural = 'Facturas Electricas'

    def __str__(self):
        return 'Electricidad: %s - %s' % (self.factura, self.monto)

在我的前端应用程序中,我首先创建一个超类型对象Factura,然后使用添加的密钥发布一个FacturaE,如下所示:

  addFactura(fecha: Date, kwh: number, monto: number) {
    this.factura = new Factura(0, fecha, false, this.id);
    this.pagoService.addFactura(this.factura).subscribe(f => {
      this.facturaElectrica = new FacturaEAdd(f.id, kwh, monto);
      this.pagoService.addFacturaElectrica(this.facturaElectrica).subscribe();
    });
  }

在 Django Admin 中手动添加 Factura 后跟 FacturaE 不会产生错误,但是通过 API 或通过我的前端应用手动执行此操作会出现以下错误。

django.db.utils.IntegrityError: UNIQUE constraint failed: CasadelaAPI_facturae.factura_id

尽管出现此错误,并且尽管返回了 500 HTTP 状态代码,但无论我使用何种方法,该对象仍会被创建。我想知道是什么导致了错误以及如何修复它。

编辑:

已解决,supersave() 方法覆盖中被调用两次,后端试图保存 FacturaE 对象两次,第二次 super().save(*args, **kwargs) 产生错误

【问题讨论】:

    标签: python angular django-rest-framework


    【解决方案1】:

    错误是因为您通过创建一个分配有现有 Factora 对象的 FactoraE 违反了 OneOnOne 属性。

    所以代码抛出Unique constraint failed ...

    请检查以下步骤:

    • 确保您没有尝试使用 Factora 对象创建另一个 FactoraE,而该对象已经存在另一个 FactoraE 和相同的 Factora 项目。

    • 可能在你的UI代码中,在服务中(这里没有提供)你没有正确传递Factora.id,所以和之前的请求一样,导致这个错误。

    更新 不建议调用super 两次,这可能会导致问题。

    【讨论】:

    • 感谢您的帮助,但事实并非如此。当 FacturaE 获得分配给它的已使用的 Factura 对象时,错误读取为上面发布的第一张图像并阻止创建 FacturaE 对象,但是当使用尚未使用或分配的新创建的 Factura 对象进行 POST 时,第二个错误正在显示,但对象仍在创建中,并显示在 UI 和 Django/admin 中。
    • 请更新您的帖子并在您的 UI 中添加 pagoService
    • 还有一件事,为什么你在save 方法中调用super 两次。一个就够了。我不确定,但检查一下,也许这是错误的原因。
    • 你明白了,调用 super 两次导致错误。谢谢
    • 任何时候我的朋友:)
    猜你喜欢
    • 1970-01-01
    • 2021-06-29
    • 2016-12-22
    • 2017-08-05
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 2020-04-24
    相关资源
    最近更新 更多