一、功能需求分析
1.功能
- 轮播图
- 推荐文章列表
- 文章标签导航
- 文章列表
- 分页
二、模型设计
根据功能分析,我们需要如下表
1.表和字段分析
- 文章分类表
- 文章表
- 文章评论表
- 推荐文章表
- 轮播图表
2.模型定义
定义一个基类模型,抽取公共字段
# 在utils目录下,创建一个models.py文件,在其中定义一个基类模型 from django.db import models class BaseModel(models.Model): """ 基类,公共字段 """ create_time = models.DateTimeField(‘创建时间‘, auto_now_add=True) update_time = models.DateTimeField(‘更新时间‘, auto_now=True) is_delete = models.BooleanField(‘逻辑删除‘, default=False) class Meta: # 抽象类,用于继承,迁移时不会创建 abstract = True
定义其他模型
# 在news目录下的models.py文件中定义如下数据模型 from django.db import models from utils.models import BaseModel class Tag(BaseModel): """ 文章分类标签模型 """ name = models.CharField(‘标签名‘, max_length=64, help_text=‘标签名‘) class Meta: ordering = [‘-update_time‘, ‘-id‘] # 排序 db_table = "tb_tag" # 指明数据库表名 verbose_name = "文章标签" # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): return self.name class News(BaseModel): """ 文章模型 """ title = models.CharField(‘标题‘, max_length=150, help_text=‘标题‘) digest = models.CharField(‘摘要‘, max_length=200, help_text=‘摘要‘) content = models.TextField(‘内容‘, help_text=‘内容‘) clicks = models.IntegerField(‘点击量‘, default=0, help_text=‘点击量‘) image_url = models.URLField(‘图片url‘, default=‘‘, help_text=‘图片url‘) tag = models.ForeignKey(‘Tag‘, on_delete=models.SET_NULL, null=True) author = models.ForeignKey(‘user.User‘, on_delete=models.SET_NULL, null=True) class Meta: ordering = [‘-update_time‘, ‘-id‘] # 排序 db_table = "tb_news" # 指明数据库表名 verbose_name = "新闻" # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): return self.title class Comments(BaseModel): """ 评论模型 """ content = models.TextField(‘内容‘, help_text=‘内容‘) author = models.ForeignKey(‘user.User‘, on_delete=models.SET_NULL, null=True) news = models.ForeignKey(‘News‘, on_delete=models.CASCADE) class Meta: ordering = [‘-update_time‘, ‘-id‘] # 排序 db_table = "tb_comments" # 指明数据库表名 verbose_name = "评论" # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): return ‘<评论{}>‘.format(self.id) class HotNews(BaseModel): """ 推荐文章表 """ news = models.OneToOneField(‘News‘, on_delete=models.CASCADE) priority = models.IntegerField(‘优先级‘, help_text=‘优先级‘) class Meta: ordering = [‘-update_time‘, ‘-id‘] # 排序 db_table = "tb_hotnews" # 指明数据库表名 verbose_name = "热门新闻" # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): return ‘<热门新闻{}>‘.format(self.id) class Banner(BaseModel): """ 轮播图 """ image_url = models.URLField(‘轮播图url‘, help_text=‘轮播图url‘) priority = models.IntegerField(‘优先级‘, help_text=‘优先级‘) news = models.OneToOneField(‘News‘, on_delete=models.CASCADE) class Meta: ordering = [‘priority‘, ‘-update_time‘, ‘-id‘] # 排序 db_table = "tb_banner" # 指明数据库表名 verbose_name = "轮播图" # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): return ‘<轮播图{}>‘.format(self.id)
三、文章标签导航功能
1.接口设计
- 接口说明:
类目 说明 请求方法 GET url定义 /
参数格式 无参数 - 返回结果
返回新闻页面,直接在模板渲染
2.后端代码
# 在news/views.py文件中定义如下视图 from django.shortcuts import render from .models import Tag def index(request): """ 新闻首页视图 :param request: :return: """ tags = Tag.objects.only(‘id‘, ‘name‘).filter(is_delete=False) return render(request, ‘news/index.html‘, context={ ‘tags‘: tags })
导入tag测试数据,或者直接用Navicat软件在tb_tag表中添加数据(数据见下方代码中引号里的内容,共6个),,,因为前段设置的原因,必须要跟我的内容一样,后面会用到
# insert news tag data INSERT INTO tb_tag(name, create_time, update_time, is_delete) values (‘Python基础‘, now(), now(), 0), (‘Python高级‘, now(), now(), 0), (‘Python函数‘, now(), now(), 0), (‘PythonGUI‘, now(), now(), 0), (‘Linux教程‘, now(), now(), 0), (‘Python框架‘, now(), now(), 0);
3.前端代码
# 修改templates/news/index.html中 news-nav部分代码如: <!-- news-nav start--> <nav class="news-nav"> <ul class="clearfix"> <li class="active"><a href="javascript:void(0)">最新资讯</a></li> {% for tag in tags %} <li><a href="javascript:void(0)" data-id="{{ tag.id }}">{{ tag.name }}</a> </li> {% endfor %} </ul> </nav> <!-- news-nav end -->
四、新闻列表功能
1.业务流程分析
- 判断前端传递标签分类id是否为空,是否为整数,是否超过范围
- 判断前端传递当前文章页数是否为空,是否为整数,是否超过范围
2.接口设计
接口说明:
类目 | 说明 |
---|---|
请求方法 | GET |
url定义 | /news/ |
参数格式 | 查询参数 |
参数说明:
参数名 | 类型 | 是否必须 | 描述 |
---|---|---|---|
tag | 整数 | 是 | 标签分类id |
page | 整数 | 是 | 当前文章页数 |
返回结果:
{ "errno": "0", "errmsg": "", "data": { "total_pages": 61, "news": [ { ‘id‘: ‘xxx‘, "digest": "在python用import或者from...import或者from...import...as...来导入相应的模块,作用和使用方法与C语言的include头文件类似。其实就是引入...", "title": "import方法引入模块详解", "author": "python", "image_url": "/media/jichujiaochen.jpeg", "tag_name": "Python基础", "update_time": "2018年12月17日 14:48" }, { ‘id‘: ‘xxx‘ "digest": "如果你原来是一个php程序员,你对于php函数非常了解(PS:站长原来就是一个php程序员),但是现在由于工作或者其他原因要学习python,但是p...", "title": "给曾经是phper的程序员推荐个学习网站", "author": "python", "image_url": "/media/jichujiaochen.jpeg", "tag_name": "Python基础", "update_time": "2018年12月17日 14:48" } ] } }
3.后端代码
在项目根目录下创建一个media文件夹,用于存放新闻图片以及用户上传文件。
# 在settings.py文件中添加 # 媒体文件配置 MEDIA_URL = ‘/media/‘ MEDIA_ROOT = os.path.join(BASE_DIR, ‘media‘)
django在调试模式下提供静态文件服务,为了能够返回media中的媒体文件还需在根urls.py中做如下配置
# 在根urls.py中加上static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) from django.urls import path, include from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path(‘‘, include(‘news.urls‘)), path(‘‘, include(‘verification.urls‘)), path(‘user/‘, include(‘user.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
原文地址:https://www.cnblogs.com/Tmclri/p/11545227.html
时间: 2024-10-08 23:05:23