如何在以下代码中专门捕获UNIQUE约束失败404,我知道我必须在(这里?)部分添加一些内容
try:
q = AnswerModel(user=user, yes_question=question_model)
q.save()
except ( here? ):
return HttpResponseRedirect('/user/already_exists')
答案 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