将会话从模板视图传递给python请求api调用

Roh*_*ain 7 python django

我想使用请求库从我的Django TemplateView进行多个内部REST API调用.现在我想将会话也从模板视图传递到api调用.建议的方法是什么,记住性能.

现在,我正在模板视图中cookie从当前request对象中提取,并将其传递给requests.get()requests.post()调用.但问题是,我必须将request对象传递给我的API客户端,这是我不想要的.

这是我用来路由我的请求的当前包装器:

def wrap_internal_api_call(request, requests_api, uri, data=None, params=None, cookies=None, is_json=False, files=None):
    headers = {'referer': request.META.get('HTTP_REFERER')}
    logger.debug('Request API: %s calling URL: %s', requests_api, uri)
    logger.debug('Referer header sent with requests: %s', headers['referer'])
    if cookies:
        csrf_token = cookies.get('csrftoken', None)
    else:
        csrf_token = request.COOKIES.get('csrftoken', None)

    if csrf_token:
        headers['X-CSRFToken'] = csrf_token
    if data:
        if is_json:
            return requests_api(uri, json=data, params=params, cookies=cookies if cookies else request.COOKIES, headers=headers)
        elif not files:
            return requests_api(uri, data=data, params=params, cookies=cookies if cookies else request.COOKIES, headers=headers)
        else:
            return requests_api(uri, data=data, files=files, params=params, cookies=cookies if cookies else request.COOKIES,
                                headers=headers)
    else:
        return requests_api(uri, params=params, cookies=cookies if cookies else request.COOKIES, headers=headers)
Run Code Online (Sandbox Code Playgroud)

基本上我想摆脱那个request参数(第一个参数),因为然后调用它我要继续将request对象从TemplateViews 传递到内部服务.另外,如何在多个呼叫之间保持持久连接?

e4c*_*4c5 5

REST 与直接调用视图

虽然 Web 应用程序可以对其自身进行 REST API 调用。这不是 REST 的设计目的。考虑以下内容:https://docs.djangoproject.com/ja/1.9/topics/http/middleware/

Django 请求响应生命周期

正如您所看到的,django 请求/响应周期有相当多的开销。添加到此网络服务器和 wsgi 容器的开销。在客户端,您有与请求库相关的开销,但请稍等,客户端也恰好是同一个 Web 应用程序,因此它也成为 Web 应用程序开销的一部分。还有持久性的问题(我很快就会谈到)。

最后但并非最不重要的一点是,如果您有 DNS 循环设置,您的请求实际上可能会在返回同一服务器之前先通过网络发出。有一种更好的方法,直接调用视图。

无需调用其余 API 即可调用另一个视图非常简单

 other_app.other_view(request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

这已经在链接中讨论过几次,例如Django Call Class based view from another class based viewCan I call a view from inside another view? 所以我就不详细说明了。

持续请求

持久性 http 请求(谈论 python 请求而不是 django.http.request.HttpRequest)通过会话对象进行管理(同样不要与 django 会话混淆)。避免混淆确实很困难:

Session 对象允许您在请求之间保留某些参数。它还会在 Session 实例发出的所有请求中保留 cookie,并将使用 urllib3 的连接池。因此,如果您向同一主机发出多个请求,底层 TCP 连接将被重用,这可能会导致性能显着提高

对 django 视图的不同点击可能来自不同的用户,因此您不希望内部 REST 调用重复使用相同的 cookie。另一个问题是 python 会话对象无法在 django 视图的两次不同点击之间持久化。套接字通常无法序列化,这是将它们放入 memcached 或 redis 的要求。

如果您仍想坚持使用内部 REST

我认为 @julian 的答案显示了如何避免将 django 请求实例作为参数传递。