Django IntegrityError:如何在删除视图中处理ForeignKeyViolation?

问题描述 投票:0回答:1

我在尝试删除 Django 中的记录时遇到问题。我有公司的删除功能,但有时如果公司在另一个表中有相关记录,我会遇到 IntegrityError 。我尝试处理 IntegrityError,但没有帮助 — 该错误发生在 try- except 块之后并导致 500 错误。这是我的代码:

@login_required(login_url=reverse_lazy('autintification'))
def delete_cp_company(request):
    db_name = LOCAL_DB if DEBUG else request.get_host().split(".")[0]
    cp_company_ids = json.loads(request.POST.get('cp_company_ids'))
    no_del = []
    for ids in cp_company_ids:
        company = CP_company_for_pattern.objects.using(db_name).get(id=ids)
        print('id', ids)
        try:
            company.delete()
        except:
            no_del.append({
                'id': company.id,
                'name': company.com_name,
            })
    return JsonResponse(data={'no_delete': no_del})

这是发送删除请求的 JavaScript:

function delete_cp_company() {
    let check_box = $('.cp_company_list_block .check_for_choose_item');
    let ids_to_delete = [];

    for (let i = 0; i < check_box.length; i++) {
        if (check_box[i].checked) {
            let deleted_tr = $(check_box[i]).closest('tr');
            let deleted_tr_id = deleted_tr.data("id");

            ids_to_delete.push(deleted_tr_id);
        }
    }

    $.ajax({
        url: "/delete_cp_company",
        method: "POST",
        data: {
            cp_company_ids: JSON.stringify(ids_to_delete),
            csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
        },
        enctype: "multipart/form-data",
        dataType: 'json',
        success: function (data) {
            processCompanyDelete(ids_to_delete, data.no_delete)
        },
        error: function (xhr, status, error) {
            console.error('AJAX Error: ' + status + ' - ' + error);
        },
    });
}

我尝试在 try-except 块中处理 IntegrityError,但该错误仍然导致 500 响应。我还尝试添加更具体的错误处理并使用 Django 事务,但似乎没有任何效果。主要问题是,当 Django 尝试提交事务时,在 try-except 块之后引发异常。

这是我收到的错误:

id 11
id 4
Internal Server Error: /delete_cp_company
Traceback (most recent call last):
  File "/path/to/django/db/backends/base/base.py", line 253, in _commit
    return self.connection.commit()
psycopg2.errors.ForeignKeyViolation: update or delete on table "CRM_App_cp_company_for_pattern" violates foreign key constraint "CRM_App_contract_tab_our_company_id_370011ff_fk_CRM_App_c" on table "CRM_App_contract_table"
DETAIL:  Key (id)=(4) is still referenced from table "CRM_App_contract_table".

The above exception was the direct cause of the following exception:
  File "/path/to/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/path/to/django/db/backends/base/base.py", line 253, in _commit
    return self.connection.commit()
django.db.utils.IntegrityError: update or delete on table "CRM_App_cp_company_for_pattern" violates foreign key constraint "CRM_App_contract_tab_our_company_id_370011ff_fk_CRM_App_c" on table "CRM_App_contract_table"
DETAIL:  Key (id)=(4) is still referenced from table "CRM_App_contract_table".

HTTP POST /delete_cp_company 500 [0.11, 127.0.0.1:58081]

如何正确处理这个错误,避免导致500错误?

javascript python django ajax django-views
1个回答
0
投票

该错误表明存在一个带有该公司外键的对象,如果您要删除该公司,则该外键将为空,这是不允许的。

很可能在您的 models.py 中您有一个带有

null=False
on_delete=models.DO_NOTHING
的外键。

class CRM_App_contract_table(models.Model):
    company = models.ForeignKey(Company, on_delete=models.DO_NOTHING)

因此您必须将其更改为

null=True
models.CASCADE

© www.soinside.com 2019 - 2024. All rights reserved.