1. 引言
ag-grid-django 是一个将 AG Grid 数据表格组件与 Django 后端深度集成的 Python 包。它允许开发者在 Django 模板中快速渲染功能强大的交互式表格,同时通过服务端分页、排序和过滤来应对大数据量场景。本文将从功能特性、安装配置、核心语法与参数、9 个实际应用案例以及常见错误与注意事项五个方面,系统介绍 ag-grid-django 的使用方法。
2. 功能概述
ag-grid-django 的核心价值在于把 AG Grid 的前端交互能力与 Django 的模型查询能力无缝衔接。它主要提供以下能力:
- 服务端分页:大数据量下只加载当前页数据,避免一次性渲染全部记录。
- 服务端排序:点击列头即可按字段排序,排序逻辑在数据库层完成。
- 服务端过滤:支持文本、数字、日期、下拉选择等多种过滤器,过滤条件由后端解析执行。
- 列配置灵活:支持自定义列宽、对齐、格式化、单元格渲染器、行样式等。
- 与 Django ORM 集成:直接基于模型或查询集生成表格数据,无需手写 JSON 接口。
- CSRF 与权限兼容:天然适配 Django 的 CSRF 防护和登录权限体系。
3. 安装与配置
3.1 安装包
使用 pip 安装 ag-grid-django:
pip install ag-grid-django
同时需要在前端引入 AG Grid 的静态资源。推荐使用官方 CDN,在模板的 head 区域加入:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/styles/ag-grid.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/styles/ag-theme-alpine.css">
<script src="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js"></script>
3.2 注册应用
在 settings.py 的 INSTALLED_APPS 中加入 ag_grid:
INSTALLED_APPS = [
# … 其他应用
'ag_grid',
]
3.3 配置 URL
在项目的 urls.py 中引入 ag-grid-django 提供的视图路由:
from django.urls import path, include
urlpatterns = [
# … 其他路由
path('ag-grid/', include('ag_grid.urls')),
]
4. 核心语法与参数
4.1 视图函数
在 Django 视图中,通过 render 函数把表格配置和数据源传给模板。核心参数包括:
- grid_data:AG Grid 的列定义与行数据配置字典。
- column_defs:列定义列表,包含字段名、标题、宽度、排序、过滤等配置。
- row_data:行数据列表,通常由模型查询集序列化而来。
- pagination:是否启用分页,默认 True。
- pagination_page_size:每页行数,默认 10。
- server_side:是否启用服务端模式,默认 True。
一个最简视图示例如下:
from django.shortcuts import render
from .models import Product
def product_list(request):
products = Product.objects.all().values('id', 'name', 'price', 'stock')
column_defs = [
{'headerName': 'ID', 'field': 'id', 'width': 80},
{'headerName': '名称', 'field': 'name', 'width': 200},
{'headerName': '价格', 'field': 'price', 'width': 120},
{'headerName': '库存', 'field': 'stock', 'width': 120},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(products),
'pagination': True,
'pagination_page_size': 10,
}
return render(request, 'product_list.html', {'grid_data': grid_data})
4.2 模板渲染
在模板中,使用 ag-grid-django 提供的模板标签渲染表格:
{% load ag_grid_tags %}
<!DOCTYPE html>
<html>
<head>
<title>商品列表</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/styles/ag-grid.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/styles/ag-theme-alpine.css">
<script src="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js"></script>
</head>
<body>
<div class="ag-theme-alpine" style="height: 500px; width: 100%;">
{% render_ag_grid grid_data %}
</div>
</body>
</html>
4.3 列定义常用参数
列定义支持 AG Grid 的绝大多数原生参数,常用如下:
- headerName:列头显示名称。
- field:对应数据字段名。
- width / minWidth / maxWidth:列宽控制。
- sortable:是否可排序,默认 True。
- filter:过滤器类型,如 'agTextColumnFilter'、'agNumberColumnFilter'、'agDateColumnFilter'。
- editable:是否可编辑。
- cellRenderer:自定义单元格渲染函数名。
- valueFormatter:值格式化函数,用于日期、货币等显示。
5. 9 个实际应用案例
5.1 案例一:基础数据列表
展示一个简单的用户列表,包含分页和排序功能:
from django.shortcuts import render
from django.contrib.auth.models import User
def user_list(request):
users = User.objects.all().values('id', 'username', 'email', 'date_joined')
column_defs = [
{'headerName': 'ID', 'field': 'id', 'width': 80},
{'headerName': '用户名', 'field': 'username', 'width': 150},
{'headerName': '邮箱', 'field': 'email', 'width': 220},
{'headerName': '注册时间', 'field': 'date_joined', 'width': 180},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(users),
'pagination': True,
'pagination_page_size': 20,
}
return render(request, 'user_list.html', {'grid_data': grid_data})
5.2 案例二:带过滤器的商品表格
为商品表格添加文本和数字过滤器:
def product_filter_list(request):
products = Product.objects.all().values('id', 'name', 'price', 'stock')
column_defs = [
{'headerName': 'ID', 'field': 'id', 'width': 80, 'filter': 'agNumberColumnFilter'},
{'headerName': '名称', 'field': 'name', 'width': 200, 'filter': 'agTextColumnFilter'},
{'headerName': '价格', 'field': 'price', 'width': 120, 'filter': 'agNumberColumnFilter'},
{'headerName': '库存', 'field': 'stock', 'width': 120, 'filter': 'agNumberColumnFilter'},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(products),
'pagination': True,
'pagination_page_size': 15,
}
return render(request, 'product_list.html', {'grid_data': grid_data})
5.3 案例三:日期格式化显示
使用 valueFormatter 对日期字段进行格式化:
def order_list(request):
orders = Order.objects.all().values('id', 'order_no', 'created_at', 'total_amount')
column_defs = [
{'headerName': '订单号', 'field': 'order_no', 'width': 180},
{
'headerName': '创建时间',
'field': 'created_at',
'width': 180,
'valueFormatter': "new Date(value).toLocaleString('zh-CN')",
},
{'headerName': '金额', 'field': 'total_amount', 'width': 120},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(orders),
'pagination': True,
'pagination_page_size': 10,
}
return render(request, 'order_list.html', {'grid_data': grid_data})
5.4 案例四:自定义单元格渲染
通过 cellRenderer 在单元格中显示状态标签:
def task_list(request):
tasks = Task.objects.all().values('id', 'title', 'status', 'assignee')
column_defs = [
{'headerName': '任务', 'field': 'title', 'width': 250},
{
'headerName': '状态',
'field': 'status',
'width': 120,
'cellRenderer': "function(params) { return '<span style=\\"color: \\" + (params.value === 'done' ? 'green' : 'orange') + '\\">' + params.value + '</span>'; }",
},
{'headerName': '负责人', 'field': 'assignee', 'width': 120},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(tasks),
'pagination': True,
'pagination_page_size': 10,
}
return render(request, 'task_list.html', {'grid_data': grid_data})
5.5 案例五:多表关联数据展示
展示关联外键字段的数据:
def employee_list(request):
employees = Employee.objects.select_related('department').values(
'id', 'name', 'department__name', 'salary', 'hire_date'
)
column_defs = [
{'headerName': '姓名', 'field': 'name', 'width': 120},
{'headerName': '部门', 'field': 'department__name', 'width': 150},
{'headerName': '薪资', 'field': 'salary', 'width': 120},
{'headerName': '入职日期', 'field': 'hire_date', 'width': 140},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(employees),
'pagination': True,
'pagination_page_size': 10,
}
return render(request, 'employee_list.html', {'grid_data': grid_data})
5.6 案例六:行点击事件处理
通过 onRowClicked 配置实现行点击跳转:
def article_list(request):
articles = Article.objects.all().values('id', 'title', 'author', 'created_at')
column_defs = [
{'headerName': '标题', 'field': 'title', 'width': 300},
{'headerName': '作者', 'field': 'author', 'width': 120},
{'headerName': '发布时间', 'field': 'created_at', 'width': 160},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(articles),
'pagination': True,
'pagination_page_size': 10,
'on_row_clicked': "function(event) { window.location.href = '/article/' + event.data.id + '/'; }",
}
return render(request, 'article_list.html', {'grid_data': grid_data})
5.7 案例七:可编辑单元格与批量保存
启用单元格编辑,并通过前端收集修改后的数据:
def inventory_list(request):
items = Inventory.objects.all().values('id', 'sku', 'quantity', 'location')
column_defs = [
{'headerName': 'SKU', 'field': 'sku', 'width': 150, 'editable': False},
{'headerName': '数量', 'field': 'quantity', 'width': 120, 'editable': True},
{'headerName': '库位', 'field': 'location', 'width': 150, 'editable': True},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(items),
'pagination': True,
'pagination_page_size': 10,
'editable': True,
}
return render(request, 'inventory_list.html', {'grid_data': grid_data})
5.8 案例八:服务端搜索与过滤
结合 Django 查询参数实现服务端过滤:
def searchable_product_list(request):
keyword = request.GET.get('q', '')
products = Product.objects.all()
if keyword:
products = products.filter(name__icontains=keyword)
products = products.values('id', 'name', 'price', 'stock')
column_defs = [
{'headerName': 'ID', 'field': 'id', 'width': 80},
{'headerName': '名称', 'field': 'name', 'width': 200},
{'headerName': '价格', 'field': 'price', 'width': 120},
{'headerName': '库存', 'field': 'stock', 'width': 120},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(products),
'pagination': True,
'pagination_page_size': 10,
}
return render(request, 'product_list.html', {'grid_data': grid_data, 'keyword': keyword})
5.9 案例九:多选行与批量操作
启用行多选,配合按钮实现批量操作:
def batch_user_list(request):
users = User.objects.all().values('id', 'username', 'email', 'is_active')
column_defs = [
{'headerName': '选择', 'field': 'id', 'checkboxSelection': True, 'width': 80},
{'headerName': '用户名', 'field': 'username', 'width': 150},
{'headerName': '邮箱', 'field': 'email', 'width': 220},
{'headerName': '状态', 'field': 'is_active', 'width': 100},
]
grid_data = {
'column_defs': column_defs,
'row_data': list(users),
'pagination': True,
'pagination_page_size': 10,
'row_selection': 'multiple',
}
return render(request, 'batch_user_list.html', {'grid_data': grid_data})
6. 常见错误与使用注意事项
6.1 常见错误
- 静态资源未加载:忘记引入 AG Grid 的 CSS 和 JS 文件,导致表格空白或报错。务必在模板中正确引入 CDN 资源。
- 字段名不匹配:column_defs 中的 field 与 row_data 中的键不一致,导致列显示为空。使用 values() 时注意字段名与列定义保持一致。
- 关联字段查询错误:使用外键关联字段如 department__name 时,必须先在查询集中使用 select_related 或 values 明确指定,否则会触发额外查询或报错。
- CSRF 校验失败:在启用服务端交互时,如果自定义了 POST 请求,需要确保模板中包含 CSRF token。
《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。全书共11章,前6章涵盖深度学习基础,包括张量运算、神经网络原理、数据预处理及卷积神经网络等;后5章进阶探讨图像、文本、音频建模技术,并结合Transformer架构解析大语言模型的开发实践。书中通过房价预测、图像分类等案例讲解模型构建方法,每章附有动手练习题,帮助读者巩固实战能力。内容兼顾数学原理与工程实现,适配PyTorch框架最新技术发展趋势。

网硕互联帮助中心



评论前必须登录!
注册