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

Django中用Raw SQL实现作者与对应书籍同页展示的问题排查

问题分析与解决

实现思路的合理性

用Raw SQL处理复杂查询逻辑是完全可行的——当Django ORM无法满足你的业务需求时,直接使用原生SQL是官方认可的方案,这个思路没问题。你现在的问题出在查询结果的处理逻辑或者SQL语句本身上,导致数据被覆盖或遗漏。

常见错误点及修复方案

1. SQL语句未正确关联/返回完整数据

首先检查你的Raw SQL是否正确关联了Author和Book表,并且返回了所有作者及其书籍。比如如果用了JOIN而非LEFT JOIN,没有书籍的作者会被排除;如果没加排序,结果集的顺序混乱会增加聚合难度。

推荐使用类似的SQL:

SELECT a.id AS author_id, a.name AS author_name, b.id AS book_id, b.title AS book_title
FROM author a
LEFT JOIN book b ON a.id = b.author_id
ORDER BY a.id

这条语句会返回所有作者,包括没有书籍的作者,且同一作者的所有书籍会连续排列,方便后续聚合。

2. 查询结果处理时未正确聚合数据

你只拿到最后一位作者的数据,大概率是处理结果时覆盖了之前的作者数据。比如错误的处理方式:

# 错误示例:每次循环都重置变量,最后只保留最后一条数据
author_data = {}
for row in query_results:
    author_data["name"] = row.author_name
    author_data["books"] = [row.book_title]

正确的做法是按作者ID分组,将同一作者的书籍聚合到列表中:

from django.db import connection

def preview(request):
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT a.id AS author_id, a.name AS author_name, b.id AS book_id, b.title AS book_title
            FROM author a
            LEFT JOIN book b ON a.id = b.author_id
            ORDER BY a.id
        """)
        rows = cursor.fetchall()

        # 聚合作者与书籍数据
        author_books = {}
        for row in rows:
            author_id, author_name, book_id, book_title = row
            # 首次遇到该作者时初始化结构
            if author_id not in author_books:
                author_books[author_id] = {
                    "name": author_name,
                    "books": []
                }
            # 若书籍存在则添加到列表(处理无书籍的作者)
            if book_id is not None:
                author_books[author_id]["books"].append({
                    "id": book_id,
                    "title": book_title
                })
        
        # 转换为列表,方便模板遍历
        authors_list = list(author_books.values())
    
    return render(request, "preview.html", {"authors": authors_list})

3. 模板渲染逻辑错误

确保模板中正确遍历所有作者及其书籍:

{% for author in authors %}
    <h3>{{ author.name }}</h3>
    <ul>
        {% for book in author.books %}
            <li>{{ book.title }}</li>
        {% empty %}
            <li>暂无著作</li>
        {% endfor %}
    </ul>
{% endfor %}

总结

你的核心问题是没有对Raw SQL返回的平级结果集做分组聚合,导致前面的作者数据被后面的覆盖。按照上面的步骤调整SQL语句和结果处理逻辑,就能展示所有作者的书籍数据了。

内容的提问来源于stack exchange,提问作者Herojos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:16:22