1

我被要求添加一些逻辑来建模唯一性。每个付款必须填写 transaction_id 或 payment_id。每个付款由 (transaction_id, operation, payment_created_date) 或 (payment_id, operation, payment_created_date) 标识。在数据库级别这工作正常。两次插入具有相同 transaction_id、操作、payment_created_date 的 Payment 会导致违反唯一约束。对于这个模型,我创建了管理页面。但是插入与管理页面相同的行会导致IntegrityError at /admin/finance/payment/add/ duplicate key value violates unique constraint "unique_finance_payment_without_payment_id" DETAIL: Key (transaction_id, operation, payment_created_date)=(dasdasd, Refund, 2021-10-04) already exists.而不是简单的用户友好管理错误Please correct the error below. Payment with this Transaction id, Operation and Payment created date already exists。如何让 Django 管理员捕获此 IntegrityError 并以管理员形式显示?

这是我的models.py

class ReportName(DiModel):
    name = CharField(
        max_length=50,
        blank=False,
        null=False)

    def __str__(self):
        return self.name


class Payment(DiModel):

    class Meta:
        unique_together = ('transaction_id', 'payment_id', 'operation', 'payment_created_date')
        constraints=[UniqueConstraint(fields=['transaction_id', 'operation', 'payment_created_date'],
                         condition=Q(payment_id=None),
                         name='unique_finance_payment_without_payment_id'),
                     UniqueConstraint(fields=['payment_id', 'operation', 'payment_created_date'],
                         condition=Q(transaction_id=None),
                         name='unique_finance_payment_without_transaction_id'),]

    OPERATION_TYPE = [
        ('Refund', 'Refund'),
        ('Charge', 'Charge'),
    ]

    CURRENCY_CODE = [
        ('EUR', 'EUR'),
        ('RUB', 'RUB'),
        ('USD', 'USD'),
        ('GBP', 'GBP'),
        ('AUD', 'AUD'),
        ('PLN', 'PLN'),
        ('SGD', 'SGD'),
        ('MYR', 'MYR'),
        ('RON', 'RON'),
        ('ZAR', 'ZAR'),
    ]

    report_name = ForeignKey(ReportName,
                             on_delete=models.PROTECT,
                             blank=False,
                             null=False,
                             help_text="Processor and report type")

    operation = CharField(max_length=6,
                          choices=OPERATION_TYPE,
                          blank=False,
                          null=False,
                          default=OPERATION_TYPE[0][0],
                          help_text='Payment operation type')

    payment_created_date = DateField(blank=False,
                                     null=False,
                                     default=timezone.now)

    amount = DecimalField(blank=True,
                          null=True,
                          max_digits=10,
                          decimal_places=2,
                          help_text='Payment amount')

    commission = DecimalField(blank=False,
                              null=False,
                              max_digits=10,
                              decimal_places=2,
                              help_text='Transaction fee')

    currency = CharField(max_length=3,
                         choices=CURRENCY_CODE,
                         blank=False,
                         null=False,
                         default=CURRENCY_CODE[0][0],
                         help_text='Amount and commission currency code')

    transaction_id = CharField(max_length=32,
                               blank=True,
                               null=True,
                               help_text='Payota transaction id')

    payment_id = IntegerField(blank=True,
                              null=True,
                              help_text='Payota payment id')

    author_user = models.ForeignKey(User,
                                    on_delete=models.PROTECT,
                                    null=True,
                                    related_name='finance_author_user')

    
    def __str__(self):
        return f"{self.report_name} {self.operation} {self.created_at}"

这是我的 admin.py

class PaymentForm(forms.ModelForm):

    class Meta:
        fields = (
            'report_name',
            'operation',
            'payment_created_date',
            'amount',
            'commission',
            'currency',
            'transaction_id',
            'payment_id',
        )



@admin.register(Payment)
class PaymentAdmin(ImportExportMixin, admin.ModelAdmin):
    form = PaymentForm
    list_display = [
        'report_name',
        'operation',
        'payment_created_date',
        'amount',
        'commission',
        'currency',
        'transaction_id',
        'payment_id',
    ]
    list_filter = (
        'report_name',
        'operation',
        ('payment_created_date', DateRangeFilter),
    )
    search_fields = ['report_name__name', 'operation']
    resource_class = PaymentResource

    class Meta:
        model = Payment
4

0 回答 0