You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django+Python Web应用中,如何正确将上下文传递给Playwright函数以实现模板变量渲染?

在Django+Python Web应用中,如何正确将上下文传递给Playwright函数以实现模板变量渲染?

看起来你遇到的问题核心是:用Playwright打开页面时,没有正确传递Django的会话(Session)信息,导致服务器端无法加载你之前存在session里的上下文数据,所以模板变量就渲染不出来啦。我来帮你一步步排查解决~

问题根源拆解

你正常访问/coaches/image视图时,浏览器带着有效的Session ID cookie,Django能通过这个ID从服务器端找到对应的session数据,所以request.session里有你需要的squad等上下文变量,模板能正常渲染。但你当前给Playwright传递的session_data只包含了cookie的名称、值和URL,缺少了Django识别session必需的关键属性(比如domain、path、httponly),导致Playwright访问页面时,Django无法关联到你原来的会话,自然拿不到上下文数据,模板变量就空了。

具体解决步骤

1. 正确构造Playwright所需的Session Cookie

Django的Session ID cookie有严格的属性要求,必须和Django设置的完全匹配才能被识别。修改你的generate视图代码,完整复制Session Cookie的所有必要属性:

def generate(request):
    # 获取Django的Session Cookie名称(默认是"sessionid",如果自定义过就替换成你的)
    session_cookie_name = settings.SESSION_COOKIE_NAME
    session_cookie_value = request.COOKIES.get(session_cookie_name)
    
    if not session_cookie_value:
        return HttpResponse("无有效会话信息", status=400)
    
    # 构造符合Playwright要求的Cookie字典,完全匹配Django的Cookie属性
    session_cookie = {
        "name": session_cookie_name,
        "value": session_cookie_value,
        "domain": request.META['HTTP_HOST'],
        "path": "/",
        "httponly": True,
        "secure": request.is_secure(),  # HTTPS环境下设为True,HTTP设为False
        "same_site": "Lax"  # 和Django默认的SameSite设置保持一致
    }
    
    # 构造完整的目标URL(必须带http/https协议)
    protocol = "https" if request.is_secure() else "http"
    target_url = f"{protocol}://{request.META['HTTP_HOST']}/coaches/image"
    
    # 注意这里要传Cookie列表给Playwright
    image_bytes = take_screenshot_from_url(target_url, [session_cookie])
    # 后续处理图片返回的逻辑...

2. 确保Playwright加载页面的完整性

修改你的take_screenshot_from_url函数,等待页面完全加载后再截图,避免因加载不完整导致的渲染问题,还可以临时关闭无头模式调试:

def take_screenshot_from_url(url, session_cookies):
    with sync_playwright() as playwright:
        webkit = playwright.webkit
        # 临时关闭无头模式,方便手动查看Playwright打开的页面状态
        browser = webkit.launch(headless=False)
        browser_context = browser.new_context(device_scale_factor=2)
        # 传入构造好的Cookie列表
        browser_context.add_cookies(session_cookies)
        page = browser_context.new_page()
        # 等待页面网络空闲后再操作,确保所有资源加载完成
        page.goto(url, wait_until="networkidle")
        # 可选:打印页面HTML,检查模板是否真的没渲染变量
        # print(page.content())
        screenshot_bytes = page.locator("#squad-image").screenshot()
        browser.close()
        return screenshot_bytes

3. 验证Session数据是否已持久化

在你正常设置session数据的视图里,如果你修改了request.session的内容,一定要调用request.session.save(),否则数据不会被保存到服务器,Playwright访问时自然拿不到这些数据。

4. 调试排查小技巧

  • 关闭Playwright的无头模式后,手动查看打开的页面,有没有显示Django的错误页面(比如500、403),或者控制台有没有JS报错。
  • 打印page.content()的内容,看看模板渲染后的HTML里,变量位置是不是空的,还是有Django的模板标签残留(如果是后者,说明模板没被渲染,大概率是URL访问错了)。

关键原理提醒

Django的Session是服务器端存储的,Cookie里只存了Session ID。你不需要把上下文数据直接传给Playwright,只要让Playwright的请求带着正确的Session ID Cookie,Django就会自动加载对应的session数据到request.session,你原来的image视图代码(把request.session数据放到context里)就能正常工作,模板也能渲染变量了。

备注:内容来源于stack exchange,提问作者bytejunkie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:48:09