Сбой единственного ограничения IntegrityError: отправка сообщения в API REST Django, поле OneToOne - PullRequest
0 голосов
/ 31 декабря 2018

Я публикую в Django REST API бэкэнда, используя веб-приложение, разработанное в Angular 7, в качестве внешнего интерфейса.В основном у меня есть модель супертипа Factura для двух подтипов, FacturaA и FacturaE, они оба связаны 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)

В моем приложении внешнего интерфейса я отправляю сообщение POST, сначала создав объект 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();
    });
  }

Добавление Factura с последующим FacturaE вручную в Django Admin не вызывает ошибок, однако выполнение этого вручную через API или через мое приложение веб-интерфейса дает мне следующееошибка.

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

Несмотря на эту ошибку и возвращая код состояния HTTP 500, объект все равно создается независимо от используемого мной метода.Я хотел бы знать, что является причиной ошибки и как ее исправить.

Редактировать:

Решено, super вызывается дважды при перезаписи метода save(), сервер пытается сохранитьFacturaE объект дважды, второй super().save(*args, **kwargs) выдавал ошибку

1 Ответ

0 голосов
/ 31 декабря 2018

Ошибка в том, что вы нарушаете атрибут OneOnOne, создавая FactoraE с назначенным ему существующим Factora объектом.

Таким образом, код выдает Unique constraint failed ....

Пожалуйста, проверьте следующие шаги:

  • убедитесь, что вы не пытаетесь создать еще один FactoraE с объектом Factora, для которого уже существует другой FactoraEс тем же Factora Item.

  • может быть, в вашем коде пользовательского интерфейса, в сервисе (который здесь не представлен) вы не передаете Factora.id правильно, поэтому он такой же, как и предыдущийзапросы, вызывающие эту ошибку.

Обновление Вызов super два раза не рекомендуется, и это может вызвать проблему.

...