如何捕捉A' UNIQUE约束失败' 404在django

时间:2015-01-01 08:59:08

标签: python django

如何在以下代码中专门捕获UNIQUE约束失败404,我知道我必须在(这里?)部分添加一些内容

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

6 个答案:

答案 0 :(得分:28)

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极有可能。

答案 1 :(得分:7)

恕我直言,我建议通过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

答案 2 :(得分:3)

通常"请求宽恕"原则是编程的好习惯,但在这种特殊情况下,我不推荐它。

您要查找的例外是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块并在保存之前检查对象是否已存在于数据库中。

我不知道哪个字段在你的情况下是独一无二的,所以我只假设它是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)

答案 3 :(得分:1)

对于Python> 3.5

您需要:

except IntegrityError as e: 
                if 'unique constraint' in e.args:

示例:

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 e.args:
               continue 

答案 4 :(得分:0)

唯一约束失败返回:“(''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

答案 5 :(得分:0)

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