文章目录
数据库模型设计
分析
- 轮播图 字段:prionrity,image_url,news(关联文章,一对一),create_time,update_time,is_delete
- 热门新闻 字段:news(一对一,关联文章表),prionrity(优先级),create_time,update_time,is_delete
- 标签 字段:name,create_time,update_time(更新时间),is_delete(逻辑删除)
- 各类型的具体文章 字段:title,digest(摘要),content(内容),clicks(点击量),image_url,auther(外键关联用户表,一对多),tag(一对多),create_time,update_time,is_delete
- 文章的评论 字段:author(评论人,关联用户表一对多),content,news(外键关联,对那个文章评论,关联文章表,一对多),create_time,update_time,is_delete,
- 一共5张表
- 每张表都有create_time,updata_time,is_delete这三个字段,用继承模型类的方法继承这三个字段
表名 | 公共的字段 | 自己的字段 | 外键关联的字段 |
---|---|---|---|
文章分类表Tag | create_time,update_time,is_delete | name | 内容 |
文章表News | title,digestcontent,clicks,image_url | tag(多对一Tag),author(多对一users.Users) | |
评论表Comments | content | author(多对一users.Users),news(多对一News) | |
热门文章表HotNews | priority | news(一对一News) | |
轮播图表Banner | priority,image_url | news(一对一News) |
前端代码
templates/news/index.html
{% extends 'base/base.html' %}
{% load static %}
{% block title %}<title>IndexPage</title>{% endblock %}
{% block link %}
<link rel="stylesheet" href="{% static 'css/news/index.css' %}">
{% endblock %}
<!-- main-contain start -->
{% block contain %}
<div class="main-contain">
<!-- banner start -->
<div class="banner">
<ul class="pic">
<!--淡入淡出banner-->
<li><a href="javascript:void(0);"><img src="{% static 'img/ui.png' %}" alt="test"></a></li>
<li><a href="javascript:void(0);"><img src="{% static 'img/youxi.png' %}" alt="test"></a></li>
<li><a href="javascript:void(0);"><img src="{% static 'img/dianshang.png' %}" alt="test"></a></li>
<li><a href="javascript:void(0);"><img src="{% static 'img/zimeiti.png' %}" alt="test"></a></li>
<li><a href="javascript:void(0);"><img src="{% static 'img/python_gui.jpg' %}" alt="test"></a></li>
<li><a href="javascript:void(0);"><img src="{% static 'img/linux.jpg' %}" alt="test"></a></li>
</ul>
<a href="javascript:void(0);" class="btn prev">
<i class="PyWhich py-arrow-left"></i></a>
<a href="javascript:void(0);" class="btn next">
<i class="PyWhich py-arrow-right"></i></a>
<ul class="tab">
<!-- 按钮数量必须和图片一致 -->
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<!-- banner end -->
<!-- content start -->
<div class="content">
<!-- recommend-news start -->
<ul class="recommend-news">
<li>
<a href="https://www.shiguangkey.com/course/2432" target="_blank">
<div class="recommend-thumbnail">
<img src="{% static 'img/python_gui.jpg' %}" alt="title">
</div>
<p class="info">Python GUI 教程 25行代码写一个小闹钟</p>
</a>
</li>
<li>
<a href="https://www.shiguangkey.com/course/2432" target="_blank">
<div class="recommend-thumbnail">
<img src="{% static 'img/python_advanced.jpg' %}" alt="title">
</div>
<p class="info">python高性能编程方法一</p>
</a>
</li>
<li>
<a href="https://www.shiguangkey.com/course/2432" target="_blank">
<div class="recommend-thumbnail">
<img src="{% static 'img/jichujiaochen.jpeg' %}" alt="title">
</div>
<p class="info">python基础 split 和 join函数比较</p>
</a>
</li>
</ul>
<!-- recommend-news end -->
<!-- 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 %}
{# <li><a href="javascript:void(0)" data-id="2">Python基础</a>#}
{# </li>#}
{##}
{# <li><a href="javascript:void(0)" data-id="3">Python高级</a>#}
{# </li>#}
{##}
{# <li><a href="javascript:void(0)" data-id="4">Python函数</a>#}
{# </li>#}
{##}
{# <li><a href="javascript:void(0)" data-id="5">PythonGUI</a>#}
{# </li>#}
{##}
{# <li><a href="javascript:void(0)" data-id="6">Linux教程</a>#}
{# </li>#}
</ul>
</nav>
<!-- news-nav end -->
<!-- news-contain start -->
<div class="news-contain">
<ul class="news-list">
<li class="news-item">
<a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"
target="_blank">
<img src="{% static 'img/linux.jpg' %}" alt="linux查找文件或目录命令"
title="linux查找文件或目录命令">
</a>
<div class="news-content">
<h4 class="news-title"><a
href="#">linux查找文件或目录命令</a>
</h4>
<p class="news-details">linux查找文件或目录命令,前提:知道文件或者目录的具体名字,例如:sphinx.conffind 查找find / -name
dirname 查找目录find -name...</p>
<div class="news-other">
<span class="news-type">Linux教程</span>
<span class="news-time">11/11 18:24</span>
<span class="news-author">python</span>
</div>
</div>
</li>
<li class="news-item">
<a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"
target="_blank">
<img src="{% static 'img/linux.jpg' %}" alt="linux下svn命令的使用"
title="linux下svn命令的使用">
</a>
<div class="news-content">
<h4 class="news-title"><a
href="https://www.shiguangkey.com/course/2432/887">linux下svn命令的使用</a>
</h4>
<p class="news-details">1、将文件checkout到本地目录svn checkout path(path是服务器上的目录) 例如:svn checkout
svn://192.168.1.1/pro/domain 简写:svn co2、往版本库中添加新的文件 svn addfile 例如:svn add te...</p>
<div class="news-other">
<span class="news-type">Linux教程</span>
<span class="news-time">11/11 18:24</span>
<span class="news-author">python</span>
</div>
</div>
</li>
<li class="news-item">
<a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"
target="_blank">
<img src="{% static 'img/linux.jpg' %}" alt="实现linux和windows文件传输"
title="实现linux和windows文件传输">
</a>
<div class="news-content">
<h4 class="news-title"><a
href="https://www.shiguangkey.com/course/2432/886">实现linux和windows文件传输</a>
</h4>
<p class="news-details">
其实这个题目有点大,这里介绍的只是linux和windows文件传输中的一种,但是这种方法却非常实用,那就是:ZModem协议具体是linux命令是:rz...</p>
<div class="news-other">
<span class="news-type">Linux教程</span>
<span class="news-time">11/11 18:24</span>
<span class="news-author">python</span>
</div>
</div>
</li>
<li class="news-item">
<a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"
target="_blank">
<img src="{% static 'img/linux.jpg' %}" alt=".htaccess配置详解"
title=".htaccess配置详解">
</a>
<div class="news-content">
<h4 class="news-title"><a
href="https://www.shiguangkey.com/course/2432">.htaccess配置详解</a>
</h4>
<p class="news-details"> .htaccess文件设置基础教程 如果你设置好了比如常用的404页面 301重定向 页面还有500页面等会设置了
无非对你的seo技术有很大帮助那么 .htaccess文件到底怎么设置呢 - .htaccess 文件(或者"分布式...</p>
<div class="news-other">
<span class="news-type">Linux教程</span>
<span class="news-time">11/11 18:24</span>
<span class="news-author">python</span>
</div>
</div>
</li>
<li class="news-item">
<a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"
target="_blank">
<img src="{% static 'img/linux.jpg' %}" alt="使用nohup命令让linux程序后台运行"
title="使用nohup命令让linux程序后台运行">
</a>
<div class="news-content">
<h4 class="news-title"><a
href="https://www.shiguangkey.com/course/2432">使用nohup命令让linux程序后台运行</a>
</h4>
<p class="news-details">使用nohup让程序永远后台运行Unix/Linux下一般比如想让某个程序在后台运行,很多都是使用 &
在程序结尾来让程序自动运行。比如我们要运行mysql在后台:/usr/local/mysql/bin/mysqld_safe --user=mysql &但是...</p>
<div class="news-other">
<span class="news-type">Linux教程</span>
<span class="news-time">11/11 18:24</span>
<span class="news-author">python</span>
</div>
</div>
</li>
</ul>
</div>
<!-- news-contain end -->
<!-- btn-more start -->
<a href="javascript:void(0);" class="btn-more">加载更多</a>
<!-- btn-more end -->
</div>
<!-- content end -->
</div>
{% endblock %}
<!-- main-contain end -->
<!-- main end -->
<!-- footer start -->
<!-- footer end -->
{% block domready %}
<script src="{% static 'js/commons.js' %}"></script>
<script src="{% static 'js/index.js' %}"></script>
{% endblock %}
后台代码
apps/news/models.py
from django.db import models
from utils.models import ModelBase #自己定义的基类
class Tag(ModelBase):
"""
分类/标签
"""
name = models.CharField(max_length=64,verbose_name='标签名',help_text='标签名')
class Meta:
#需要注意的是:不论你使用了多少个字段排序, admin 只使用第一个字段
ordering = ['-update_time','-id'] #按照指定的字段进行数据库的排序, 用更新时间和id,默认从大到小,前面加负号是从小到大
db_table = 'tb_tag' #指定该类的数据库表单名字
verbose_name = '新闻标签' #在admin站点中显示的名称,给你的模型类起一个更可读的名字
verbose_name_plural = verbose_name #显示的复数名称,若未提供该选项, Django 会使用 verbose_name + "s"
def __str__(self):
return self.name
class News(ModelBase):
"""
文章
"""
title = models.CharField(max_length=150,verbose_name='标题',help_text='标题') #字符串,显示名字为标题
digest = models.CharField(max_length=20,verbose_name='摘要',help_text='摘要') #显示的名字和描述都是‘摘要’
content = models.TextField(verbose_name='内容',help_text='内容') #文本
clicks = models.IntegerField(default=0,verbose_name='点击量',help_text='点击量') #整形
image_url = models.URLField(default='',verbose_name='图片url',help_text='图片url') #继承CharField
# 一个标签对应多个文章/新闻,一对多,在多(新闻)里外键关联(ForeignKey)一(标签)
# 外键关联的Tag这里最好用引号,这样不用考虑先后,如果不加引号,Tag模型类必须在News前面
tag= models.ForeignKey('Tag',on_delete=models.SET_NULL,null=True)
# 一个作者/用户对应多个文章/新闻,一对多,在多(新闻)里外键关联(ForeignKey)一(作者)
#on_delete表示外键关联到用户表,SET_NULL表示当用户表删除了该用户,新闻表中不删除,仅仅是把外键置空
author = models.ForeignKey('users.Users',on_delete=models.SET_NULL,null=True)
class Meta:
ordering = ['-update_time','-id']
db_table = 'tb_news'
verbose_name = '新闻'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
class Comments(ModelBase):
"""
评论
"""
content = models.TextField(verbose_name='内容',help_text='内容')
author = models.ForeignKey('users.Users',on_delete=models.SET_NULL,null=True)
#CASCADE级联删除,新闻表删除时评论表也一起删除
news = models.ForeignKey('News',on_delete=models.CASCADE)
class Meta:
ordering = ['-update_time','-id']
db_table = 'tb_comments'
verbose_name = '评论'
verbose_name_plural = verbose_name
def __str__(self):
return f'评论{self.id}'
class HotNews(ModelBase):
"""
热门文章
"""
news = models.OneToOneField('News',on_delete=models.CASCADE)
priority = models.IntegerField(verbose_name='优先级',help_text='优先级')
class Meta:
ordering = ['-update_time','-id']
db_table = 'tb_hotnews'
verbose_name = '热门文章'
verbose_name_plural = verbose_name
def __str__(self):
return f'热门新闻{self.id}'
class Banner(ModelBase):
"""
轮播图
"""
image_url = models.URLField(verbose_name='轮播图url',help_text='轮播图url')
priority = models.IntegerField(verbose_name='优先级',help_text='优先级')
news = models.OneToOneField('News',on_delete=models.CASCADE)
class Meta:
ordering = ['-update_time','-id']
db_table = 'tb_banners'
verbose_name = '轮播图'
verbose_name_plural = verbose_name
def __str__(self):
return f'轮播图{self.id}'
把 urls 改一下,改成 views.IndexView.as_view()
apps/news/views.py
from django.shortcuts import render
from django.views import View
from apps.news import models
def index(request):
return render(request,'news/index.html')
class IndexView(View):
"""
"""
def get(self,request):
# tags = models.Tag.objects.filter(is_delete=False)
#通过表中的is_delete判断是否被删除
tags = models.Tag.objects.only('id','name').filter(is_delete=False) #only确定要查询的字段,其他的不查
# context = {
# 'tags':tags,
# }
#将当前方法下的变量都传进locals,python内置函数
# return render(request,'news/index.html',context=context)
return render(request,'news/index.html',locals())
utils/models.py
#!/home/xiaoge/env python3.6
# -*- coding: utf-8 -*-
"""
__title__ = ' models'
__author__ = 'xiaoge'
__mtime__ = '2019/6/2 下午6:27'
# code is far away from bugs with the god animal protecting
I love animals. They taste delicious.
┏┓ ┏┓
┏┛┻━━━━━━┛┻┓
┃ ☃ ┃
┃ ┳┛ ┗┳ ┃
┃ ┻ ┃
┗━┓ ┏━┛
┃ ┗━━━┓
┃ 神兽保佑 ┣┓
┃永无BUG!┏┛
┗┓┓┏━┳┓┏┛
┃┫┫ ┃┫┫
┗┻┛ ┗┻┛
"""
from django.db import models
class ModelBase(models.Model):
"""
模型基类,不存到数据库中
"""
create_time = models.DateTimeField(auto_now_add=True,verbose_name='创建时间')
update_time = models.DateTimeField(auto_now_add=True,verbose_name='更新时间')
is_delete = models.BooleanField(default=False,verbose_name='逻辑删除')
#该表用于继承,不存到数据库,数据库中没有这张表
class Meta: #抽象类,数据库迁移时不会创建该模型
abstract = True
- 外键关联的 author,tag 自动生成字段 author_id,tag_id