【问题标题】:Django: Get page title from middlewareDjango:从中间件获取页面标题
【发布时间】:2019-07-07 12:03:54
【问题描述】:

我编写了一个小型中间件来跟踪用户活动:

class AccessLogs(object):

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    response = self.get_response(request)

    if "/media/" not in request.path:
        try:
            ActivityLog(user=request.user, pageURL=request.path).save()
        except Exception as e:
            print(e)

    return response

有没有什么方法可以使用这种中间件方法获取页面的标题?我在这里查找了很多东西,例如模板视图、自定义响应,但似乎没有任何效果。是否有任何类或函数可以检索访问页面的标题?任何帮助将不胜感激。

编辑:我正在寻找的是一种获取用户刚刚访问的页面标题的方法,因此我可以将其与数据库中的其他信息一起存储在此中间件中。

【问题讨论】:

  • 页面的标题是视图的属性吗?你能展示一个你想获得标题的示例视图吗?
  • @IainShelvington:我认为是响应中的<title>...</title> 标签。
  • request.resolver_match.view_name 将包含路径/url 中设置的视图名称。如果这足够了,我建议使用它

标签: python django dom django-middleware


【解决方案1】:

是的,虽然不是所有的响应都是 HTTP 响应,也不是所有的 HTTP 响应本身都有标题。但我们可以尽最大努力从响应中获取标题。

为此,我们可以使用 HTML 抓取工具,例如 beautifulsoup4 [PiPy]。您可能需要安装:

pip install <b>beautifulsoup4 lxml</b>

然后我们可以通过以下方式从响应中获取标题:

from bs4 import BeautifulSoup

def get_response_title(response):
    try:
        soup = BeautifulSoup(response.content, 'lxml')
        return soup.find('title').getText()
    except AttributeError:
        return None

因此,您可以在中间件中使用它,例如:

类访问日志(对象):

    def __call__(self, request):
        response = self.get_response(request)
        如果 '/media/' 不在 request.path 中:
            尝试:
                title = get_response_title(response)
                ActivityLog(user=request.user, title=title, pageURL=request.path).save()
            例外为 e:
                打印(e)

话虽如此,作为@IainShelvington says,它会减慢处理速度,因为我们每次都会查看响应。一些 Web 开发框架,如 Yesod [yesodweb.com] 会将标题设置为在处理程序中传递的变量,从而更方便地检测它。

【讨论】:

  • 只是补充一点,如果您关心性能,您可能不应该这样做。解析每个响应只是为了获得标题有点矫枉过正。
  • 我希望避免 html 报废,但现在我会处理这个问题。非常感谢!
  • @IainShelvington:这确实有点矫枉过正,我同意这一点。有点可悲的是,Django 没有一个处理程序对象,它旨在收集标题,然后渲染它,例如 Yesod 的 Handler Widget monad。
  • @WillemVanOnsem 我同意,要在 Django 中正确处理此问题,您可能必须创建另一个“框架”或添加到 Django 顶部的每个视图中的 Mixin,以便为每个响应添加该标题但这是很多样板
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 1970-01-01
相关资源
最近更新 更多