如何合并Django ORM查询结果,返回含作者名与书籍名的JSON对象?
解决Django中合并作者与书籍查询结果返回JSON的问题
首先咱们来分析下你当前代码的问题:你用Authors.objects.filter(aid = l).values('aname')得到的s是一个QuerySet对象(本质是类似列表的集合),而不是单个字符串,直接把它作为JSON字典的键肯定会报错——因为字典的键必须是字符串、数字这类不可变类型,QuerySet显然不符合要求。
接下来给你两种可行的修改方案,你可以根据需求选择:
方案一:使用get()获取单个作者对象(推荐)
这种方式更直接,因为aid是作者表的主键,唯一对应一个作者,用get()可以直接拿到作者实例,然后提取名字,同时增加异常处理让接口更健壮:
from django.http import JsonResponse def authbook(request): aid = request.GET.get('bks', '') try: # 通过主键获取单个作者实例 author = Authors.objects.get(aid=aid) # 获取该作者关联的所有书籍名称 books_list = Books.objects.filter(bookauth__aid=aid).values('bname') # 构造符合要求的JSON结构 response_data = { "author_name": author.aname, "books": list(books_list) } return JsonResponse(response_data) except Authors.DoesNotExist: # 处理作者不存在的情况,返回错误提示和404状态码 return JsonResponse({"error": "指定的作者不存在"}, status=404)
方案说明:
- 用
get()替代filter():因为主键是唯一的,get()会直接返回单个作者对象,而不是QuerySet,能直接提取aname属性。 - 明确的JSON键名:用
"author_name"和"books"作为键,结构清晰,前端更容易解析。 - 异常处理:当传入的
aid不存在时,返回友好的错误提示,符合RESTful接口的规范。
方案二:从QuerySet中提取作者名
如果你坚持要用filter(),可以通过first()取出QuerySet中的第一个元素(因为aid唯一,只会有一个结果),再提取作者名:
def authbook(request): aid = request.GET.get('bks', '') # 获取作者名的QuerySet,取出第一个元素 author_query = Authors.objects.filter(aid=aid).values('aname').first() if not author_query: return JsonResponse({"error": "指定的作者不存在"}, status=404) author_name = author_query['aname'] # 获取书籍列表 books_list = Books.objects.filter(bookauth__aid=aid).values('bname') # 构造JSON返回 return JsonResponse({ "author_name": author_name, "books": list(books_list) })
方案说明:
values('aname').first()会返回一个字典(比如{'aname': '张三'}),或者None(当作者不存在时)。- 先判断作者是否存在,再提取名字,避免后续报错。
两种方案最终返回的JSON格式类似这样:
{ "author_name": "J.K.罗琳", "books": [ {"bname": "哈利波特与魔法石"}, {"bname": "哈利波特与密室"} ] }
内容的提问来源于stack exchange,提问作者Django_noob
相关产品推荐
相关产品推荐

