前言
Flask是一个使用python编写的轻量级Web框架,对比其他相同类型的框架而言,这个框架更加的灵活轻便。并且具有很强的定制性,用户可以根据自己的需求添加功能,有强大的插件库,这也是为什么这个框架在python领域一直火热的原因。这篇文章我们将使用这个框架编写一个属于自己的博客网站!并教你如何通过使用内网穿透工具处理项目,让本地的项目可以在公网访问!
文章目录
- 1.个人的注册与登录模块
- 2.首页文章展示模块
- 3.文章详情展示模块
- 4.文章发布模块
- 5.文章添加分类模块
- 6.文章分类管理模块
- 7.文章管理模块
- 8.用户个人信息注销模块
- 9.信息管理模块
- 10.程序启动模块
- 11.内网穿透模块
- 12.总结
丠x1f680;首先来看看我们开发的博客Web项目的一些展示
项目主要包含主要以下功能:个人注册于登录,首页文章展示,文章详情展示,文章发布模块,文章添加分类模块,文章分类管理模块,用户信息管理模块,程序启动模块。
🚀下面我们对各个模块的代码进行编写
1.个人的注册与登录模块
这个模块的主要让用户进行用户的注册,之后判断输入的密码是否一致,并将结果写入到数据库。
from flask import render_template, redirect, url_for, request, flash, sessionfrom front_back import frontfrom modles.dbmodels import User, dbimport hashlibfrom utils import login_check@front.route('/login',methods=['GET','POST'])def login():if request.method=='GET':return render_template('login.html')elif request.method=='POST':username=request.form.get('username')password=request.form.get('password')user=User.query.filter_by(username=username,password=password).first()print(user)if user:session['user']=usernameprint(session['user'])flash('登录成功')return redirect(url_for('front.index'))else:flash('登录失败')return redirect(url_for('front.login'))@front.route('/register',methods=['GET','POST'])def register():# 如果是get请求的话就返回页面,post请求的话就接收表单数据if request.method == 'GET':return render_template("register.html")elif request.method == 'POST':username = request.form.get('username')password = request.form.get('password')check_password = request.form.get('check_password')if username and password and password == check_password:md5 = hashlib.md5()md5.update(password.encode('utf-8'))user = User()user.username = username# 使用hashlib加密密码再存入数据库,拿到md5.hexdigest()加密后的密码user.password = md5.hexdigest()user.password=passwordprint(username,password)try:db.session.add(user)db.session.commit()flash('注册成功,欢迎访问我的个人博客!')return redirect(url_for('front.register'))except Exception:flash('注册失败,请检查密码后重新注册')return redirect(url_for('front.register'))else:flash('注册失败')return redirect(url_for('front.register'))
2.首页文章展示模块
这个模块合并了分页的功能,当发布文章的数量在当前页面无法展示完全的时候就使用增加分页的方式进行展示,并通过bootstrap提供的分页导航栏进行编写。使用bootstrap进行前端页面的开发,可以让我们在不具备很好的前端知识的情况下也可以开发出精美的页面。
@front.route('/index')@front.route('/')# @login_requireddef 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.itemsgroups=ArticleGroup.query.all() #拿到模型所有的数据return render_template("index.html",groups=groups,article=article,paginate=paginate)
3.文章详情展示模块
这个模块主要是拿到文章模型的全部时间并进行展示,并通过文章的id进行精准展示
@front.route('/article_detail/<int:article_id>')# @login_requireddef 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的语法进行文章发编写与发布,同时增加右边的语法预览框方便用户看到文章的展示情况
@front.route('/add_article',methods=['GET','POST'])# @login_requireddef 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=titlearticle.content=contentarticle.gid=gidarticle.uid=uidarticle.create_time=create_timeprint(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.文章添加分类模块
这个模块,用户可以自己输入要增加的分组的名称,之后可以选择分组要展现的颜色进行展示,并把相关数据存入数据库
@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=namegroup.color=colortry:db.session.add(group)db.session.commit()flash("添加分组成功")return redirect(url_for('front.manage'))except Exception:flash("添加失败")return redirect(url_for('front.manage'))
6.文章分类管理模块
这个模块主要是对用户编辑的分组与颜色进行编辑与删除的管理功能
@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=namegroup.color=colortry: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.文章管理模块
这个模块提供了文章的管理功能,用户如果对已经发布的文章有继续改进的想法可以在这个模块进行编辑,并对文章进行删除或者编辑重新发布的操作。
@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=titlearticle.content=contentprint(content)article.gid=gidarticle.update_time=update_timetry: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.usernamedef get_id(self):return Trueclass 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.titleclass 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_loaderdef 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 appdef register_blueprint(app):from front_back import frontapp.register_blueprint(front)
应用程序主类
from current import create_appapp=create_app()if __name__ == '__main__':app.run(host='0.0.0.0',debug=True,port=83)
到这里我们的博客项目相关模块就编写完成啦,其实还有很多的功能小伙伴们可以根据自己的需求添加,这也是Flask极具特色的一个地方,这里要说明的一点是,由于前端部分的代码太多啦,这里就不展示出来了,需要的小伙伴可以私聊我拿到整体的代码哟。
11.内网穿透模块
这个模块对于很多小伙伴来说可能比较陌生,这里举一个例子方便小伙伴们理解。
假如说我们要把上面写好的项目进行部署,并让全部人可以使用的话,很容易想到的一点是,利用服务器。但是服务器的成本较高,而且部署的过程也比较繁杂,那么有没有什么好的方式可以帮我们实现本地的服务id映射到公网访问呢?答案就是内网穿透
这里给大家介绍一个快捷的内网穿透工具,花生壳。大家可以直接去搜索下载哦。
下载好之后我们只需要把我们本机的ip输入进去,他就会帮我们生成一个域名,实现公网可访问,如下图。
之后到浏览器测试是否可以访问,可以成功访问即代表映射成功:
12.总结
到这里对于博客的编写与内网穿透的实践就介绍完了!总体来说要上手Flask这个框架的话还是不难的,但重要的是当你想学习一样东西的时候就要坚持下去,努力了就会有回报!需要获取完整源码的同学也可以关注下方的公众号给我留言哦🏭