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

如何使用Django ORM实现表关联并生成DataTable兼容JSON响应

Django ORM关联查询+DataTable兼容JSON响应实现方案

问题背景

需要通过Django ORM实现Product与ProductCategory两张表的关联查询,返回兼容DataTable的JSON响应,要求包含产品详情及分类名称(categoryname)而非仅分类ID,现有模型、视图及Serializer代码已提供,但对Serializer的用法不熟悉。

解决方案

1. 修改ProductSerializer,添加分类名称字段

Serializer的核心作用是将Django模型对象转换为可直接序列化的Python字典,同时支持灵活扩展字段。我们需要在Serializer中新增自定义字段来获取关联分类的名称:

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    # 自定义字段,从关联的category对象中提取categoryname
    categoryname = serializers.CharField(source='category.categoryname')

    class Meta:
        model = Product
        # 明确列出需要返回的所有字段,包含原产品字段及新增的categoryname
        fields = [
            'productid', 'sku', 'shortcode', 'category', 
            'categoryname', 'productname', 'description', 
            'barcode', 'treshhold', 'isactive'
        ]
  • source='category.categoryname':指定该字段的值来自Product实例关联的category(ProductCategory对象)的categoryname属性,序列化时会自动填充该值。

2. 调整视图代码,用Serializer替代model_to_dict

原代码中model_to_dict仅能提取模型自身字段,无法处理关联对象的自定义字段,改用Serializer完成序列化:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.http import JsonResponse
from .models import Product
from .serializers import ProductSerializer

def get_product(request):
    # 从请求参数中取值,添加默认值避免KeyError
    draw = int(request.GET.get('draw', 1))
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 10))
    sku_filter = request.GET.get('sku', '')

    # 使用select_related预加载关联的category,*避免N+1查询*,提升性能
    products = Product.objects.filter(sku__icontains=sku_filter).select_related('category')
    
    recordsTotal = products.count()
    recordsFiltered = recordsTotal

    # 计算页码,使用整数除法避免浮点数问题
    page = (start // length) + 1

    paginator = Paginator(products, length)

    try:
        object_list = paginator.page(page)
    except PageNotAnInteger:
        object_list = paginator.page(1)
    except EmptyPage:
        object_list = paginator.page(paginator.num_pages)

    # 序列化分页后的产品列表,many=True表示处理多个对象
    serializer = ProductSerializer(object_list, many=True)
    # serializer.data即为包含categoryname的目标字典列表
    data = serializer.data

    json_res = {
        "draw": draw,
        "recordsTotal": recordsTotal,
        "recordsFiltered": recordsFiltered,
        'data': data,
    }

    return JsonResponse(json_res)
  • request.GET.get():替代直接索引参数,避免前端未传参数时抛出KeyError
  • select_related('category'):预加载关联的分类数据,避免循环查询每个产品的分类(N+1问题)
  • ProductSerializer(object_list, many=True):将分页后的产品列表批量序列化,自动处理每个产品的关联分类名称

3. Serializer核心工作原理

Serializer主要承担两种转换工作:

  • 序列化:将Django模型实例转换为可直接生成JSON的Python字典,支持自定义字段、关联对象字段提取、数据格式化
  • 反序列化:将前端传来的JSON数据转换为模型实例,同时完成数据验证
  • 本次场景仅用到序列化功能,通过source参数轻松关联获取关联表字段值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 23:47:29