如何将Python列表变量中的数据加载到Django Paginator?
嘿,我来帮你搞定这个Django分页的问题~你有两个选择:要么直接用你现在拿到的row结果集做分页,要么改用Django ORM来处理(更推荐后者),下面分别给你讲清楚:
方案1:直接用现有结果集实现分页
Django的Paginator其实可以接受任何可迭代对象(包括列表、元组这类集合),所以你可以直接把row传给它。不过要注意,fetchall()会把所有查询结果一次性加载到内存里,如果你的表数据量很大,这种方式会拖慢性能,小数据量的话没问题。
修改你的test视图代码如下:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.shortcuts import render import MySQLdb def test(request): db = MySQLdb.connect(host="localhost", user="pc", passwd="3346378", db="mc") cur = db.cursor() cur.execute('''SELECT * FROM hello left join hell on hello.Id=hell.Id ''') row = cur.fetchall() db.close() # 别忘了关闭数据库连接! # 分页逻辑 paginator = Paginator(row, 10) # 每页显示10条数据,可根据需求调整 page = request.GET.get('page') # 从URL获取页码参数,比如?page=2 try: page_obj = paginator.page(page) except PageNotAnInteger: # 如果页码不是整数,默认显示第一页 page_obj = paginator.page(1) except EmptyPage: # 如果页码超出范围,显示最后一页 page_obj = paginator.page(paginator.num_pages) # 把分页对象传给模板 return render(request, 'your_template.html', {'page_obj': page_obj})
之后在模板里,你就可以像普通Django分页那样遍历page_obj,还能添加分页导航(比如上一页、下一页、页码按钮)。
方案2:推荐使用Django ORM(更优方案)
虽然直接用原生SQL能实现,但Django ORM更安全(自动防SQL注入)、更易维护,而且会自动生成分页查询的SQL(只查询当前页需要的数据,不会把所有数据加载到内存),性能更好。步骤如下:
第一步:定义模型
先在你的app的models.py里定义对应hello和hell表的模型(要和数据库实际表结构对应):
from django.db import models class Hello(models.Model): # 按你的实际表字段调整,这里只是示例 Id = models.IntegerField(primary_key=True) name = models.CharField(max_length=100) # 其他字段... class Meta: db_table = 'hello' # 指定数据库中已存在的表名 class Hell(models.Model): Id = models.IntegerField(primary_key=True) # 关联Hello表,对应你SQL里的left join逻辑 hello = models.OneToOneField(Hello, on_delete=models.CASCADE, db_column='Id') # 其他字段... class Meta: db_table = 'hell' # 指定数据库中已存在的表名
第二步:用ORM实现联表查询和分页
修改views.py,去掉原生SQL,改用ORM:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.shortcuts import render from .models import Hello def test(request): # ORM实现left join查询,和你原生SQL的逻辑一致 queryset = Hello.objects.all().select_related('hell') # select_related优化联表查询性能 # 分页逻辑 paginator = Paginator(queryset, 10) page = request.GET.get('page') try: page_obj = paginator.page(page) except PageNotAnInteger: page_obj = paginator.page(1) except EmptyPage: page_obj = paginator.page(paginator.num_pages) return render(request, 'your_template.html', {'page_obj': page_obj})
这样不仅代码更简洁,而且当数据量大的时候,ORM只会查询当前页的10条数据,内存占用小很多,还能享受Django的其他特性(比如admin管理、表单验证等)。
内容的提问来源于stack exchange,提问作者Jane
相关产品推荐
相关产品推荐

