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

如何获取含关联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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 23:06:21