Django view 怎样可以先返回结果,再执行一部分其他逻辑? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
btv2bt
V2EX    Django

Django view 怎样可以先返回结果,再执行一部分其他逻辑?

  •  
  •   btv2bt 2020-02-28 13:56:12 +08:00 4969 次点击
    这是一个创建于 2126 天前的主题,其中的信息可能已经有所发展或是发生改变。

    除去 Celery 的话,还有其他的办法么?

    第 1 条附言    2020-02-28 14:29:38 +08:00
    具体场景:
    Windows 环境,API 接收到请求之后(随后告诉请求方参数已收到),根据参数执行一段 cmd 命令,命令执行完后再把结果返回给请求方
    第 2 条附言    2020-02-28 14:44:28 +08:00
    似乎描述的不太清楚,思路是比较明确的,像站长说的那样;

    只是不确定用哪种具体的 库 /方法 来实现
    第 3 条附言    2020-02-28 14:59:23 +08:00
    现在方案是站长说的那种,再具体些就是:

    A 发请求到 B 的某个 API,
    B 收到后返回 任务 id,
    B 执行任务,
    结果返回至 A 的结果收集接口


    此处请教的是如何实现 先返回 id,再执行后续逻辑;
    起初描述的是先返回结果,可能造成了一部分疑问
    32 条回复    2020-06-27 01:18:36 +08:00
    iConnect
        1
    iConnect  
       2020-02-28 13:59:57 +08:00 via Android
    async 在一个线程里可以,thread 也可以在多个线程里
    btv2bt
        2
    btv2bt  
    OP
       2020-02-28 14:16:33 +08:00
    @iConnect 不是很明白,方便细说一下么
    Livid
        3
    Livid  
    MOD
    PRO
       2020-02-28 14:18:08 +08:00
    如果你可以说一下具体的应用场景,然后可能会有其他解决方法。
    qile1
        4
    qile1  
       2020-02-28 14:24:44 +08:00 via Android
    楼主是不是想,直接返回保存成功,另一个线程后台保存数据到数据库?
    btv2bt
        5
    btv2bt  
    OP
       2020-02-28 14:25:26 +08:00
    @Livid Windows 环境,API 接收到请求之后(随后告诉请求方参数已收到),根据参数执行一段 cmd 命令,命令执行完后再把结果返回给请求方
    btv2bt
        6
    btv2bt  
    OP
       2020-02-28 14:28:31 +08:00
    @qile1 嗯,类似,具体可以看上一条回复
    woodensail
        7
    woodensail  
       2020-02-28 14:30:44 +08:00
    感觉是类似长连接的需求啊,这种做法服务端和客户端都得改造,代价太大了。
    改用离线计算的方式来实现?
    Livid
        8
    Livid  
    MOD
    PRO
       2020-02-28 14:33:39 +08:00   1
    那么你可能需要这样来实现它:

    API 收到请求之后,返回一个任务 ID,然后用异步任务去执行,执行完毕之后根据分配的任务 ID 写入结果。

    请求方根据任务 ID 发起另外一个或者多个请求去拿结果,在异步任务没有完成之前会拿到「任务还没有执行完毕」,完成之后拿到的就是异步任务写入的结果。
    cominghome
        9
    cominghome  
       2020-02-28 14:36:49 +08:00
    站长的方式靠谱。典型的异步任务流程。
    btv2bt
        10
    btv2bt  
    OP
       2020-02-28 14:38:41 +08:00
    @woodensail 离线计算怎么讲;
    的确类似长链接,现在还没开始写…所以也还好,不知道有啥建议么

    说到这,想起感觉可以中间用个 redis 之类的来处理下?
    btv2bt
        11
    btv2bt  
    OP
       2020-02-28 14:41:10 +08:00
    @Livid
    @cominghome en ,现在思路就是这样的
    只是不知道用哪种具体的方式来实现 异步任务
    woodensail
        12
    woodensail  
       2020-02-28 14:41:28 +08:00
    站长给离线计算的方案了,另外就是注意离线计算结果的保存和销毁策略。可以考虑比如定时 1 小时销毁;或者按账号,每个账号只保留最新的一个计算结果。
    Livid
        13
    Livid  
    MOD
    PRO
       2020-02-28 14:42:49 +08:00
    不过貌似 Django 也考虑了这种情况,仅供参考吧:

    https://stackoverflow.com/a/15569619
    mimzy
        14
    mimzy  
       2020-02-28 14:50:00 +08:00
    有类似场景,用了 Celery,前端轮询结果,感觉轮询这里不太优雅
    fengshils
        15
    fengshils  
       2020-02-28 14:50:06 +08:00
    使用 celery 返回任务 id,在定时去拿结果可好
    est
        16
    est  
       2020-02-28 14:52:12 +08:00
    具体是可以不用其他库实现的。

    但是 LZ 说这个需求不对。你要的是浏览器配合。
    676529483
        17
    676529483  
       2020-02-28 14:55:58 +08:00
    一般都用 celery 做吧,如果用最新的 django3.0,可以考虑下 django_simple_backend 这个库
    btv2bt
        18
    btv2bt  
    OP
       2020-02-28 15:01:06 +08:00
    @mimzy 结果回写到 db,结果查询请求单独写个接口更合适些

    @fengshils
    btv2bt
        19
    btv2bt  
    OP
       2020-02-28 15:02:13 +08:00
    @676529483 嗯,只是不太想在 Windows 上折腾 celery

    服务器这边用了 celery 4,客户端这边 windows 又不支持 4,就有点蛋疼
    wuwukai007
        20
    wuwukai007  
    &nbs;  2020-02-28 15:10:43 +08:00 via Android
    别用 celery 在 windows 上,用了还要在配个 redis,徒增成本
    btv2bt
        21
    btv2bt  
    OP
       2020-02-28 15:15:12 +08:00
    @wuwukai007 是的啊,所以想问有没其他办法…

    是不是换 tornado 就好了……
    wuwukai007
        22
    wuwukai007  
       2020-02-28 15:36:06 +08:00 via Android
    曲线一点,用 apscheduler 做异步任务,建张状态表,直接返回前端任务启动成功与否,然后任务里面写状态,前端 api 访问状态,完成后在查表返回结果
    xgq89757
        23
    xgq89757  
       2020-02-28 15:40:13 +08:00 via iPhone
    @btv2bt django 的 5 大中间件不知道能不能满足你的需求。
    btv2bt
        24
    btv2bt  
    OP
       2020-02-28 15:52:45 +08:00
    @xgq89757 提醒了我,谷歌了一下 django after response,有两种思路:
    * 有一个第三方库
    * 重载一个 HttpResponse

    我试一下去,谢谢啦
    robinlovemaggie
        25
    robinlovemaggie  
       2020-02-28 16:01:33 +08:00
    参考各大话费充值系统和类银行转账系统的事务模型。
    ytymf
        26
    ytymf  
       2020-02-28 16:50:05 +08:00
    不想用 celery,还有 huey,不过也要 redis
    xgq89757
        27
    xgq89757  
       2020-02-29 18:22:59 +08:00 via iPhone
    @btv2bt 可以用 process_response 这个,django 自带的,执行视图函数结束之后会调用这个
    btv2bt
        28
    btv2bt  
    OP
       2020-02-29 22:41:06 +08:00 via Android
    @xgq89757 我试了一下重构 response,但还是会阻塞,用了一个第三方库,没这个问题了;
    process response 的话,会阻塞吗
    bnm965321
        29
    bnm965321  
       2020-03-12 10:18:37 +08:00
    重载 response 会堵塞,因为没有释放这个 server 不能继续接客
    btv2bt
        30
    btv2bt  
    OP
       2020-03-13 08:04:43 +08:00 via Android
    @bnm965321 嗯,用了 after response 这个东西,看了下代码应该是有个单独的线程在处理队列里的东西
    Vieufoux
        31
    Vieufoux  
       2020-06-25 14:42:20 +08:00
    @btv2bt 所以楼主最后采用了哪种方案?
    btv2bt
        32
    btv2bt  
    OP
       2020-06-27 01:18:36 +08:00 via Android
    @Vieufoux after response 这个第三方库
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2991 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 12:11 PVG 20:11 LAX 04:11 JFK 07:11
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86