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

Django搜索功能报错:'NoneType' object has no attribute 'strip'

CS50W Wiki搜索功能错误修复

问题描述

开发Django搜索功能时遇到AttributeError: 'NoneType' object has no attribute 'strip',需求为:查询内容与条目名称完全匹配时跳转至条目页,不匹配时展示所有包含该查询作为子串的条目(如查询ytho显示Python)。

错误回溯

Traceback (most recent call last):
  File "C:\Users\anshi\.virtualenvs\storefront-bp3LZ8Cr\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\anshi\.virtualenvs\storefront-bp3LZ8Cr\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\Python\Py Projects\CS50 attempt 00\wiki\encyclopedia\views.py", line 70, in search
    content = converter(search_title)
  File "D:\Python\Py Projects\CS50 attempt 00\wiki\encyclopedia\views.py", line 19, in converter
    html = Markdowner.convert(content)
  File "C:\Users\anshi\.virtualenvs\storefront-bp3LZ8Cr\lib\site-packages\markdown\core.py", line 248, in convert
    if not source.strip():
AttributeError: 'NoneType' object has no attribute 'strip'
[21/Dec/2022 02:09:18] "POST /search/ HTTP/1.1" 500 72472

原代码问题分析

View层代码

def search(request):
    if request.method == 'POST':
        search_title = request.POST['q']
        
        content = converter(search_title)

        if search_title is not None:
            return render(request, "encyclopedia/entry.html", {
                    "entry": content,
                    "entryTitle": search_title
            })

        else:
            entries = util.list_entries()
            search_pages = []
            for entry in entries:
                if search_title in entries:
                    search_pages.append(entry)
            return render(request, "encyclopedia/search.html",{
                "entries": search_pages
                })
  1. 逻辑判断失效:if search_title is not None永远为真(POST参数不会为None,最多是空字符串),导致永远无法进入搜索结果分支。
  2. 转换器调用时机错误:直接调用converter(search_title),当条目不存在时,转换器内部获取的内容为None,传给Markdown工具时触发strip()调用错误。
  3. 子串匹配逻辑错误:if search_title in entries是检查查询内容是否在条目列表中,而非检查查询内容是否是条目名称的子串。

HTML表单代码

<form action="{% url 'search' %}" method="POST">
    {% csrf_token %}
    <input class="search" type="text" name="q" placeholder="Search Encyclopedia">
</form>

表单本身无问题,需配合修正后的后端逻辑使用。

修复方案

修正View层代码

def search(request):
    if request.method == 'POST':
        search_title = request.POST['q'].strip()
        # 先调用CS50W提供的工具函数检查条目是否存在
        entry_content = util.get_entry(search_title)
        
        if entry_content:
            # 条目存在时再转换Markdown并渲染详情页
            content = converter(search_title)
            return render(request, "encyclopedia/entry.html", {
                "entry": content,
                "entryTitle": search_title
            })
        else:
            # 条目不存在时,搜索包含子串的条目(不区分大小写)
            entries = util.list_entries()
            search_pages = []
            query_lower = search_title.lower()
            for entry in entries:
                if query_lower in entry.lower():
                    search_pages.append(entry)
            return render(request, "encyclopedia/search.html", {
                "entries": search_pages
            })

修正converter函数(处理空内容情况)

确保转换器在内容不存在时返回合法值,避免Markdown转换报错:

def converter(title):
    content = util.get_entry(title)
    if not content:
        return ""  # 或返回自定义提示内容
    html = Markdowner.convert(content)
    return html

关键修复点

  1. 先判断条目存在性:调用util.get_entry获取原始内容,确认存在后再进行Markdown转换。
  2. 修正子串匹配逻辑:将查询和条目名称统一转为小写,实现不区分大小写的子串匹配。
  3. 前置空值处理:在转换器中提前判断内容是否为空,避免传递None给Markdown工具。

内容的提问来源于stack exchange,提问作者anshith S.Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:25:42