python 如何在django中捕获'UNIQUE constraint failed' 404

zwghvu4y  于 2023-05-12  发布在  Python
关注(0)|答案(6)|浏览(257)

如何具体捕获UNIQUE约束失败404在下面的代码中,我知道我必须在(这里)中添加一些东西?)节

try:
    q = AnswerModel(user=user, yes_question=question_model)
    q.save()
except ( here? ):
    return HttpResponseRedirect('/user/already_exists')
vhmi4jdf

vhmi4jdf1#

from django.db import IntegrityError

except IntegrityError:

这就是你需要的

编辑为@mbrochh:

from django.db import IntegrityError

except IntegrityError as e: 
    if 'unique constraint' in e.message: # or e.args[0] from Django 1.10
        #do something

是的,你可以更精确,但在问题的情况下,UNIQUE failed的可能性很高。

cotxawn7

cotxawn72#

恕我直言,我建议通过get_or_create()来解决这种情况。

new_obj, created = AnswerModel.objects.get_or_create(user=user, yes_question=question_model)
if created:
    do_something_for_new_object(new_obj)
else:
    logging.error("Duplicated item.")
    return
ilmyapht

ilmyapht3#

通常,“请求原谅”原则是编程中的一个很好的实践,但在这种特殊情况下,我不推荐它。
您正在查找的异常是IntegrityError。您可以通过简单地删除try-catch块并强制该异常来轻松地解决这个问题。回溯显示异常类。
问题是,有几种不同类型的完整性错误,因此在try-catch块中,您必须检查类似if ex.pgcode == 23505的内容,以查看这是否实际上是一个UNIQUE约束错误。这个问题之前已经回答过了:IntegrityError: distinguish between unique constraint and not null violations
更糟的是:每个ORM都有不同的错误代码,字段名不会是pgcode,而是其他的,有些ORM根本不会抛出UNIQUE约束。因此,如果你正在构建一个可重用的应用程序,或者如果你正在使用一个糟糕的ORM(如MySQL),或者如果你不确定将来是否会更改项目的数据库,你不应该这样做!
更好的方法是简单地删除try-catch块,并在保存之前检查对象是否已经在数据库中。
我不知道在您的例子中哪个字段是UNIQUE,所以我将假设它是user字段。你的代码看起来像这样:

answers = AnswerModel.objects.filter(user=user)
if answers:
   return HttpResponseRedirect('/user/already_exists')
obj = AnswerModel.objects.create(user=user, yes_question=question_model)
...

如果你正在处理一个组合的唯一约束,第一行应该是这样的:

answers = AnswerModel.objects.filter(user=user, yes_question=question_model)
1cklez4t

1cklez4t4#

Python 3.5以上版本

您需要:

except IntegrityError as e: 
   if 'unique constraint' in str(e.args).lower():

示例:

from django.db import IntegrityError

 for column in csv.reader(io_string, delimiter=',', quotechar="|"):
     try:
         _, created = Brand.objects.update_or_create(
            system_id=column[0],
            name=column[1],
            slug=column[2],
            description=column[3],
            image=column[4]
           )
     except IntegrityError as e: 
           if 'unique constraint' in str(e.args).lower():
               continue 
           else:
               raise e # Not the unique error we were expecting
oknrviil

oknrviil5#

django.db.models.query.QuerySet._create_object_from_params中找到。还有一些变化:

from typing import Any, Dict, Type  
from django.db import transaction, IntegrityError, Model

def get_or_create_obj(model: Type[Model], defaults: Dict[str, Any] = None, **kwargs: Any):
    defaults = defaults or {}
    try:
        with transaction.atomic():
            return model.objects.create(**kwargs, **defaults), True
    except IntegrityError as e:
        try:
            return model.objects.using("default").get(**kwargs), False
        except model.DoesNotExist:
            pass
        raise e
js81xvg6

js81xvg66#

唯一约束失败返回:“('UNIQUE约束失败:notepad_notepadform. title')”基本上是一个元组,所以我们可以使用下面的代码来捕获它并执行任何需要的操作:

from django.db import IntegrityError
try:
        if form.is_valid():
            form.save()

    except IntegrityError as e:
        if 'UNIQUE constraint' in str(e.args):
            #your code here

相关问题