113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
from django.core.paginator import Paginator
|
||
from django.http import JsonResponse
|
||
|
||
from django.core.exceptions import ValidationError
|
||
from django.utils.html import escape
|
||
from .models import Article
|
||
from django.shortcuts import get_object_or_404
|
||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||
|
||
# 文章列表页视图,带分页和请求频率限制
|
||
def article_list(request):
|
||
|
||
# 获取分页参数
|
||
page = request.GET.get('page', 1) # 当前页数,默认为第一页
|
||
limit = request.GET.get('limit', 10) # 每页文章数,默认为10
|
||
|
||
# 获取所有文章,并按发布时间倒序排序
|
||
articles = Article.objects.all().order_by('-published_at')
|
||
|
||
# 使用 Paginator 进行分页
|
||
paginator = Paginator(articles, limit)
|
||
|
||
try:
|
||
current_page = paginator.page(page) # 获取当前页的数据
|
||
except PageNotAnInteger:
|
||
current_page = paginator.page(1) # 如果请求的页数不存在,默认返回第一页
|
||
except EmptyPage:
|
||
# 如果页码超出范围,返回空列表
|
||
return JsonResponse({'code': 200, 'message': '没有更多数据', 'data': {}})
|
||
|
||
# 将文章列表转换为字典列表
|
||
articles_list = list(current_page.object_list.values('id', 'chinese_title', 'english_title', 'published_at', 'status'))
|
||
|
||
# 格式化文章的发布时间
|
||
for article in articles_list:
|
||
article['published_at'] = article['published_at'].strftime('%Y-%m-%d %H:%M:%S') if article['published_at'] else '未发布'
|
||
|
||
# 返回 JSON 数据,适配前端使用
|
||
data = {
|
||
"code": 200,
|
||
"msg": "成功",
|
||
"count": paginator.count, # 文章总数
|
||
"data": articles_list
|
||
}
|
||
|
||
return JsonResponse(data)
|
||
|
||
def article_detail(request, pk, lang):
|
||
try:
|
||
# 检查是否传入了危险参数 (如防止SQL注入等)
|
||
pk = escape(pk) # 对传入的主键进行转义,避免潜在的注入风险
|
||
lang = escape(lang) # 对语言参数进行转义
|
||
|
||
# 检查参数是否有效
|
||
if not pk or not lang:
|
||
raise ValidationError('参数不能为空')
|
||
|
||
# 检查语言是否有效
|
||
if lang not in ['zh', 'en']:
|
||
return JsonResponse({
|
||
"code": 400,
|
||
"msg": "无效的语言参数",
|
||
"data": {}
|
||
})
|
||
|
||
# 获取指定的文章
|
||
article = get_object_or_404(Article, pk=pk)
|
||
|
||
# 根据语言参数返回不同语言的文章内容
|
||
if lang == 'en':
|
||
title = article.english_title
|
||
keywords = article.english_keywords
|
||
content = article.english_content
|
||
else:
|
||
title = article.chinese_title
|
||
keywords = article.chinese_keywords
|
||
content = article.chinese_content
|
||
|
||
# 构造响应数据
|
||
data = {
|
||
"code": 200,
|
||
"msg": "成功",
|
||
"data": {
|
||
'id': article.id,
|
||
'title': title,
|
||
'keywords': keywords,
|
||
'content': content,
|
||
'published_at': article.published_at.strftime('%Y-%m-%d %H:%M:%S') if article.published_at else '未发布',
|
||
'status': article.status
|
||
}
|
||
}
|
||
return JsonResponse(data)
|
||
|
||
except ValidationError as ve:
|
||
return JsonResponse({
|
||
"code": 400,
|
||
"msg": str(ve),
|
||
"data": {}
|
||
})
|
||
|
||
except Article.DoesNotExist:
|
||
return JsonResponse({
|
||
"code": 404,
|
||
"msg": "未找到对应的文章",
|
||
"data": {}
|
||
})
|
||
|
||
except Exception as e:
|
||
return JsonResponse({
|
||
"code": 500,
|
||
"msg": "服务器内部错误",
|
||
"data": {"error": str(e)}
|
||
}) |