项目:新闻系统
Todo:【新闻系统】
需要用户注册,登录,登陆之后可以在前台进行发布新闻,管理员在后台进行登录,登录之后就可以看到已经注册了哪些用户,以及哪个用户发布了什么新闻。
查看新闻,进行审核,审核通过的新闻才能正常显示出来。
正常在前台发布的是待审核的文章,待审核状态的文章是不能显示出来的。
用户中心:修改资料,上传头像,用户发布的文章,收藏的文章。
可以评论文章,评论的信息要显示到文章详情页下面。
收藏文章。
用户列表,对用户进行删除,看到文章列表,文章分类是在后台进行添加的。
前台:
注册模块
登录模块:验证码
用户中心:
上传头像:上传图片
发布文章:富文本编辑器
首页:分页展示文章列表
文章分类:点击某一个分类展示此分类下面的文章
文章详情页面:评论,收藏(多对多)
后台:
登录
添加修改删除分类
审核文章
管理用户
文章列表:搜索

# start.py
""" Todo:入口文件【不放置任何前后台视图函数】 """
from models import *
from modules.web.index import index_blue
from modules.web.user import user_blue
from modules.web.news import news_blue
from modules.admin.index import admin_index_blue
from modules.admin.news import admin_news_blue
# 注册蓝图:
# 前台:
app.register_blueprint(index_blue)
app.register_blueprint(user_blue, url_prefix='/user')
app.register_blueprint(news_blue, url_prefix='/news')
# 后台:
app.register_blueprint(admin_index_blue, url_prefix='/admin')
app.register_blueprint(admin_news_blue, url_prefix='/admin')
# 将cate_id放置到g变量中,以便各个视图函数使用
@app.before_request
def g_cates_data():
cates = Cate.query.all()
g.cates = cates
if __name__ == '__main__':
# db.drop_all()
# db.create_all()
app.run()
# setting.py
""" Todo:配置文件 """
DEBUG = True # 开启调试
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:mysql@127.0.0.1:3306/item?charset=utf8' # 连接数据库
# SQLALCHEMY_ECHO = True # 查询时会显示原始sql语句【在控制面板显示】
SECRET_KEY = 'abc' # 密钥
SQLALCHEMY_TRACK_MODIFICATIONS = False # 是否显示警告信息
SQLALCHEMY_COMMIT_ON_TEARDOWN = True # 数据内容发生改变之后,自动提交
PER_PAGE_NUM=2 # 分页【如果总数据未超过定义的分页数据PER_PAGE_NUM,则不会显示分页】
# models.py
""" Todo:创建表 """
from apps import *
from datetime import datetime
# 基类
class BaseModel():
create_time = db.Column(db.DateTime, default=datetime.now, comment='创建时间')
# onupdate 这个属性可以起到更新记录的时候更新 update_time 字段为当时的修改时间
update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now ,comment='更新时间')
''' 前台 '''
# 用户表和新闻表的关系表
tb_user_news = db.Table(
'tb_user_news',
db.Column('id', db.Integer, primary_key=True, comment='主键ID'),
db.Column('user_id', db.Integer, db.ForeignKey('user.id'), comment='外键指向user表ID'),
db.Column('news_id', db.Integer, db.ForeignKey('news.id'), comment='外键指向news表ID'),
)
# 用户表
class User(db.Model, BaseModel):
id = db.Column(db.Integer, primary_key=True, comment='主键ID')
name = db.Column(db.String(30), nullable=False, default='', comment='用户名')
pwd = db.Column(db.String(30), nullable=False, default='', comment='密码')
pic = db.Column(db.String(100), default='default.jpg', comment='头像')
collections = db.relationship('News', secondary=tb_user_news)
# 新闻分类表
class Cate(db.Model, BaseModel):
id = db.Column(db.Integer, primary_key=True, comment='新闻分类ID')
name = db.Column(db.String(30), nullable=False, default='', comment='新闻分类名称')
newss = db.relationship('News', backref='one_cate' )
# 新闻文章表
class News(db.Model, BaseModel):
id = db.Column(db.Integer, primary_key=True, comment='新闻文章主键ID')
title = db.Column(db.String(30), nullable=False, default='', comment='新闻文章名称')
content = db.Column(db.Text, comment='新闻内容')
status = db.Column(db.Integer, default=0, comment='新闻状态:0未审核,1通过,-1未通过')
cate_id = db.Column(db.Integer, db.ForeignKey(Cate.id), comment='外键指向新闻分类ID')
user_id = db.Column(db.Integer, db.ForeignKey(User.id), comment='外键指向用户ID')
# 评论表
class Comment(db.Model, BaseModel):
id = db.Column(db.Integer, primary_key=True, comment='主键ID')
content = db.Column(db.String(255), comment='评论内容')
user_id = db.Column(db.Integer, db.ForeignKey(User.id), comment='外键指向用户ID')
news_id = db.Column(db.Integer, db.ForeignKey(News.id), comment='外键指向新闻ID')
''' 后台 '''
# 管理员表
class Admin(db.Model, BaseModel):
id = db.Column(db.Integer, primary_key=True, comment='主键ID')
name = db.Column(db.String(30), comment='管理员名称')
pass_hash = db.Column(db.String(128), comment='管理员密码')
# manager.py
""" Todo """
from flask_script import Manager
from apps import app
from flask_migrate import Migrate, MigrateCommand
from models import db
manager = Manager(app=app)
migrate = Migrate(app=app, db=db)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
# apps.py
""" Todo:实例化app,挂载各种扩展 """
from flask import Flask, Blueprint, render_template, request, flash, redirect, url_for, session, make_response, g, current_app, jsonify
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import and_
import sys, os
from flask_uploads import UploadSet, IMAGES, configure_uploads
app = Flask(__name__)
app.config.from_object('setting')
# print(sys.modules['__main__']) # 获取入口文件的物理位置:<module '__main__' from 'C:\\Users\\Dell\\Desktop\\ITEM\\start.py'>
print(getattr(sys.modules['__main__'], '__file__')) # C:\Users\Dell\Desktop\ITEM\start.py
enter = getattr(sys.modules['__main__'], '__file__')
# 拼接后的路径:C:\Users\Dell\Desktop\ITEM/static/upload
# 加os.path.abspath()后的绝对路径:C:\Users\Dell\Desktop\ITEM\static\upload
root_path = os.path.abspath(os.path.dirname(enter)+'/static/upload')
app.config['UPLOADED_ITEM_DEST'] = root_path # 设置上传路径
app.config['UPLOADED_ITEM_ALLOW'] = IMAGES # 允许类型
item = UploadSet('ITEM') # 实例化图片上传类,设置上传的统一名称
configure_uploads(app, item) # 将app的config配置注册到UploadSet实例item
db = SQLAlchemy(app=app)
一、数据库迁移命令【即:生成 migrations 目录的命令】
终端操作:
1、初始化迁移环境:python manager.py db init
2、生成迁移版本:python manager.py db migrate
3、提交到数据库:python manager.py db upgrade
注意:如果后期变更/增加表或者表中的字段,则只需要在终端输入后两条命令。(即:不需要初始化)
二、modules 目录【admin和web】
1、admin——后台
# index.py【首页】
""" Todo """
from models import *
from werkzeug.security import generate_password_hash, check_password_hash
from utils.common import is_admin_login
admin_index_blue = Blueprint('admin', __name__)
# 定义创建管理员的视图函数
@admin_index_blue.route('/add_admin')
def add_admin():
new_admin = Admin(name='admin', pass_hash=generate_password_hash('962464'))
db.session.add(new_admin)
return redirect(url_for('admin.login'))
# 后台首页
@admin_index_blue.route('/')
@is_admin_login
def index():
newss = News.query.all()
comments = Comment.query.all()
users = User.query.all()
return render_template('admin/index.html', newss=newss, comments=comments, users=users)
# 后台登录
# @admin_index_blue.route('/login', methods=['GET', 'POST'])
# def login():
# if request.method == 'POST':
# name = request.form.get('name')
# pass_hash = request.form.get('pass_hash')
# one_admin = Admin.query.filter(Admin.name == name).first()
# if not one_admin:
# flash('管理员不存在')
# else:
# # 验证密码方法。返回True或False【第一个参数:数据库里面保存的密文密码。第二个参数:传递过来的明文密码】
# flag = check_password_hash(one_admin.pass_hash, pass_hash)
# if flag:
# session['admin_id'] = one_admin.id
# session['admin_name'] = one_admin.name
# flash('管理员登录成功!')
# return redirect(url_for('admin.index'))
# else:
# flash('管理员登录失败')
# return render_template('admin/login.html')
# 后台登录
'''
json
'''
@admin_index_blue.route('/login', methods=['GET', 'POST'])
def login():
# 定义一个字典
# if request.method == 'POST':
# r = {
# 'code':300,
# 'message':'成功',
# }
# return jsonify(r)
if request.method == 'POST':
r = {}
name = request.form.get('name')
pass_hash = request.form.get('pass_hash')
one_admin = Admin.query.filter(Admin.name == name).first()
if not one_admin:
r = {
'code':300,
'message':'用户不存在',
}
else:
# 验证密码方法。返回True或False【第一个参数:数据库里面保存的密文密码。第二个参数:传递过来的明文密码】
flag = check_password_hash(one_admin.pass_hash, pass_hash)
if flag:
session['admin_id'] = one_admin.id
session['admin_name'] = one_admin.name
r = {
'code':200,
'message':'登录成功!',
}
else:
r = {