文章内容

2024/12/17 0:51:59,作 者: 黄兵

TypeError: 'builtin_function_or_method' object is not iterable

最近在编写 Python 代码的时候,出现了如下错误:

  File "E:\Code\project\app\templates\document\index.html", line 40, in block 'content'

    {% for child in item.items %}

TypeError: 'builtin_function_or_method' object is not iterable

具体错误代码如下:

<div class="d-grid mt-3 landing-row-group">
    {% for child in item.items %}
        <div class="layout-flex-direction-column h-auto">
            <a class="card p-4 card-flush" href="{{ child.link_text }}">
                <div class="card-header p-0 min-h-lg-auto">
                    <h3 class="fs-5 card-title mt-0">{{ child.title }}</h3>
                </div>
                <div class="card-body p-0">
                    <div class="text-gray-700">{{ child.sub_title }}</div>
                </div>
            </a>
        </div>
    {% endfor %}
</div>

后端代码如下:

@document.route('/', methods=['GET'])
def get_document():
    if request.method == 'GET':
        get_url = request.path
        get_meta = Meta.query.filter_by(uri=get_url).first()
        # 查询文档首页菜单内容
        get_category_type = DocumentCategoryType.query.filter_by(code='home').first_or_404()
        get_menu = DocumentCategory.query.filter_by(type_id=get_category_type.id).filter(
            DocumentCategory.parent_id == None).order_by(DocumentCategory.rank).all()
        temp_list = []
        for menu in get_menu:
            child_menu = []
            get_child_menu = DocumentCategory.query.filter_by(parent_id=menu.id).all()
            for child in get_child_menu:
                child_menu.append({'name': child.name, 'link_text': child.link_text})
            temp_list.append({'name': menu.name, 'link_text': menu.link_text, 'top_menu': menu.is_top_menu,
                              'expandable_menu': menu.is_expandable_menu, 'children': child_menu})
        g.menu = temp_list
        get_menu_by_url = DocumentCategory.query.filter_by(link_text=get_url).first()
        get_introduction = DocumentCategoryIntroduction.query.filter_by(category_id=get_menu_by_url.id).all()
        introduction = []
        for introduction_item in get_introduction:
            get_introduction_items = DocumentIntroductionItem.query.filter_by(
                introduction_id=introduction_item.id).all()
            introduction_items = []
            for child in get_introduction_items:
                introduction_items.append({'title': child.title, 'link_text': child.link_text,
                                           'sub_title': child.sub_title})
            introduction.append({'title': introduction_item.section_title,
                                 'sub_title': introduction_item.section_sub_title, 'items': introduction_items})
        print(introduction)
        return render_template('document/index.html', meta=get_meta, type=get_category_type.code,
                               introduction=introduction, menu=get_menu_by_url)
    else:
        abort(405)

出现问题的原因:

TypeError: 'builtin_function_or_method' object is not iterable 表示在模板中 item.items 被当作一个不可迭代的对象,而实际上它被错误地指向了一个方法,而不是一个列表。

上面的代码:items 是一个键(key),不是一个方法,但 Flask 模板渲染时可能误将 item.items 解析为 dict.items 这个内置方法。

introduction_items = []
introduction.append({'title': introduction_item.section_title,
                     'sub_title': introduction_item.section_sub_title, 'items': introduction_items})

在这种情况下,items 是列表类型,没有问题,但在模板渲染时可能由于模板引擎将 itemsdict.items() 发生混淆,导致冲突。

解决方案:

将键名 items 改为其他名称,例如 content_items,避免与 dict.items() 冲突。

修改代码:

introduction_items = []
introduction.append({
    'title': introduction_item.section_title,
    'sub_title': introduction_item.section_sub_title,
    'content_items': introduction_items
})

然后在模板中对应修改为:

{% for child in item.content_items %}
    <div class="layout-flex-direction-column h-auto">
        <a class="card p-4 card-flush" href="{{ child.link_text }}">
            <div class="card-header p-0 min-h-lg-auto">
                <h3 class="fs-5 card-title mt-0">{{ child.title }}</h3>
            </div>
            <div class="card-body p-0">
                <div class="text-gray-700">{{ child.sub_title }}</div>
            </div>
        </a>
    </div>
{% endfor %}

这样就解决了上面存在的问题。


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - TypeError: 'builtin_function_or_method' object is not iterable

分享到:

发表评论

评论列表