如何获取含关联Bookmark的BookmarkCategory数据并返回JSON
获取分类及关联书签的JSON数据
请求示例
GET -> localhost:8000/api/bookmarks
目标JSON格式(示例)
{ "python": { "title": "Python", "bookmarks": [ { "title": "Python Documentation", "url": "https://docs.python.org" } ] }, "javascript": { "title": "Javascript", "bookmarks": [ { "title": "JavaScript Documentation", "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript" } ] } }
模型定义
class BookmarkCategory(models.Model): title = models.CharField(max_length=255) class Bookmark(models.Model): title = models.CharField(max_length=255) url = models.CharField(max_length=255) category = models.ManyToManyField(BookmarkCategory)
当前查询方式
from .models import BookmarkCategory bookmarks = BookmarkCategory.objects.all()
实现方案
方法1:基于Django REST Framework实现
如果使用DRF,通过嵌套序列化器可以快速生成目标结构:
# serializers.py from rest_framework import serializers from .models import BookmarkCategory, Bookmark class BookmarkSerializer(serializers.ModelSerializer): class Meta: model = Bookmark fields = ['title', 'url'] class BookmarkCategorySerializer(serializers.ModelSerializer): bookmarks = BookmarkSerializer(many=True, source='bookmark_set') class Meta: model = BookmarkCategory fields = ['title', 'bookmarks'] # views.py from rest_framework.response import Response from rest_framework.decorators import api_view from .serializers import BookmarkCategorySerializer @api_view(['GET']) def bookmarks_list(request): # 使用prefetch_related避免N+1查询 categories = BookmarkCategory.objects.prefetch_related('bookmark_set').all() serializer = BookmarkCategorySerializer(categories, many=True) # 转换为以分类标题小写为键的字典结构 data = {item['title'].lower(): item for item in serializer.data} return Response(data)
方法2:手动构造数据(无DRF依赖)
如果不使用DRF,直接遍历模型实例构造数据:
# views.py from django.http import JsonResponse from .models import BookmarkCategory def bookmarks_list(request): categories = BookmarkCategory.objects.prefetch_related('bookmark_set').all() result = {} for category in categories: category_key = category.title.lower() bookmarks = [] for bookmark in category.bookmark_set.all(): bookmarks.append({ 'title': bookmark.title, 'url': bookmark.url }) result[category_key] = { 'title': category.title, 'bookmarks': bookmarks } return JsonResponse(result)
说明:
prefetch_related('bookmark_set')用于预加载关联的书签数据,避免多次查询数据库- 示例中将分类标题转为小写作为键,和目标格式匹配;若不需要可直接使用原标题作为键
内容的提问来源于stack exchange,提问作者nandesuka
相关产品推荐
相关产品推荐

