下面详细解释一下如何在Django中进行分页查询并返回JSON格式的数据,并解决中文乱码问题。
1. 安装相关依赖库
首先需要安装以下两个库:
- django-pure-pagination (https://pypi.org/project/django-pure-pagination/)
- django-core-extensions (https://pypi.org/project/django-core-extensions/)
可以使用pip进行安装:
pip install django-pure-pagination django-core-extensions
2. 修改settings配置
在settings.py中添加以下配置:
INSTALLED_APPS = [
# ...
'pure_pagination',
'core_extensions',
]
# Pagination settings
PAGINATION_SETTINGS = {
'PAGE_RANGE_DISPLAYED': 5,
'MARGIN_PAGES_DISPLAYED': 2,
'SHOW_FIRST_PAGE_WHEN_INVALID': True,
}
3. 创建分页处理类
在app目录下创建一个pagination.py文件,添加以下代码:
from pure_pagination import Paginator, PageNotAnInteger
class PaginationHandler():
def __init__(self, request, queryset, page_size=10, prefetch_related=None, select_related=None):
self.request = request
self.queryset = queryset
self.page_size = page_size
self.prefetch_related = prefetch_related
self.select_related = select_related
def get_paginated_data(self):
page = self.request.GET.get('page', 1)
# 如果传进来的数据中有额外的关联表,使用select_related和prefetch_related优化查询速度
queryset = self.queryset
if self.prefetch_related:
queryset = queryset.prefetch_related(*self.prefetch_related)
if self.select_related:
queryset = queryset.select_related(*self.select_related)
paginator = Paginator(queryset, self.page_size, request=self.request)
try:
data = paginator.page(page)
except PageNotAnInteger:
data = paginator.page(1)
except Exception:
data = []
return {
'current_page': data.number,
'total_pages': paginator.num_pages,
'has_previous': data.has_previous(),
'has_next': data.has_next(),
'previous_page_number': data.previous_page_number(),
'next_page_number': data.next_page_number(),
'object_list': list(data),
}
4. 编写视图函数
在views.py中定义视图函数,处理分页和JSON数据返回,例如:
from django.http import JsonResponse
from .models import Post
from .pagination import PaginationHandler
def post_list(request):
data = Post.objects.all()
# 获取分页处理类
paginator = PaginationHandler(request, data)
# 获取分页数据
paginated_data = paginator.get_paginated_data()
# 返回JSON格式数据
return JsonResponse(paginated_data, safe=False)
5. 解决返回JSON数据中文乱码问题
在JSONResponse时需要加入参数json_dumps_params={'ensure_ascii':False}
,将ensure_ascii设置为False,以解决中文乱码问题,例如:
return JsonResponse(paginated_data, json_dumps_params={'ensure_ascii':False}, safe=False)
至此,我们就完成了Django分页查询并返回JSON数据并解决中文乱码问题的完整攻略。
以下是示例代码:
分页处理类示例
from django.http import request
from django.test import TestCase
from .pagination import PaginationHandler
from .models import Post
class PaginationTestCase(TestCase):
def setUp(self):
for i in range(1, 16):
Post.objects.create(title=f"Post {i}", body="body content...")
self.request = request.HttpRequest()
self.request.GET['page'] = 1
self.handler = PaginationHandler(self.request, Post.objects.all())
def test_paginator(self):
paginated_data = self.handler.get_paginated_data()
self.assertEqual(paginated_data['current_page'], 1)
self.assertEqual(paginated_data['total_pages'], 2)
self.assertEqual(paginated_data['has_previous'], False)
self.assertEqual(paginated_data['has_next'], True)
self.assertEqual(paginated_data['previous_page_number'], None)
self.assertEqual(paginated_data['next_page_number'], 2)
self.assertEqual(len(paginated_data['object_list']), 10)
self.assertEqual(paginated_data['object_list'][0].title, 'Post 1')
def test_select_related(self):
paginated_data = PaginationHandler(self.request, Post.objects.all(), select_related=['user']).get_paginated_data()
self.assertEqual(len(paginated_data['object_list']), 10)
self.assertEqual(paginated_data['object_list'][0].user.username, 'admin')
def test_prefetch_related(self):
paginated_data = PaginationHandler(self.request, Post.objects.all(), prefetch_related=['comments']).get_paginated_data()
self.assertEqual(len(paginated_data['object_list']), 10)
self.assertEqual(len(paginated_data['object_list'][0].comments.all()), 2)
视图函数示例
from django.http import JsonResponse
from .models import Post
from .pagination import PaginationHandler
def post_list(request):
data = Post.objects.all()
# 获取分页处理类
paginator = PaginationHandler(request, data)
# 获取分页数据
paginated_data = paginator.get_paginated_data()
# 返回JSON格式数据
return JsonResponse(paginated_data, json_dumps_params={'ensure_ascii':False}, safe=False)
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django分页查询并返回jsons数据(中文乱码解决方法) - Python技术站