使用Python+Flask开发博客项目,并实现内网穿透_flask框架内网攻击

35 阅读6分钟

### 2.首页文章展示模块


这个模块合并了分页的功能,当发布文章的数量在当前页面无法展示完全的时候就使用增加分页的方式进行展示,并通过bootstrap提供的分页导航栏进行编写。使用bootstrap进行前端页面的开发,可以让我们在不具备很好的前端知识的情况下也可以开发出精美的页面。


![在这里插入图片描述](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/5ab00f6f468a44ccb4c85e25b336a704~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262951&x-signature=zLwa5xRMweHu71FSVmvR%2BiSoiu4%3D)



@front.route('/index') @front.route('/')

@login_required

def index(): page=int(request.args.get('page',default=1)) #找到传入的?page=? 参数,没有的话默认就是1,因为传回来的是字符串,所以需要转化成int #pre_page=? 这个是设置每一页最多显示几条数据 paginate=Article.query.order_by(Article.create_time.desc()).paginate(page=page,per_page=5) article=paginate.items groups=ArticleGroup.query.all() #拿到模型所有的数据 return render_template("index.html",groups=groups,article=article,paginate=paginate)


### 3.文章详情展示模块


这个模块主要是拿到文章模型的全部时间并进行展示,并通过文章的id进行精准展示


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H3NWBcYU-1636098859836)(picture/image-20211105153111194.png)]](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c8d787772940429998919b4c4785a20f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262951&x-signature=%2BruURDBz5%2Bz6ByZbO7WAokLRQkc%3D)



@front.route('/article_detail/int:article\_id')

@login_required

def article_detail(article_id): article=Article.query.get(article_id) groups=ArticleGroup.query.all() #拿到模型所有的数据 return render_template("article_detail.html",groups=groups,article=article)


### 4.文章发布模块


这个模块引入了md格式的文章编写模块,用户可以根据md的语法进行文章发编写与发布,同时增加右边的语法预览框方便用户看到文章的展示情况


![在这里插入图片描述](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/30eb7827a79c411f9a099b69ff62866f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262951&x-signature=%2FUjOgP3Ur93hkAFKLDer1Dy%2F99M%3D)



@front.route('/add_article',methods=['GET','POST'])

@login_required

def add_article(): if request.method=='GET': groups=ArticleGroup.query.all() #拿到模型所有的数据 return render_template("add_article.html",groups=groups) elif request.method=='POST': title=request.form.get('title') content=request.form.get('content') gid=request.form.get('gid')

    user=User.query.filter_by(username=session.get('user')).first()
    uid=user.id
    # 获取当前时间,从datetime这个库里面
    create_time=datetime.datetime.now()

    article=Article()
    article.title=title
    article.content=content
    article.gid=gid
    article.uid=uid
    article.create_time=create_time
    print(user,title,content,gid,uid,create_time)
    try:
        db.session.add(article)
        db.session.commit()
        flash('添加%s成功' % title)
        return redirect(url_for('front.add\_article'))
    except Exception:
        flash('添加%s失败' % title)
        return redirect(url_for('front.add\_article'))

### 5.文章添加分类模块


这个模块,用户可以自己输入要增加的分组的名称,之后可以选择分组要展现的颜色进行展示,并把相关数据存入数据库


![在这里插入图片描述](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/31c68c87b3ae451f94df8ef21af48d50~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262951&x-signature=uBDkuEv%2Bpvpi0pv8YzKZ9FwalJ8%3D)



@front.route("/add_group",methods=['GET','POST']) def add_group(): if request.method=='GET': groups = ArticleGroup.query.all() colors=['default','primary','success','into','warning','danger'] return render_template('add_group.html',colors=colors,groups=groups) elif request.method=='POST': name=request.form.get('name') color=request.form.get('color') group=ArticleGroup() group.name=name group.color=color try: db.session.add(group) db.session.commit() flash("添加分组成功") return redirect(url_for('front.manage')) except Exception: flash("添加失败") return redirect(url_for('front.manage'))


### 6.文章分类管理模块


这个模块主要是对用户编辑的分组与颜色进行编辑与删除的管理功能


![在这里插入图片描述](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e7ac4e7051714362b1f3e26dddbc3691~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262951&x-signature=41weAS8Sab%2FbjCAJwOvffr8nbd4%3D)



@front.route("/article_group_manage")

def article_group_manage(): groups = ArticleGroup.query.all() return render_template('article_group_mange.html',groups=groups) @front.route('/edit_group/int:gid',methods=['GET','POST']) def edit_group(gid): if request.method=='GET': groups=ArticleGroup.query.all() #找到通过id找到分组 group=ArticleGroup.query.get(gid) colors = ['default', 'primary', 'success', 'into', 'warning', 'danger'] return render_template('edit_group.html',group=group,colors=colors,groups=groups) elif request.method=='POST': name=request.form.get("name") color=request.form.get("color")

    group=ArticleGroup.query.get(gid)
    group.name=name
    group.color=color
    try:
        db.session.add(group)
        db.session.commit()
        flash("修改成功")
        return redirect(url_for("front.article\_group\_manage"))
    except Exception:
        flash("修改失败")
        return redirect(url_for("front.article\_group\_mange"))

删除的 视图函数

@front.route('/delete_group/int:gid') def delete_group(gid): group=ArticleGroup.query.get(gid) try: db.session.delete(group) db.session.commit() flash('删除%s成功' % group.name) return redirect(url_for("front.article_group_manage")) except Exception: flash('删除%s失败' % group.name) return redirect(url_for("front.article_group_manage"))


### 7.文章管理模块


这个模块提供了文章的管理功能,用户如果对已经发布的文章有继续改进的想法可以在这个模块进行编辑,并对文章进行删除或者编辑重新发布的操作。


![在这里插入图片描述](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0b3758eef87448629061949ab0420c84~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262951&x-signature=zz%2BKyjwSMlp1PFYC1ADx1mfbtNw%3D)





@front.route('/edit_article/int:article\_id',methods=['GET','POST']) def edit_article(article_id): if request.method=='GET': # 拿到文章内容 article=Article.query.get(article_id) groups=ArticleGroup.query.all() return render_template('edit_article.html',groups=groups,article=article) elif request.method=='POST': title=request.form.get("title") content=request.form.get("content") gid=request.form.get("gid") update_time=datetime.datetime.now()

    article=Article.query.get(article_id)
    article.title=title
    article.content=content
    print(content)
    article.gid=gid
    article.update_time=update_time

    try:
        db.session.commit()
        return redirect(url_for("front.article\_manage"))
    except Exception:
        flash("修改%s失败" % title)
        return redirect(url_for("front.article\_manage"))

@front.route('/delete_article/int:article\_id') def delete_article(article_id): article=Article.query.get(article_id) try: db.session.delete(article) db.session.commit() flash("删除文章%s成功"%article.title) return redirect(url_for("front.article_manage")) except Exception: flash("删除文章%s失败"%article.title) return redirect(url_for("front.article_manage"))


### 8.用户个人信息注销模块


通过这个模块用户可以一键注销当前登录的账号,并回到登录页面



注销登录,在base写上

@front.route('/logout') def logout(): session.clear() flash("注销登录成功") return redirect(url_for('front.login'))


### 9.信息管理模块


对于上面模块的信息都需要存入到mysql数据库,首先在本地的MySQL数据库创建一个blog库,之后执行Web项目,这个模块会把对于的数据库表信息与数据库表进行映射创建,并赋值对应的类型。实现可以避免手动创建数据表的繁杂操作。



login_manager = LoginManager()

db=SQLAlchemy() #实例化sqlalchemy对象

class User(db.Model,UserMixin): # __tablename__='login_register' id = Column(db.Integer,autoincrement=True,primary_key=True) #autoincrement自增长 username=Column(db.String(50),nullable=False) password=Column(db.String(128),nullable=True)

# 没有这个的话,使用{{users}}显示的就是一个对象
def \_\_repr\_\_(self):
    return self.username

def get\_id(self):
    return True

class Article(db.Model): tablename='article' id = db.Column(db.Integer, autoincrement=True, primary_key=True) title = db.Column(db.String(50), nullable=False,unique=True) content=db.Column(db.String(512),nullable=True) uid=db.Column(db.Integer,db.ForeignKey('user.id')) gid=db.Column(db.Integer,db.ForeignKey('article_group.id')) create_time=db.Column(db.DateTime) update_time=db.Column(db.DateTime) #下面相当于做一个联表查询。 users=db.relationship('User',backref=db.backref('articles')) groups=db.relationship('ArticleGroup',backref=db.backref('articles'))

def \_\_repr\_\_(self):
    return '<Article %s>'%self.title

class ArticleGroup(db.Model): tablename='article_group' id = db.Column(db.Integer, autoincrement=True, primary_key=True) name = db.Column(db.String(50), nullable=False,unique=True) color= db.Column(db.String(50), nullable=False)

def \_\_repr\_\_(self):
    return '<ArticleGroup %s>'% self.name

@login_manager.user_loader def get_user(user_id): #对主键的查询是没有必要使用filler_by的 user = db.session.query(User).get(user_id) return user


### 10.程序启动模块


这个模块为了让Flask的启动入口更加的简洁,我对启动模块的代码进行了封装操作。



def create_app(): app=Flask(name) app.config.from_object('config') register_blueprint(app) db.init_app(app)

login_manager.init_app(app)
login_manager.login_view="front.login"
login_manager.login_message_category='请先登录或注册'

db.create_all(app=app)
return app

def register_blueprint(app): from front_back import front app.register_blueprint(front)


**应用程序主类**  
 ![在这里插入图片描述](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/6d970438a1104f42855672595abea75e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262951&x-signature=%2B3NkcK26qmB4hubEX%2FCs2Oq4MtI%3D)



from current import create_app

app=create_app() if name == 'main': app.run(host='0.0.0.0',debug=True,port=83)

img img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!