django 内 A 接口将 request 转发到 B 接口, 获取返回, 再继续 A 接口的逻辑,都有哪些方法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
firejoke
V2EX    Django

django 内 A 接口将 request 转发到 B 接口, 获取返回, 再继续 A 接口的逻辑,都有哪些方法?

  •  
  •   firejoke 2019-05-17 15:56:42 +08:00 4517 次点击
    这是一个创建于 2404 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景:
    有一个接口, 接受请求返回一个状态信息
    另一个接口, 有一小段逻辑需要跟据状态信息做相应的处理
    不想重复写查询代码, 想着直接从 A 接口获取接口
    目前我试过的只有这一个 A.py

    from django.views.generic import View from django.http import JsonResponse, HttpResponseRedirect class A(View): def get(self, request, *args, **kwargs): return HttpResponseRedirect('/') def post(self, request, *args, **kwargs): result_dict = {'res': 'Test'} return JsonResponse(result_dict) 

    B.py

    import json from django.views.generic import View from django.http import JsonResponse, HttpResponseRedirect from .A import A class B(View): def get(self, request, *args, **kwargs): return HttpResponseRedirect('/') def post(self, request, *args, **kwargs): view = A.as_view() res = view(request) res = res.getvalue() res = json.loads(res)['res'] result_dict = {'res': self._logic(res)} return JsonResponse(result_dict) def _logic(): if res == 1: ...... return 1 elif == 2: ...... return 2 else: return 0 

    总感觉以前在哪看到过更规范的, 但忘了......

    第 1 条附言    2019-05-17 17:40:08 +08:00

    再具体一点
    A.py

    import json from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.base import View class A(LoginRequiredMixin, View): def get(self, request, *args, **kwargs): return HttpResponseRedirect('/') def post(self, request, *args, **kwargs): data = json.loads(request.POST.get('data', '{}')) result = {'res': _logic(data)} def _logic(d): ...... return res 

    B.py

    import json from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.base import View class A(LoginRequiredMixin, View): def get(self, request, *args, **kwargs): return HttpResponseRedirect('/') def post(self, request, *args, **kwargs): data = request.POST.get('data') data = json.loads(data) data.update({'check': 1}) post = QueryDict(mutable=True) post.update({'data': json.dumps(data)}) request.POST = post res = view(request) res = res.getvalue() res = json.loads(res) if res['statu'] == 0: ...... elif res['statu'] == 1: ...... else: ...... 
    14 条回复    2019-05-20 11:12:54 +08:00
    so1n
        1
    so1n  
       2019-05-17 16:07:15 +08:00
    不可以函数调用吗
    40huo
        2
    40huo  
       2019-05-17 16:25:15 +08:00
    非要用接口的话可以用 Django 带的 testclient
    firejoke
        3
    firejoke  
    OP
       2019-05-17 17:19:15 +08:00
    @so1n A 接口需要从 request 中获取是否已经登陆, 然后还要获取其他信息, 所以必须把 rrequest 传过去, 并且 request 还要修改一下携带的参数
    firejoke
        4
    firejoke  
    OP
       2019-05-17 17:40:58 +08:00
    @40huo 但是接口会检测登陆信息, 可以看我更新的附言
    noobsheldon
        5
    noobsheldon  
       2019-05-17 18:10:38 +08:00 via Android
    把 A 接口写成 middleware ?
    firejoke
        6
    firejoke  
    OP
       2019-05-17 18:24:05 +08:00
    @noobsheldon 是个思路, 给定一个路由范围, 凡是访问该范围内的路由, 都先走一遍 A 的逻辑, 然后将结果加在 request 里?
    可以, 也是一个 hack 方法~
    lusi1990
        7
    lusi1990  
       2019-05-17 18:24:28 +08:00 via Android
    面向切片? before request ? 继承? 我瞎猜的
    firejoke
        8
    firejoke  
    OP
       2019-05-17 18:31:33 +08:00
    @noobsheldon 不过这样的话, 我完全可以把 A 的逻辑单独摘出来放到 util 工具模块里去,
    我现在就想知道还有没有其他的可以在 B 接口访问 A 接口的方法, 万一以后还有其他这类场景, 而 A 的逻辑又太多不好摘出来, 就需要用到这类方法了
    firejoke
        9
    firejoke  
    OP
       2019-05-17 18:34:02 +08:00
    @lusi1990 继承没必要, 并不需要 A 的所有方法, 装饰器就和上面那位要写成 middleware 的思路差不多
    noobsheldon
        10
    noobsheldon  
       2019-05-17 18:48:37 +08:00 via Android
    @firejoke 分接口的目的不就是为了分开吗…如果有公用部分直接做成 utils (如你所言)
    firejoke
        11
    firejoke  
    OP
       2019-05-17 19:24:41 +08:00
    @noobsheldon 对了, 可以用 django 的 signal 信号机制, B 接口做完一部分逻辑, 发送一个信号, A 接口接收信号, 做处理, 再发送一个信号, B 接口再接收信号
    应用场景应该是 B 接口对 C 资源做出了改变, 而 A 接口需要根据 C 资源的状态更改 D 资源, 防止其他接口访问 D 资源的时候出现幻读之类的
    比如回帖, 更新帖子内容, 通知楼主, 可以把每一个逻辑单独做出来, 防止多个接口对同一个资源多次访问
    metamask
        12
    metamask  
       2019-05-18 10:40:32 +08:00
    感觉有些乱来

    view 的作用是处理 request response, 没必要这么引用

    如果 A 和 B 有代码可以共用,那么就抽出来做个 Mxin 就可以,没必要交叉

    随便改了下,类似这样
    https://gist.github.com/chrisguox/4de1a0cc586055d776be818ed636cf6e
    metamask
        13
    metamask  
       2019-05-18 10:45:04 +08:00
    如果更复杂的情况,

    如果是基本业务代码相同,可以考虑做成 parent view 然后继承;
    如果是业务代码共用,需要做部分处理,那么在类内做成 base func,用*kwarg 来做处理,

    代码相对来说可能比较漂亮些;

    另外作为 drf 吹( django rest framework ),推荐你使用。
    firejoke
        14
    firejoke  
    OP
       2019-05-20 11:12:54 +08:00
    @freakxx
    我也喜欢 rest 风格, 有考虑后面整个用 restframework 做(反正这小项目后端完全我一个人做主~)
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5340 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 06:04 PVG 14:04 LAX 22:04 JFK 01:04
    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