在使用Django的ORM时,在什么时候引发了异常

时间:2013-01-04 13:27:40

标签: django django-orm

足够简单的例子 - 我有一些以查询集开头的Django代码......

queryset = MyModel.objects.all()

稍后它会执行各种过滤,具体取决于一些可配置的选项......

if something:
    queryset = self.queryset.filter(foo=some_foo)

if another_thing:
    queryset = self.queryset.filter(bar=some_bar)

最后它执行查找......

try:
    obj = queryset.get()
except ObjectDoesNotExist:
    raise ValidationError('Does not exist')

现在,由于过滤需要灵活的方式,some_foosome_bar变量可能不是正确的类型(例如,我们最终可能是空的字符串试图过滤整数字段。)因此,此代码最终可能会引发TypeErrorValueError

没关系,我可以恰当地处理这个案子,但是从ORM合同中我不清楚的是在什么时候我应该期望提出这些例外。

  • 是否会在.filter()声明中发生?...
  • ...或.get()声明?...
  • ...或者处于未指定状态,我能够处理它吗? (例如,可能取决于数据库后端的实现?)

1 个答案:

答案 0 :(得分:1)

要回答原始问题,在构建新的查询集时,会在调用过滤时引发FieldErrorValueError

>>> a = Account.objects.all()
>>> a = a.filter(id=3)
>>> a = a.filter(no_exist=3)
<snip>
FieldError: Cannot resolve keyword 'no_exist' into field. Choices are: active, created_on, group, id, ...

>>> a = Account.objects.all()
>>> a = a.filter(id='abc')
ValueError: invalid literal for int() with base 10: 'abc'

我还要补充一点,这种模式对我来说似乎有误导性,因为filter通常用于返回模型的列表/可迭代,而不是像{{1一样一个 }}。为了清楚和更容易处理异常,我建议使用这种模式:

get

另一个额外的好处是,IIRC,克隆查询集的工作相对昂贵,所以你忽略了这个开销,同时使代码更清晰。回到你的问题,用这种模式毫无疑问会引发异常。