首页 > 解决方案 > Flask 和 Jinja 模板抛出错误:'Cursor' 类型的对象没有 len()

问题描述

我看过类似的错误,但不幸的是我看不到它们是如何被修复的。我对 Flask 很陌生(一般是 Python)。我为我的数据库构建了一个小搜索功能,搜索工作正常。除非那里没有与搜索参数匹配的内容。然后我得到一个空行。相反,我想抛出一条消息,说“未找到结果”或类似的消息。

所以在 app.py 文件中我有这个搜索功能:

@app.route("/search", methods=["GET", "POST"])
def search():
    query = request.form.get("query")
    questions = list(mongo.db.questions.find({"$text": {"$search": query}}))    
    return render_template("questions.html", questions=questions)

这确实有效。我可以找到带有各种文本等的帖子并适当地显示它们。

在我的 HTML 文件中,我运行一个返回搜索的表单:

 <form action="{{ url_for('search') }}" method="POST">
<input type="text" name="query" id="query" minlength="3" class="validate" required>
<button type="submit">Search</button>
 </form>

这一切目前都有效(我从这段代码中删除了正文部分,但这应该是让它工作所需的最低限度)。

现在,在此页面上,我显示了该用户可用的所有问题。它们都在一个 for 循环中:

  <ul class="collapsible">
        {% for question in questions %}
        <li></li> 
  </ul>

ETC...

在那个 for 循环之上我放了:

{% if questions|length > 0 %}

然后在底部</ul>我放了这个:

{% else %}
<h3>No Questions found matching that search</h3>
{% endif %}

只有当我把{% if questions|length > 0 %}做的事情停止工作并且我得到那个长度错误时。即使在搜索和看到类似的帖子之后,我也真的不知道如何解决这个问题。

Full error traceback:
Traceback (most recent call last):
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\pauld\OneDrive\Documents\GitHub\pros_and_cons\app.py", line 26, in get_questions
    return render_template("questions.html", questions=questions)
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\templating.py", line 137, in render_template
    return _render(
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\flask\templating.py", line 120, in _render
    rv = template.render(context)
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\jinja2\environment.py", line 1090, in render
    self.environment.handle_exception()
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\jinja2\environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "C:\Users\pauld\AppData\Roaming\Python\Python38\site-packages\jinja2\_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\pauld\OneDrive\Documents\GitHub\pros_and_cons\templates\questions.html", line 1, in top-level template code
    {% extends "base.html" %} {% block content %}
  File "C:\Users\pauld\OneDrive\Documents\GitHub\pros_and_cons\templates\base.html", line 100, in top-level template code
    {% block content %} {% endblock %}
  File "C:\Users\pauld\OneDrive\Documents\GitHub\pros_and_cons\templates\questions.html", line 23, in block "content"
    {% if questions|length > 0 %}
TypeError: object of type 'Cursor' has no len()

标签: pythonflasksearchjinja2

解决方案


可能是您缺少{% endfor %}标签

<ul class="collapsible">
  {% for question in questions %}
    <li></li>

  {% endfor %} {# -- the missing tag -- #}

</ul>

无论如何,jinja2已经提供了另一种使用循环的方法,它将ifandfor循环结合在一起:{% for .. %} .. {% else %} .. {% endfor %}

参考这个话题https://jinja.palletsprojects.com/en/2.11.x/templates/#for

试试下面的代码:

<ul class="collapsible">

  {% for question in questions %}

    <li>{{ question.. }}</li>

  {% else %}

    <li>No Questions found matching that search</li>

  {% endfor %}
</ul>

更新 1

而不是list在您的 search()函数中返回 a ,请尝试

    # questions = list(mongo.db.questions.find({"$text": {"$search": query}})) 
    # print(questions) 
    # it will return a list object

    questions = mongo.db.questions.find({"$text": {"$search": query}})  # remove 'list()' function
    # print(questions)
    # it will return the appropriate object : Cursor

更新 2

尝试

{% if questions.count() > 0 %}

代替

{% if questions|length > 0 %}

推荐阅读