在 Django 中,将查询结果转换为 JSON 响应有几种常用方法。以下是三种推荐的方式:

方法 1:使用 values() + JsonResponse(推荐)

from django.http import JsonResponse

def poetry_list(request):
    # 获取数据并转换为字典列表
    queryset = Poetrylist.objects.order_by("-onclick")[:10].values(
        'id', 'title', 'author', 'content'  # 明确指定需要返回的字段
    )
    data = list(queryset)  # 将 QuerySet 转换为列表
    return JsonResponse(data, safe=False)  # safe=False 允许非字典数据

方法 2:手动构建字典列表

from django.http import JsonResponse

def poetry_list(request):
    poems = Poetrylist.objects.order_by("-onclick")[:10]
    data = []
    for poem in poems:
        data.append({
            'id': poem.id,
            'title': poem.title,
            'author': poem.author,
            'content': poem.content,
            'onclick': poem.onclick,
            # 添加其他需要的字段
        })
    return JsonResponse(data, safe=False)

方法 3:使用 Django 的序列化模块(含元数据)

from django.http import HttpResponse
from django.core import serializers

def poetry_list(request):
    poems = Poetrylist.objects.order_by("-onclick")[:10]
    # 直接序列化为 JSON 字符串
    data = serializers.serialize('json', poems)
    return HttpResponse(data, content_type='application/json')

说明:

  1. 字段选择

    • 使用 .values() 或手动循环时,明确指定需要返回的字段,避免暴露敏感数据

    • 排除不需要的字段(如密码、内部状态等)

  2. 日期/复杂字段处理

# 在手动序列化中处理日期
data.append({
    'publish_date': poem.publish_date.isoformat()  # 转换为 ISO 格式字符串
})

     安全增强

return JsonResponse(
    {'status': 'success', 'data': data},  # 封装为标准结构
    status=200,
    json_dumps_params={'ensure_ascii': False}  # 支持中文
)

完整示例(推荐结构)

from django.views.decorators.http import require_GET

@require_GET
def top_poems(request):
    try:
        poems = Poetrylist.objects.order_by("-onclick")[:10].values(
            'id', 'title', 'author', 'onclick'
        )
        return JsonResponse({
            'code': 200,
            'message': 'OK',
            'data': list(poems)
        }, json_dumps_params={'ensure_ascii': False})
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': str(e)
        }, status=500)