足够简单的例子 - 我有一些以查询集开头的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_foo
或some_bar
变量可能不是正确的类型(例如,我们最终可能是空的字符串试图过滤整数字段。)因此,此代码最终可能会引发TypeError
或ValueError
。
没关系,我可以恰当地处理这个案子,但是从ORM合同中我不清楚的是在什么时候我应该期望提出这些例外。
.filter()
声明中发生?... .get()
声明?... 答案 0 :(得分:1)
要回答原始问题,在构建新的查询集时,会在调用过滤时引发FieldError
和ValueError
:
>>> 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,克隆查询集的工作相对昂贵,所以你忽略了这个开销,同时使代码更清晰。回到你的问题,用这种模式毫无疑问会引发异常。