新闻列表功能
1.业务流程分析
- 判断前端传递标签分类id是否为空,是否为整数,是否超过范围
- 判断前端传递当前文章页数是否为空,是否为整数,是否超过范围
2.接口设计
接口说明:
类目 说明
请求方法 GET
url定义 /news/
参数格式 查询参数
参数说明:
参数名 类型 是否必须 描述
tag 整数 是 标签分类id
page 整数 是 当前文章页数
返回结果:
{
"errno": "0",
"errmsg": "",
"data": {
"total_pages": 61,
"news": [
{
"digest": "在python用import或者from...import或者from...import...as...来导入相应的模块,作用和使用方法与C语言的include头文件类似。其实就是引入...",
"title": "import方法引入模块详解",
"image_url": "/media/jichujiaochen.jpeg",
"tag_name": "Python基础",
"update_time": "2018年12月17日 14:48"
},
{
"digest": "如果你原来是一个php程序员,你对于php函数非常了解(PS:站长原来就是一个php程序员),但是现在由于工作或者其他原因要学习python,但是p...",
"title": "给曾经是phper的程序员推荐个学习网站",
"image_url": "/media/jichujiaochen.jpeg",
"tag_name": "Python基础",
"update_time": "2018年12月17日 14:48"
}
]
}
}
在项目根目录下创建一个media文件夹,用于存放新闻图片
图片文件在网盘中可以找到,knight已经为各位打包好。
链接:https://pan.baidu.com/s/1Hfci7xNBe7FC0LdNGFzR0Q
提取码:18n6
# 在settings.py文件中添加
# 媒体文件配置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
django在调试模式下提供静态文件服务,为了能够返回media中的媒体文件还需在根urls.py中做如下配置
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', include('news.urls')),
path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
导入测试数据,为了测试数据的导入,请确保表名一致
# 在xshell中导入测试数据,在xshell中通过rz命令,将tb_news_20181217.sql文件上传到虚拟机
mysql -u 用户名 -p -D 数据库名 < tb_news_20181217.sql
sql文件在网盘中可以找到的
链接:https://pan.baidu.com/s/1Hfci7xNBe7FC0LdNGFzR0Q
提取码:18n6
切记一定要先导入类别再导入新闻
导入之后,视图代码如下
from django.shortcuts import render
from django.views import View
from django.core.paginator import Paginator
from django.db.models import F
from .models import Tag, News
from utils.res_code import json_response
def news(request):
"""
新闻首页视图
:param request:
:return:
"""
tags = Tag.objects.only('id', 'name').filter(is_delete=False)
return render(request, 'news/index.html',context={'tags': tags})
class NewsListView(View):
"""
新闻列表视图
url: /news/
args: tag, page
"""
def get(self, request):
try:
tag_id = int(request.GET.get('tag', 0))
except Exception as e:
tag_id = 0
try:
page = int(request.GET.get('page', 0))
except Exception as e:
page = 1
# 使用only返回的是对象,所以传递到前端时需要迭代处理
# news_queryset = News.objects.select_related('tag', 'author').only(
# 'title', 'digest', 'image_url', 'update_time', 'tag__name', 'author__username')
# values 返回字典
news_queryset = News.objects.values('id', 'title', 'digest', 'image_url', 'update_time').annotate(
tag_name=F('tag__name'))
news = news_queryset.filter(is_delete=False, tag_id=tag_id) or news_queryset.filter(is_delete=False)
paginator = Paginator(news, 5)
# 获取页面数据 get_page可以容错
news_info = paginator.get_page(page)
data = {
'total_pages': paginator.num_pages,
'news': list(news_info)
}
return json_response(data=data)
接下来的url是为了ajax请求能够拿到我们文章的数据
from django.urls import path
from . import views
app_name = "news"
urlpatterns = [
path("",views.news),
path('news/', views.NewsListView.as_view(), name='news_list')
]
之后我们再去刷新页面,就可以看到