猪精雅0

导航

期末作品检查

  • 连接数据库
打开命令提示符(win+R)

输入 cmd 回车

输入 数据库的bin文件的路径,例:C:\Program Files\MySQL\MySQL Server 5.7\bin 回车
输入 mysql -u root -p 回车

输入 mysql的密码 回车(有设置密码就输入密码 回车,没密码就直接回车)

输入 show databases; 回车(注意:有 s 和 ; 号)

输入 create database (数据库名)charset utf8;(注意:此处的database无s,区别于上一条代码,charset utf8设置了这个才能将中文存入数据库)

运行结果如图:

 

  • 创建数据库的表格
建立mysql和app的连接,创建用户模型

在py文件中创建表格

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import databases

app = Flask(__name__)
app.config.from_object(databases)#app连接数据库

db = SQLAlchemy(app)

class User(db.Model):创建user表格
    __tablename__ ='user'
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    username = db.Column(db.String(20),nullable=False)
    password = db.Column(db.String(20), nullable=False)
class Trip(db.Model):
__tablename__='trips'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
author_id = db.Column(db.Integer,db.ForeignKey('user1.id'))
ttitle = db.Column(db.String(100),nullable=False)
loca = db.Column(db.String(100),nullable=False)
feeling =db.Column(db.Text,nullable=False)
creat_time = db.Column(db.DateTime,default=datetime.now)
author = db.relationship('User', backref=db.backref('trips'))链接user表,通过user.trips可以获取到trip表的内容

class Comment(db.Model):
__tablename__ = 'comment'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
author_id = db.Column(db.Integer, db.ForeignKey('user1.id'))
trip_id = db.Column(db.Integer, db.ForeignKey('trips.id'))
detail = db.Column(db.Text, nullable=False)
creat_time = db.Column(db.DateTime, default=datetime.now)
author = db.relationship('User', backref=db.backref('comments'))链接到user表,通过user.comments可以获取到comment表中的内容
travel = db.relationship('Trip', backref=db.backref('comments'))链接到trip表,通过trip.comments可以获取到comment表中的内容
 
db.create_all()数据库创建表格语句 @app.route('/') def hello_world(): return 'Hello World!'


另一个py文件
数据库配置信息databases.py

SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:@127.0.0.1:3306/data?charset=utf8' 注释:root是数据库名,冒号后面是密码
 SQLALCHEMY_TRACK_MODIFICATIONS =False
 

 

  • 项目需要使用的库
from flask import Flask,request,render_template,redirect,url_for,session
from flask_sqlalchemy import SQLAlchemy
import sqlconnect
from functools import wraps
from  datetime import datetime
from sqlalchemy import or_, and_
from werkzeug.security import generate_password_hash,check_password_hash

 

  • 网站父模板统一布局:头部导航条、中间主显示区域布局

作为父模板,要让子模板继承,要加{%block title %}{% endblock %}
{%block title %}{% endblock %}子模板可以增加title
{%block head %}{% endblock %}子模板可以增加head
{%block main %}{% endblock %}子模板可以增加body的内容
头部导航条
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %} </title>
<link href="../static/base.css" rel="stylesheet" type="text/css"> 连接到css文件
<script src="../static/base.js"></script> 连接到javaScript文件
{% block head %}{% endblock %}
</head>
<body id="myBody">
<div class="daohanglang" id="daohanglang">
    <ul class="daohanglang dh" id="daohanglang">
        <li><img class="turn_on_off" id="on_off" onclick="mySwitch()" src="{{ url_for('static',filename='image/on.jpg') }}" width="25px" height="30px"></li>
        <li class="daohang"><a class="daohang"  href="{{ url_for('first')}}"><img src="../static/image/sy.png" width="25px">首页</a></li>
        <li class="daohang"><a class="daohang"  href="{{ url_for('trip')}}">发布游记</a></li>
        <li class="daohang"><a class="daohang"  href="#">旅行攻略</a></li>
        <li class="daohang">
            <form action="{{ url_for('search') }}">
                <input class="sousuo" id="sousuo" type="text" placeholder="搜索" name="tri">
                <button type="submit" ><img src="../static/image/fdj.png" width="15px"></button>
            </form>
        </li>
    </ul>
  <nav>
{% if username %}
<a class="daohangright" href="{{ url_for('logout') }}">注销</a> logout是后台设置注销功能的函数名
<a class="daohangright" href="{{ url_for('centen',user_id =session['userid'], tag='1') }}"><img src="../static/image/ren.png" width="20px" height="20px"> {{ username       }}</a>
{% else %}
<a class="daohangright" href="{{ url_for('sign_up') }}" >注册</a> sign_in是后台设置登录功能的函数名
<a class="daohangright" href="{{ url_for('sign_in') }}" >登录</a> sign_up是后台设置注册功能的函数名
{% endif %}
  </nav>
</div>
中间的主显示区,主要在body里面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body>注释:<div style=“...”>通过在style设置,可以设置div的位置,样式等,也可以通过css文件来设置   <div>

    hello python!
  </div>
  <div>
    hello word!
  </div>
</body> </html>

 

  • 注册、登录、注销
注册页面的前端
<div class="box"> <h2 class="title"> <div class="normal-title">   <a class="color" href="http://127.0.0.1:5000/login/">登录</a>   <b>|</b>   <a class="color" href="http://127.0.0.1:5000/regiter/">注册</a> </div></h2> <form action="http://127.0.0.1:5000/regiter/" method="post"> <div class="input-box" > <input id="newname" type="text" placeholder="please enter user name" name="newname">用户设置用户名 name="newname"是给后台传值,id="newname"是给javascript传值 </div> <div class="input_box"> <input id="newpass" type="password" placeholder="Please enter your password" name="newpass">用户设置密码 name="newname"是给后台传值,id="newname"是给javascript传值
      </div>
      <div class="input_box"> <input id="againpass" type="password" placeholder="Please enter your password again" name="againpass">用户确定密码 </div>

       <div id="error_box"><br></div>设置一个报错的div,验证输入的内容是否合法
       <div class="input_box"> <button onclick="return mySubmit()">Submit</button></div>提交按钮,onclick是给按钮添加动作,返回一个mySubmit()的函数
 </form> </div>
javaScript 用于验证用户注册的用户名和密码是否合法
function mySubmit(){
            var oNewname = document.getElementById("newname");
            var oNewpass = document.getElementById("newpass");
            var oAgainname = document.getElementById("againpass");
            var oError = document.getElementById("error_box");
            oError.innerHTML="<br>"
            //验证用户名,用户名要6-12位数
            if(oNewname.value.length<6 && oNewname.value.length>12) {
                oError.innerHTML = "User name must be between 6 and 12 digits!!!";
                return false;
            }
      //用户名的第一位不能是数字
           else if ((oNewname.value.charCodeAt(0)>=48)&&(oNewname.value.charCodeAt(0)<=57)){
                oError.innerHTML = "The first letter can not be a number!!!";
                return false;
            }
       //用户名只能为数字或密码
            else for(var i=0;i<oNewname.value.length;i++){
                if((oNewname.value.charCodeAt(i)<48 || oNewname.value.charCodeAt(i)>57)&&(oNewname.value.charCodeAt(i)<97 || oNewname.value.charCodeAt(i)>122)){
                    oError.innerHTML = "Only number and letter!!! ";
                    return false;
                }
                }
            //验证密码
            if(oNewpass.value.length>12|| oNewpass.value.length<6){
                oError.innerHTML="The password must be between 6 and 12 digits!";
                return false;
            }
           //判断用户输入两次的密码是否一致
            else if(oNewpass.value != oAgainname.value) {
                oError.innerHTML="The password entered twice is not the same!!!";
                return false;
            }
        //验证成功
            window.alert("Successful registration!")
            return true;
        }
注册页面的后台python文件
@app.route("/regiter/",methods=['GET','POST'])网页请求的方法:GET,POST Get方法用于浏览页面,Post方法用于提交页面 def sign_up(): if request.method == 'GET':如果请求的方法是GET return render_template("sign_up.html")返回注册页面 else: name = request.form.get('newname')获取前端的用户名 passw = request.form.get('newpass')获取前端的用户密码 samename = User.query.filter(User.username == name).first()在User表中查询是否存在一样的用户名 if samename:存在一样的用户名,返回提示 return u'username existed!' else: # 将用户名和密码存入数据库 users =User(username = name ,password = passw,) db.session.add(users) db.session.commit() return render_template("sign_in.html")#注册成功后跳转到登录界面

注:登录页面的前端与注册页面的前端相似,验证用户名和密码是否合法的方法也是相似的

登录页面的后台python文件
@app.route("/login/",methods=['GET','POST'])
def sign_in():
    if request.method =='GET':
        return render_template("sign_in.html")
    else:
        name = request.form.get('name')
        passw = request.form.get('password')
        user = User.query.filter(User.username == name).first()
        #判断用户名是否存在
        if user:
            #判断密码是否正确
            if user.check_password(passw):
                session['user']=name#记住用户名  前端调用:session['user'] 后端调用:session.get('user')
                session['userid'] = user.id 记住用户id
                session.permanent = True
                return redirect(url_for('first'))登录成功返回首页
            else:
                return u'密码错误!'
        else:
            return u'不存在该用户名!'
注销只需要清除session保存的值
@app.route('/logout/')
def logout():
    session.clear()
    return redirect(url_for('first'))

运行结果如图:

     

 

 

  • 发布、列表显示
发布页面的前端
{% extends 'base.html' %}继承父模板
{% block title %}
发布游记
{% endblock %}
{% block head %}
    <link href="../static/tijiao.css" rel="stylesheet" type="text/css">
    <script src="../static/tijiao.js"></script>
{% endblock %}
{% block main %}
<h2 style="text-align:center; font-family:华文行楷" >发布游记</h2>
    <form action="http://127.0.0.1:5000/trip/" method="post" style="align-content: left">
        <div class="triptext">
            <label for="zhuti" class="wenzi" >主题</label><br>
            <textarea class="zhuyaoneirong" rows="1" cols="65" id="zhuyao" name="biaoti"></textarea><br>
            <label for="didian" class="wenzi">地点</label><br>
            <textarea class="zhuyaoneirong" rows="1" cols="65" id="zhuyao" name="locat"></textarea><br>
            <label for="youji" class="wenzi">游记</label><br> 
            <textarea class="neirong" rows="20" cols="65" id="xiangqing" name="feel"></textarea><br>
            <button onclick="return myQuestion()">发布</button>
        </div>
    </form>
{% endblock %}
发布页面的JavaScript
function myQuestion(){
    return True
}
发布页面的后端python
@app.route("/trip/",methods=['GET','POST'])
@login_re
def trip():
    if request.method=='GET':
        return render_template("trip.html")
    else:
        ttitle = request.form.get('biaoti')
        location = request.form.get('locat')
        feel = request.form.get('feel')
        authorid = User.query.filter(User.username == session.get('user')).first().id
        trips = Trip(ttitle =ttitle,loca = location,feeling=feel,author_id=authorid)
        db.session.add(trips)将用户输入的游记存入Trip表
        db.session.commit()
        return redirect(url_for('first'))


首页显示Trip表中的数据
@app.route('/')
def first():
context={
      查找Trip表中所有的数据
'visit':Trip.query.order_by('-creat_time').all()#在Trip表中查询,根据创建时间排序
}
return render_template("first.html",**context)把context传值给first页面发布列表发布的游记显示在首页{% extends 'base.html' %}
{% block title %}
首页
{% endblock %}
{% block head %}
    <link href="{{ url_for('static',filename='zz.css') }}" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript" src="../static/gongneng.js"></script>
{% endblock %}

{% block main %}
<body bgcolor="#696969">
<div id="kuai">
    <ul class="trip-list" >
        {% for t in visit %}<li class="trip">
                <span class="" aria-hidden="true"></span>
                <a class="picture"><img src="../static/image/tx1.png"> </a>
                <a href="{{ url_for('centen',user_id=t.author_id,tag=1) }}" class="a wenzi">{{ t.author.username }}</a>给用户名添加链接,链接到该用户的个人中心
                <span class="createtime wenzi">{{ t.creat_time }}</span><br>显示发布游记的时间 
        <a class="a wenzi" href="{{ url_for ('td',trip_id=t.id) }}" >{{ t.ttitle }}</a>链接到这篇游记的详细内容页
<span class="location wenzi"><img src="../static/image/dd.png" width="15px"> {{ t.loca }}</span> 显示地点
<p class="wenzi">{{ t.feeling }}</p> </li>显示游记内容
       <li class="nav">
        <div class="dzsc"> <a href="{{ url_for ('td',trip_id=t.id) }}" class="aa wenzi"> <img src="../static/image/pl.png" width="18px"> {{ t.comments|length }} </a>
        注释:显示该游记总评论数,链接到详情页,获取这篇游记的id传递给详情页
        </div> </li>
       <hr style="width: 100%"> {% endfor %}
       </ul>
        </div> </body> {% endblock %}

 运行结果如图:

 

  • 详情页、评论、列表显示
详情页面的前端
{% extends 'base.html' %}继承父模板 {% block title %} {% endblock %} {% block head %} <link href="../static/zz.css" rel="stylesheet" type="text/css"> <script src="../static/tijiao.js"></script> {% endblock %} {% block main %} <body bgcolor="#696969"> <div style="float: right"> <ul id="divright"> <li><a class="dtpic"> <img src="../static/image/tx1.png"> </a></li> <li><a href="{{ url_for('centen',user_id=tri.author_id,tag=1) }}" class="a wenzi">{{ tri.author.username }}</a></li><br>
    注释:{{tri.author.username}}是显示游记的作者名

      {{url_for('center',user_id=tri.author_id,tag=1)}}给名字添加链接,链接到该作者的用户中心,给center传入作者的id和tag=1的信息 <li><span class="wenzi">{{ tri.loca }}</span></li><br>显游记的地点 <li><span class="createtime wenzi">{{ tri.creat_time }}</span></li><br>显示发布游记的时间 </ul> </div> <div id="divleft" class="bianju"> <div class="bianju"> <p class="a center wenzi">{{ tri.ttitle }}</p>显示游记的题目 <br> <p class="wenzi">{{ tri.feeling }}</p><br>显示游记的内容 </div> <hr> <form action="{{ url_for('comment') }}" method="post" >设置form表单用户提交用户的评论 <div class="bianju"> <textarea class="wenzi" row="3" cols="100" placeholder="请输入评论" name="pinglun" ></textarea> <input name="tripid" type="hidden" value="{{ tri.id }}">隐藏的输入框,输入用户的id <button type="submit">发送</button> </div> </form> <hr> <div class="bianju"> <h4 class="wenzi"><img src="../static/image/pl.png" width="20"> {{ tri.comments|length }}</h4>显示该文章评论总数 <hr> <ul style="margin-bottom: 10px"> {% for co in tri.comments %}循环输出该游记的所有评论 <li> <a href="{{ url_for('centen',user_id=co.author_id,tag=1) }}" class="a wenzi">{{ co.author.username }}</a>显示评论者名 <span class="createtime wenzi">{{ co.creat_time }}</span>显示评论时间 <p class="wenzi">{{ co.detail }}</p><br>显示评论内容 </li> <hr> {% endfor %} </ul> </div> </div> </body> {% endblock %}
游记详情页面的后端,python文件
@app.route("/td/<trip_id>")传递游记的id def td(trip_id): trip=Trip.query.filter(Trip.id == trip_id).first()查找到该游记的数据 return render_template("tripdetial.html",tri=trip )传递给详情页
用户提交评论的后端操作,python文件
@app.route("/comment/",methods=['POST'])
@login_re
def comment():
    detial=request.form.get('pinglun')获取前端传递的评论
    trip_id = request.form.get('tripid')获取前端传递的游记id
    author_id = User.query.filter(User.username == session.get('user')).first().id  通过用户名查找到该用户的id
    comment = Comment(detail=detial,author_id=author_id,trip_id=trip_id) 将评论内容,用户id和游记id存入Comment表
    db.session.add(comment)
    db.session.commit()
    return redirect(url_for("td",trip_id=trip_id ))返回该篇游记的详情页

 

运行结果如图:

 

  • 个人中心
个人中心页面前端
{% extends 'base.html' %}
{% block title %} 个人中心 {% endblock %} {% block head %} <link href="{{ url_for('static',filename='zz.css') }}" rel="stylesheet" type="text/css"> <link href="{{ url_for('static',filename='base.css') }}" rel="stylesheet" type="text/css"> {% block header %}{% endblock %} {% endblock %} {% block main %} <body bgcolor="#a9a9a9"> <div class="div-center"> <div class="biaotidh"> <ul class="nav_ul">
      注释:个人中心显示该用户所有的游记,评论,点赞数和收藏数 <li role="presentation"><a href="{{ url_for('centen',user_id = user.id,tag='1') }}" class="a wenzii border">全部游记</a></li> <li role="presentation"><a href="{{ url_for('centen',user_id = user.id,tag='2') }}" class="a wenzii border">全部评论</a></li> <li role="presentation"><a href="{{ url_for('centen',user_id = user.id,tag='3') }}" class="a wenzii border">个人中心</a></li> </ul> </div> <hr> {% block user %}让子页面继承 {% endblock %} </div> </body> {% endblock %}
个人中心--全部评论页面前端
{% extends 'usercen.html' %}继承个人中心页面
{% block header %}
    <link href="{{ url_for('static',filename='zz.css') }}" rel="stylesheet" type="text/css">
    <link href="{{ url_for('static',filename='base.css') }}" rel="stylesheet" type="text/css">
{% endblock %}
{% block user %}
<div>
    <a class="dtpicc"><img src="{{ url_for('static',filename='image/tx1.png') }}"></a>
    <span class="wenzi a">{{ username }}</span>
    <h4 class="wenzi">游记:({{ travel|length }})</h4>
    <ul class="usertrip" >
        {% for ave in travel %}
            <li class="trip">
                <span class="createtime wenzi">{{ ave.creat_time }}</span><br><br>
                <a class="a wenzi" href="{{ url_for ('td',trip_id=ave.id) }}" >{{ ave.ttitle }}</a>
            </li>
        {% endfor %}
    </ul>
</div>
{% endblock %}
个人中心页面的后端,python
@app.route("/centen/<user_id>/<tag>")
@login_re
def centen(user_id,tag):
    user = User.query.filter(User.id == user_id).first()
    zan = Dianzan.query.filter(Dianzan.author_id == user.id).all()
    cang = Shoucang.query.filter(Shoucang.author_id == user.id).all()
    context = {
        'user':user,
        'username': user.username,
        'travel': user.trips,
        'comment': user.comments,
        'zan':zan,
        'cang':cang
    }
    if tag == '1':
        return render_template("user1.html", **context)
    if tag == '2':
        return render_template("user2.html", **context)
    if tag == '3':
        return render_template("user3.html", **context)

运行结果如图:

 

  • 搜索,条件组合搜索
搜索、组合搜索功能的前端
<form action="{{ url_for('search') }}">链接到search函数
<input class="sousuo" id="sousuo" type="text" placeholder="搜索" name="tri">将键入的值命名为tri传递给后端
<button type="submit" ><img src="{{ url_for('static',filename='image/fdj.png') }}" width="15px"></button>
</form>
搜索、组合搜索功能的后端,python文件
@app.route("/search/")
def search():
    t = request.args.get("tri")获取前端要查找的值
    tri = Trip.query.filter(or_(Trip.ttitle.contains(t), Trip.feeling.contains(t))).order_by('-creat_time')在Trip表中查询
    return render_template("first.html",visit = tri)返回并传值给first页面

 运行结果如图:

        

 

  • 个人学期总结

   这个学期,老师带领我们学习了python的flask框架,经过一个学期的学习,我了解到这个框架的强大,这个框架相对于JSP是比较容易上手的。老师带领我们学习了如何使用python搭建Web和信息管理系统的原理,我学到了如何使用python做一个信息管理系统。老师的授课方式是我很喜欢的一种方式,虽然每节课后都有作业,但这能让我们学的更扎实。每次实现功能都能让我拥有巨大的成就感。期末的大作业,我搭建了一个发布旅行感受的系统,这让我将老师所教授的知识都发挥出来。我认为我这个学期学的还不够多,接下来我还会继续学习,继续深造。

 

posted on 2018-01-04 13:00  102林晓霞  阅读(251)  评论(1编辑  收藏  举报