使用django开发服务器,他的objects.get(pk=xxx) 或者objects.get(abc=xxx)得到的结果只能有且只有一条,不然是会报 DoesNotExist 或者 MultipleObjectsReturned 的错误。
如果没有防范措施,那这服务器不就挂了? 就会有一个500error
其他类似的queryset的方法也会有raise各种错误。
这怎么办?每次使用get都要catch这两个错误吗?
或者保证数据参数的正确性?
请教各位pythoner
1
fishsjoy 2015-04-17 14:32:43 +08:00 1
get方法就是这么定义的。
主键的话不会出现MultipleObjectsReturned, DoesNotExist 可以用get_object_or_404。 当然,你可以用filter方法 |
2
happywowwow OP @fishsjoy 如果有这样的表 id user_id team_id 可能有时候有这样的需求 result = objects.get(user_id=123, team_id=321) 如果有两条或者没有的话,就会有错了
不过想了想,这里是可以用filter代替 除了还是需要判断一下 result = objects.filter(user_id=123, team_id=321) if not result: return '404' else: result = result[0] 这样吗? |
3
timonwong 2015-04-17 15:03:22 +08:00 1
@happywowwow
光是 filter 不够,因为还只是构建 QuerySet 阶段,这个 QuerySet 是 lazy 的,只有 get(), all(), slice 等操作才会触发。 你只有根据场景,catch IndexError (using slice) 或 DoesNotExist (using get()) 异常, 或者,使用 first() |
4
happywowwow OP @timonwong 啊,上面回复是写错了,应该还有一个.all()
我主题里的问题主要是每次使用这种会抛出异常的query方法,是不是都要放在try里面? 不然好像也没什么办法保证服务器不500? 除非除非,构建鲁棒的写入数据库的操作? 但感觉这难免有异常数据 |
5
virusdefender 2015-04-17 15:23:18 +08:00 1
get本来就是为了获取单条数据用的,如果你用filter的话,不也是需要判断获取的数据数据么,要不直接results[0]也会异常的。
|
6
yueyoum 2015-04-17 15:24:21 +08:00 2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!
这个和 django orm 有毛关系啊!!!!!!!!!!!! python 语言内建异常机制, 这是一种风格和哲学。 python代码就要这么写。 按照你的意思,是不是 python 的 buildin function: open 设计是错误的。 我 open一个不存在的文件, 居然会引发异常, 每次都要 try catch。。。 用 C 也好麻烦啊, 每次都要 判断 open/fopen 的返回值 |
7
yueyoum 2015-04-17 15:26:35 +08:00
上面补充一下 : 以 read 模式 open 一个不存在的文件
|
8
happywowwow OP @virusdefender
@yueyoum 感谢两位 所以那些使用 get 的时候需要 catch 这两个 exception ,而 filter 出来的结果需要做一定判断,这是必不可少的了。 我之前的疑惑是有没有办法减少这样的操作,但看来是没有的。 为了服务器的鲁棒,使用get的时候还是都得加上 try catch 的了。 |
9
ericls 2015-04-17 16:33:53 +08:00 1
|
10
happywowwow OP @ericls
感谢~ 1、我知道这个api 2、如上一个需求,如果有这样的表三个字段,分别是id user_id team_id 可能有时候有这样的需求 result = objects.get(user_id=123, team_id=321) 如果有两条或者没有的话,就会有错了。这个表中user_id 字段和 team_id 都不是唯一的,但某一个user_id 或者 team_id 对应的结果理论上只能有一条(或没有),但出现多条的情况下,get_object_or_404 这个接口只能处理了 DoesNotExist 这个exception,但还是会报MultipleObjectsReturned。 3、我这rest api设计里面,返回json格式。是的,使用类似 get_object_or_404 这种封装的接口可能是我需要的,而这个封装可能需要我自己去做了~ |
11
chenxytw 2015-04-17 17:08:12 +08:00
话说。。。为什么不设置成unique = =也就从理论上避免了多条数据了出现
|
12
happywowwow OP @chenxytw
啊哈,你没有看懂上面的需求吗? 如果有这样的表三个字段,分别是 id user_id team_id 0 1 1 1 1 2 2 2 1 3 1 2 4 3 1 5 1 3 1、只有id是唯一的 2、单个的 user_id,team_id都是可以重复的,也就不能是unique的,但是某一对(user_id, team_id)只能对应一条记录 |
13
happywowwow OP @timonwong
啊哈,你说这个 filter 出来的 queryset 是 lazy 是没错的,但 filter 的结果在 if 比较的时候也会触发,不一定需要 all() slice 只有 filter 的 queryset 在bool 比较的时候也会触发。 参见 https://docs.djangoproject.com/en/1.5/ref/models/querysets/#when-querysets-are-evaluated 啊,所以之前我那没有 .all() 的代码也是可以执行的。。。 |
14
happywowwow OP |
15
Catstyle 2015-04-17 17:33:57 +08:00 1
啊哈,你需要的是unique_with?
|
16
Catstyle 2015-04-17 17:36:12 +08:00
哦,django orm里面是unique_together
|
17
happywowwow OP @Catstyle 感谢! 有这个加了就更好了
|
18
chenxytw 2015-04-18 10:40:02 +08:00 1
@happywowwow
可以设置联合约束呀。。。。 已经建好的表 ALTER TABLE `table` ADD UNIQUE `unique_together`(`user_id `, `team_id`); 新表 CREATE TABLE `table` (id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, team_id INT, UNIQUE `team_and_user_unique` (`user_id`, `team_id`)); |
19
happywowwow OP @chenxytw 是的 现在就是这么对表做了处理。。。省得出错。。
|
20
happywowwow OP @happywowwow 测试
|
21
eric6356 2015-05-08 11:37:58 +08:00
|
24
eric6356 2015-05-08 11:39:57 +08:00
|
25
happywowwow OP @happywowwow test
|
26
happywowwow OP |
27
happywowwow OP @happywowwow test
|
28
happywowwow OP @happywowwow test111
|
29
happywowwow OP @eric6356 666
|
30
happywowwow OP @eric6356 77777
|