足够简单的例子 - 我有一些以查询集开头的Django代码......
queryset = MyModel.objects.all()
Run Code Online (Sandbox Code Playgroud)
稍后它会执行各种过滤,具体取决于一些可配置的选项......
if something:
queryset = self.queryset.filter(foo=some_foo)
if another_thing:
queryset = self.queryset.filter(bar=some_bar)
Run Code Online (Sandbox Code Playgroud)
最后它执行查找...
try:
obj = queryset.get()
except ObjectDoesNotExist:
raise ValidationError('Does not exist')
Run Code Online (Sandbox Code Playgroud)
现在,由于过滤需要灵活的方式发生,some_foo或者some_bar变量可能不是正确的类型(例如,我们最终会得到一个空字符串,试图过滤整数字段.)所以它是可能的为此代码最终提出一个TypeError或一个ValueError.
那很好,我可以适当地处理这个案子,但是我从ORM合同中不清楚的是,我应该在什么时候期望提出这些例外.
.filter()声明中出现吗?....get()声明上?......为了回答最初的问题,当构建新的查询集时,在调用过滤器时会引发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'
Run Code Online (Sandbox Code Playgroud)
我还要补充一点,这种模式对我来说似乎具有误导性,因为它filter通常用于返回模型的列表/可迭代,而不是像get. 为了清楚和更容易地处理异常,我建议使用这种模式:
>>> 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'
Run Code Online (Sandbox Code Playgroud)
另一个额外的好处是,IIRC,克隆查询集的工作相对昂贵,因此您可以忽略该开销,同时使代码更清晰。回到你的问题,使用这种模式,毫无疑问会在哪里引发异常。
| 归档时间: |
|
| 查看次数: |
224 次 |
| 最近记录: |