Flask-新闻系统项目

本文介绍了如何使用Flask框架创建一个新闻系统,包括数据库迁移步骤、项目目录结构解析以及如何启动程序。通过终端操作进行数据库迁移,并使用navicat等工具实时查看数据变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目:新闻系统

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 = {
  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值