码迷,mamicode.com
首页 > 其他好文 > 详细

期末作品检查

时间:2018-01-07 11:49:50      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:tom   第三方   修改密码   prim   搜索   dex   文章   config   button   

  1. 个人学期总结
  2. 总结Python+Flask+MysqL的web建设技术过程,标准如下:
    1. 即是对自己所学知识的梳理
    2. 也可作为初学入门者的简单教程
    3. 也可作为自己以后复习的向导
    4. 也是一种向外展示能力的途径

一、个人学期总结   

     在这个学期里,我通过学校课程学习了Python+Flask+MysqL的web建设技术。一开始我们学的是简单的基本语法和输出输入,学习了用turtle库绘制出图形,学习了字符串基本操作、凯撒密码、自制九九乘法表、中英文词频统计等等,虽然语句都挺简单的,但也是为了以后开发web做准备。到真正进入web开发时,我们首先安装了pycharm、MySQL和一些python的第三方库,接着首先老师教了我们网页前端的制作,页面的排版分布,设计了简单的布局。第一次知道原来网页原来是div块组成的,而且可以通过class值或id值来设计css样式布置结构,还能编写js代码,设置一些权限,也能让按钮实现更多的功能。虽然感觉学起来并不难,但却很繁琐,比如在布置div块的位置的时候,很多时候是一个值一个值去试的,还有很多属性值要自己再额外去查找,编写过程中也要细心谨慎。随后学习了很多功能的实现,比如登录注册搜索发布。最主要的就是连接mysql,通过前端文本框将数值存入数据库,最后再调用数据库把想要的结果显示出来,这是最难也是最重要的地方,需要自己用心去记一些语法。通过本次web建设技术的课程,我将这一学期所学的web开发基础的知识用到了具体的实践中去,锻炼了动手实践能力和独立思考的能力,收获了喜悦也收获了失落。在这一个学期里,除了课堂上所教的知识,我也在网上搜索了很多资料,完善自己的前端网页,尽量做到完美,但由于水平有限做出来的还是没能像一些网站一样简洁漂亮,今后还会继续努力,做出更好的网页。

配置环境: python3.5,flask2.0,连接数据库时使用了pymysql,所有使用前应该安装pymysql:pip install pymysql

程序结构:

技术分享图片

二、建立mysql和app的连接

在config.py中加入以下两项配置:

import os
SECRET_KEY = os.urandom(24)
SQLALCHEMY_DATABASE_URI = mysql+pymysql://root:@127.0.0.1:3306/test?charset=utf8
SQLALCHEMY_TRACK_MODIFICATTONS = False
 
 在主py文件里加入
import config
app.config.from_object(config)

db = SQLAlchemy(app)
 就可以完成app和数据的关联,并生成一个可以操作app数据库的SQLAlchemy实例db
 
创建数据库表:
class User(db.Model):
    __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(200),nullable=False)
    nickname = db.Column(db.String(20))

    @property
    def password(self):  # 外部使用,取值
        return self._password

    @password.setter
    def password(self, row_password):  # 外部使用,赋值
        self._password = generate_password_hash(row_password)

    def check_password(self, row_password):  # 密码验证
        result = check_password_hash(self._password, row_password)
        return result


class Question(db.Model):
    __tablename__=question
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title =db.Column(db.String(100), nullable=False)
    detail = db.Column(db.Text, nullable=False)
    creat_time=db.Column(db.DateTime,default=datetime.now)
    author_id = db.Column(db.Integer,db.ForeignKey(User.id))
    author=db.relationship(User,backref=db.backref(question))


class Comment(db.Model):
    __tablename__ = comment
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    author_id = db.Column(db.Integer, db.ForeignKey(User.id))
    question_id = db.Column(db.Integer, db.ForeignKey(question.id))
    creat_time = db.Column(db.DateTime, default=datetime.now)
    detail = db.Column(db.Text, nullable=False)
    question = db.relationship(Question, backref=db.backref(comments))
    author = db.relationship(User, backref=db.backref(comments))

 

三、完成基本的页面设计

1.导航,头部,CSS基础

 制作自己的导航条。
HTML头部元素:
<base>  定义了页面链接标签的默认链接地址
<style>  定义了HTML文档的样式文件
<link>  定义了一个文档和外部资源之间的关系
 
<div>
<nav class="bar6">
<ul>
        <li><img src="../static/image/ars.png" width=50px></li>
        <li><img id="on_off" onclick="mySwitch()" src="http://img2.imgtn.bdimg.com/it/u=1878009223,3806655311&fm=200&gp=0.jpg" width="50px"></li>

        <li><a href="{{ url_for(‘base‘) }}" >首页</a></li>
        <li><a href="{{ url_for(‘questions‘) }}">发布问答</a></li>

        {% if username %}
            <li><a href="{{ url_for(‘usercenter‘,user_id=session.get(‘userid‘),tag=3) }}" style="margin-right: -10px;color:deepskyblue">{{ session.get(‘user‘)  }}</a></li>
            <li><a href="{{ url_for(‘logout‘) }}" >注销</a></li>
            <li><a href="{{ url_for(‘change‘) }}" >修改密码</a></li>
        {% else %}
            <li><a href="{{ url_for(‘sign_in‘) }}" >登录</a></li>
            <li><a href="{{ url_for(‘sign_up‘) }}" >注册</a></li>
        {% endif %}
        <form action="{{ url_for(‘search‘) }}" method="get">
            <li><input name =‘q‘ type="text" style="border-radius: 25px;margin-top: 12px" placeholder="请输入您要搜索的关键字...">
            <button type="submit"style="border-radius: 25px;margin-top: 9px"></button></li>
         </form>
        </ul>
</nav>
</div>

结果:

技术分享图片

 

 
2.CSS实例:图片导航块
  1. 认识CSS的 盒子模型。
  2. CSS选择器的灵活使用。
  3. 实例:
    1. 图片文字用div等元素布局形成HTML文件。
    2. 新建相应CSS文件,并link到html文件中。
    3. CSS文件中定义样式
      1. div.img:border,margin,width,float
      2. div.img img:width,height
      3. div.desc:text-align,padding
      4. div.img:hover:border
      5. div.clearfloat:clear
 html:
<div class="container">

        <div class="bar7">

            <ul>
                <li><a href="https://baike.baidu.com/item/ARASHI/4106370?fr=aladdin">
                    <img src="http://p3.so.qhimgs1.com/bdr/_240_/t0109ab8c105af58973.jpg" width="300px"></a>
                   <div class="desc"><a href="{{ url_for(‘base‘) }}"></a>首页</div>
                </li>
                <li><a href="https://baike.baidu.com/item/ARASHI/4106370?fr=aladdin">
                    <img src="http://p0.so.qhimgs1.com/bdr/_240_/t010b57c4173029c22c.jpg"  width="300px" ></a>
                    <div class="desc"><a href="https://baidu.com/">联系我们</a></div></li>
                <li><a href="https://baike.baidu.com/item/ARASHI/4106370?fr=aladdin">
                    <img src="http://p3.so.qhimgs1.com/bdr/_240_/t0109ab8c105af58973.jpg" width="300px"></a>
                   <div class="desc"><a href="https://baidu.com/">联系我们</a></div>
                </li>
                <li><a href="https://baike.baidu.com/item/ARASHI/4106370?fr=aladdin">
                    <img src="http://p0.so.qhimgs1.com/bdr/_240_/t010b57c4173029c22c.jpg"  width="300px" ></a>
                    <div class="desc"><a href="https://baidu.com/">联系我们</a></div>
                </li>
            </ul>

        </div>

css:

.bar7 ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow-x: hidden;
    overflow-y: auto;

}
.bar7 ul li {
    float: left;

}

li a:hover:not(.active) {
    background-color: orange;
}

.col-sm-6 {
    width: 50%;
}
.row {
    margin-right: -15px;
    margin-left: -15px;
}
.container {
    width: 1500px;
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto;
}

img{
    margin:10px;

}
div.desc{
    text-align: center;
    padding:5px;
}
div.img:hover{
    border: 1px solid #777777;
}

结果:

技术分享图片

 

3.完成登录与注册页面的前端

完成登录与注册页面的HTML+CSS+JS,其中的输入项检查包括:

用户名6-12位

首字母不能是数字

只能包含字母和数字

密码6-12位

注册页两次密码是否一致

 
 登录js:
function myLogin() {
    var oUname = document.getElementById("uname");
    var oPass = document.getElementById("upass");
    var oError = document.getElementById("error_box");
    var isError = true;
    oError.innerHTML = "<br>";
    if (oUname.value.length < 6 || oUname.value.length > 20) {
        oError.innerHTML = ‘请输入6-20位的用户名‘;
        isError = false;
        return isError;
    }
    if (oUname.value.charCodeAt(0) >= 48 && oUname.value.charCodeAt(0) <= 57) {
        oError.innerHTML = ‘首字母不能为数字‘;
        return isError;
    } else for (var i = 0; i < oUname.value.length; i++) {
        if ((oUname.value.charCodeAt(i) > 122 || oUname.value.charCodeAt(i) < 97) && (oUname.value.charCodeAt(i) > 57 && oUname.value.charCodeAt(i) < 48)) {
            oError.innerHTML = ‘只能输入字母或数字‘;
            isNotError = false;
            return isError;
        }
    }

    if (oPass.value.length < 6 || oPass.value.length > 20) {
        oError.innerHTML = ‘请输入6-20位的密码‘;
        return isError;

    }
}

注册js:

function myRegist() {
    var oUname=document.getElementById("uname");
    var oPass=document.getElementById("upass");
    var oPas=document.getElementById("upas");
    var oError=document.getElementById("error_box");
    var isError=true;
    oError.innerHTML="<br>";
    if(oUname.value.length< 6||oUname.value.length> 20){
        oError.innerHTML=‘请输入6-20位的用户名‘;
        isError=false;
        return isError;
    }
    else if(oUname.value.charCodeAt(0)>=48&&oUname.value.charCodeAt(0)<=57){
        oError.innerHTML=‘首字母不能为数字‘;
        return isError;
    }
    else for(var i=0;i<oUname.value.length;i++){
        if((oUname.value.charCodeAt(i)>122||oUname.value.charCodeAt(i)<97)&&(oUname.value.charCodeAt(i)>57&&oUname.value.charCodeAt(i)<48)){
            oError.innerHTML=‘只能输入字母或数字‘;
            isError=false;
            return isError;
            }
        }
    if(oPass.value.length<6||oPass.value.length>20){
        oError.innerHTML=‘请输入6-20位的密码‘;
        isError=false;
        return isError;

    }
    if(oPass.value!=oPas.value){
        oError.innerHTML=‘密码不一致‘;
        isError=false;
        return isError;

    }
    window.alert(‘注册成功‘)
    return isError
}

登录html:

    <div class="box">
        <h2>登录</h2>
         <form class="form" method="post" action="{{ url_for(‘sign_in‘) }}">

        <div class="input_box">
            <input id="uname" class="sign" type="text" placeholder="请输入用户名" name="username">
        </div>
        <div class="input_box">
            <input id="upass" class="sign" type="password" placeholder="请输入密码" name="password">
        </div>

        <div id="error_box"><br>
        </div>
        <div class="input_box">
            <input type="submit" name="commit" value="登录" class="sign-in-button" data-disable-with="登录" onclick="return myLogin()">

            </div>
         </form>
        </div>

注册html:

    <div class="box">
        <h2>注册</h2>
        <form action="{{ url_for(‘sign_up‘) }}" method="post">

        <div class="input_box">
            <input id="uname" class="sign" type="text" placeholder="请输入用户名" name="username">
        </div>
         <div class="input_box">
            <input id="unick" class="sign" type="text" placeholder="请输入昵称" name="nickname">
        </div>
        <div class="input_box">
            <input id="upass" class="sign" type="password" placeholder="请输入密码" name="password">
        </div>
        <div class="input_box">
            <input id="upas" class="sign" type="password" placeholder="请再输入一次密码"  name="opassword">
        </div>
        <div id="error_box"><br>
        </div>
        <div class="input_box">
            <input type="submit" name="commit" value="注册" class="sign-in-button" data-disable-with="注册" onclick="return myRegist()">

            </div>
</form>
        </div>

css:

h2{
    text-align: center;
    color:#3194d0;
    font-size: 20px;
}
.sign{
    width: 100%;
    height: 50px;
    margin-bottom: 0;
    vertical-align: middle;
}
.box{
    width: 300px;
    height: 155px;
    margin: 50px auto;
    margin-top:150px ;
}
.sign-in-button{
    width: 100%;
    padding: 9px 18px;
    font-size: 18px;
    border: none;
    border-radius: 25px;
    color: #fff;
    background: #3194d0;
    cursor: pointer;
    outline: none;
    display: block;
    clear: both;
}


.text{
    width: 80px;
    height: 30px;
    margin-bottom: 0;
    vertical-align: middle;
}

 结果:

技术分享图片技术分享图片

 

四、开始flask项目

1.完成注册功能
主py文件中:
  1. from flask import  request, redirect, url_for
  2. @app.route(‘/regist/‘, methods=[‘GET‘, ‘POST’])

def regist():

   if request.method == ‘GET‘:

        return render_template(‘regist.html‘)

   else:

        username = request.form.get(‘username’)#获取form中的数据

        判断用户名是否存在:存在报错

  不存在,存到数据库中

       redirect重定向到登录页

 

@app.route(/sign_up/,methods=[GET,POST])
def sign_up():
    if request.method==GET:
        return render_template(sign_up.html)
    else:
        usern=request.form.get(username)
        nickn= request.form.get(nickname)
        passw = request.form.get(password)
        user=User.query.filter(User.username==usern).first()
        if user:
            return 该用户名已存在
        else:
            user1=User(username=usern,nickname=nickn,password=passw)
            db.session.add(user1)
            db.session.commit()
            return redirect(url_for(sign_in)) 
2.完成登录功能,用session记住用户名
 

主py文件中:

    1. @app.route设置methods
    2. GET
    3. POST
      1. 读取表单数据
      2. 查询数据库
        1. 用户名密码对:
          1. 记住用户名
          2. 跳转到首页
        2. 用户名密码不对:
          1. 提示相应错误。

session:

  1. 从`flask`中导入`session`
  2. 设置`SECRET_KEY`
  3. 操作字典一样操作`session`:增加用户名`session[‘username‘]=`username
 
@app.route(/sign_in/,methods=[GET,POST])
def sign_in():
    if request.method == GET:
        return render_template(sign_in.html)
    else:
        username = request.form.get(username)
        password = request.form.get(password)
        user = User.query.filter(User.username == username).first()
        if user:
            if user.check_password(password):
                session[user]=username
                session[userid]=user.id
                session.permanent = True
                return redirect(url_for(base))
            else:
                return 密码错误
        else:
            return 用户名不存在

 

 
3.登录之后更新导航
 
  1. 用上下文处理器app_context_processor定义函数
    1. 获取session中保存的值
    2. 返回字典
  2. 在父模板中更新导航,插入登录状态判断代码。
    1. 注意用{% ... %}表示指令。
    2. {{ }}表示变量
  3. 完成注销功能。
    1. 清除session
    2. 跳转
 
@app.route(/logout/)
def logout():
    session.clear()
    return redirect(url_for(base))

技术分享图片

 

 
 
 
4.发布功能完成
 
  • 编写要求登录的装饰器

from functools import wraps

def loginFirst(func): #参数是函数

@wraps(func)

      def wrapper(*args, ** kwargs): #定义个函数将其返回

          #要求登录

          return func(*args, ** kwargs)

      return wrapper #返回一个函数

 
  • 应用装饰器,要求在发布前进行登录,登录后可发布。
@app.route(‘/question/‘,methods=[‘GET‘,‘POST‘])
@loginFirst
def question():
  • 建立发布内容的对象关系映射。
class Question(db.Model):
  • 完成发布函数。

保存到数据库。

重定向到首页。

def loginFirst(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        if session.get(user):
            return func(*args,**kwargs)
        else:
            return redirect(url_for(sign_in))
    return wrapper
    <div class="box">
        <h2>发布问答</h2>
        <form action="{{ url_for(‘questions‘) }}" method="post">
        <div class="input_box">
            <label for="question">问题</label>
            <textarea id="question" rows="1" cols="40" name="title"></textarea>
         </div>
        <div class="input_box">
            <label for="issue">详情</label>
                <textarea id="issue" rows="5" cols="40" name="detail" ></textarea>
        </div>
        <div class="input_box">
            <input type="submit" name="commit" value="提交" class="sign-in-button" data-disable-with="提交" onclick="myQuestion()">

            </div>
function myQuestion() {
        var title =document.getElementById("title")
        var detail = document.getElementById("detail")
        var creat_time=document.getElementById("creat_time")
        var author_id =document.getElementById("author_id")
        var author=document.getElementById("author")
        var isError = true;


        if (title.value.length > 100) {
            oError.innerHTML = "问题请输入100位以内字符"
            isError = false;
        }
            return isError;
    }

技术分享图片

5.首页列表显示全部问答,完成问答详情页布局。
1.首页列表显示全部问答:
  1. 将数据库查询结果传递到前端页面 Question.query.all()
  2. 前端页面循环显示整个列表。
  3. 问答排序

     2.完成问答详情页布局:

  1. 包含问答的全部信息
  2. 评论区
  3. 以往评论列表显示区
3.在首页点击问答标题,链接到相应详情页。
 
        {% for foo in questions %}
            <ul class="list">
                <li class="zero"><a href="{{url_for(‘usercenter‘,user_id=foo.author_id,tag=1) }}">{{ foo.author.username }}</a></li><br>
                <li class="one" ><a href="{{ url_for("detail",question_id=foo.id) }}">标题:{{ foo.title }}</a></li>
                <li class="one" >详情:{{ foo.detail }}</li>
                <br>
                <li>发布时间:{{ foo.creat_time }}</li>
                <br>
            </ul>

          {% endfor %}
 
@app.route(/question/,methods=[GET,POST])
@loginFirst
def questions():
    if request.method==GET:
        return render_template(questions.html)
    else:
        title=request.form.get(title)
        detail=request.form.get(detail)
        author_id=User.query.filter(User.username==session.get(user)).first().id
        question=Question(title=title,detail=detail,author_id=author_id)
        user = User.query.filter(User.username == session.get(user)).first()
        question.author = user
        db.session.add(question)#保存到数据库
        db.session.commit()#提交
    return redirect(url_for(base))

 

技术分享图片

 

7.从首页问答标题到问答详情页
1.主PY文件写视图函数,带id参数。
2.首页标题的标签做带参数的链接。
      {{ url_for(‘detail‘,question_id = foo.id) }}
 

3.在详情页将数据的显示在恰当的位置。 

 

4.建立评论的对象关系映射:

class Comment(db.Model):
    __tablename__=‘comment‘

@app.route(/detail/<question_id>)
def detail(question_id):
    quest=Question.query.filter(Question.id==question_id).first()
    return render_template(detail.html,ques=quest)
    <ul class="list">
    <div class="page-header">
        <h3>{{ ques.title }}<br></h3>
        <small>{{ ques.author.username }}</small>
    </div>
        <p class="answer" style="text-indent: 18px">{{ ques.detail }}</p>
        <hr>
        <form action="{{ url_for(‘comment‘) }}" method="post">
        <span class="badge">{{ ques.creat_time }}</span>
        <div>
            <textarea name="new_comment" class="form-control" rows="3" id="new-comment" placeholder="我也说一句..."></textarea>
            <input name="question_id" type="hidden"   value="{{ ques.id }}" >
        </div>
        <button type="submit" class="btn btn-default">发送</button>
        <h4>评论:({{ ques.comments|length }})</h4><br>
        <ul>
            {% for ques in ques.comments %}
            <li>
                <a href="{{ url_for(‘usercenter‘,user_id=ques.author_id,tag=3) }}">{{ ques.author.username }}</a>
                <span class="badge">{{ ques.creat_time }}</span><br>
                <p>评论:{{ ques.detail }}</p>
            </li>
            {% endfor %}
         </ul>
 技术分享图片
8.完成评论功能
 

1.定义评论的视图函数
@app.route(‘/comment/‘,methods=[‘POST‘])
def comment():
读取前端页面数据,保存到数据库中

技术分享图片
@app.route(‘/comment/‘, methods=[‘POST‘])
def comment():
    comment_detail = request.form.get(‘new_comment‘)
    quest_id = request.form.get(‘question_id‘)
    author_id = User.query.filter(User.username == session.get(‘user‘)).first().id
    comment = Comment(detail=comment_detail, author_id=author_id, question_id=quest_id, )
    db.session.add(comment)
    db.session.commit()
    return redirect(url_for(‘detail‘, question_id=quest_id))
技术分享图片

 

2.用<input type="hidden" 方法获取前端的"question_id" 

<input name="question_id" type="hidden" value="{{ ques.id }}">

 

3.显示评论次数

 <span class="tcomment">评论:({{ ques.comments|length }})</span>

 

4.要求评论前登录

@app.route(‘/comment/‘, methods=[‘POST‘])
@loginFirst
def comment():

 

5.尝试实现详情页面下的评论列表显示

技术分享图片
<ul class="list-group">
       {% for com in comment %}
         <li ><a href="#">{{ com.author.username }}</a>
                      <br>
         <span >{{ com.create_time }}</span>
         <p class="abstract">{{ com.detail }}</p>
                      </li>
        {% endfor %}
                  </ul>
 
 
9.评论列表显示及排序,个人中心显示
 

1.显示所有评论
{% for foo in ques.comments %}

技术分享图片
            <ul class="list-group">
             {% for foo in question %}
                  <li class="list-group-item">
                    <span class="glyphicon-leaf" aria-hidden="true"></span>
                  <img id="qu" src="{{ url_for(‘static‘,filename=‘images/title.png‘)}}">
                    <a href = "#">{{ foo.author.username }}{{ foo.title }}</a>
                           <span class="badge">{{ foo.create_time }}</span>
            </li>
                {% endfor %}
            </ul>
技术分享图片

 

2.所有评论排序
uquestion = db.relationship(‘Question‘, backref=db.backref(‘comments‘, order_by=creat_time.desc))

 ‘comments‘: Comment.query.order_by(‘create_time‘).all()

 

3.显示评论条数
{{ ques.comments|length }}

<span class="tcomment">评论:({{ ques.comments|length }})</span>

 

4.完成个人中心

1.个人中心的页面布局(html文件及相应的样式文件)

2.定义视图函数def usercenter(user_id):

3.向前端页面传递参数

4.页面显示相应数据

发布的全部问答

发布的全部评论

个人信息

技术分享图片
{% extends ‘index.html‘ %}
{% block title %}usercenter {% endblock%}
{% block main%}

<div class="page-header">
    <h3><span class="glyphicon glyphicon-user" aria-hidden="true"></span>
    {{username}} <br> <small>全部问答><span class="badge"></span> </small></h3>
    <ul class="list-group" style="">
        {% for foo in question %}
            <li class="list-group-item">
                <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>
                <a href="#">{{foo.author.username }}</a>
                <span class="badge">{{foo.creat_time}}</span>
                <p style="">{{foo.detail}}</p>
            </li>
    {% endfor %}
    </ul>
</div>

<div class="page-header">
     <h3><span class="glyphicon glyphicon-user" aria-hidden="true"></span>
    {{user}} <br> <small>个人信息><span class="badge"></span> </small></h3>
    <ul class="list-group" style="">
          {% for foo in comments %}
            <li class="list-group-item">
                <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>
                <a href="#">{{foo.author.username }}</a>
                <span class="badge">{{foo.creat_time}}</span>
                <p style="">{{foo.detail}}</p>
            </li>
    {% endfor %}
    </ul>
</div>

<div class="page-header">
     <h3><span class="glyphicon glyphicon-user" aria-hidden="true"></span>
    {{user}} <br> <small>个人信息><span class="badge"></span> </small></h3>
      <ul class="list-group" style="">
          <li class="list-group-item">用户:{{username}}</li>
          <li class="list-group-item">编号:</li>
          <li class="list-group-item">昵称:</li>
          <li class="list-group-item">文章篇:</li>
      </ul>
</div>

{% endblock %}
技术分享图片

 

5.各个页面链接到个人中心

 <a href = "{{ url_for (‘userCenter‘,user_id=each.author.id) }}">{{ foo.author.username }}{{ foo.title }}</a>
 技术分享图片

 

10.个人中心标签页导航

1.新页面userbase.html,用<ul ><li role="presentation"> 实现标签页导航。
<ul class="nav nav-tabs">
  <li role="presentation"><a href="#">Home</a></li>
  <li role="presentation"><a href="#">Profile</a></li>
  <li role="presentation"><a href="#">Messages</a></li>
</ul>

 

2.让userbase.html继承base.html。
重写title,head,main块.
将上述<ul>的样式放在head块,<ul>放在main块中.
定义新的块user。

技术分享图片
{% extends "index.html" %}
{% block usertitle %}个人中心{% endblock %}
{% block userhead %}
    <style>
        .nav_ul li{
            list-style: none;
            float: left;
            margin: 10px;
            margin-top: 5cm;
        }
    </style>
{% endblock %}

{% block mywebbody %}
<ul class="nav_ul">
    <li role="presentation"><a href="#">questions</a> </li>
    <li role="presentation"><a href="#">comments</a> </li>
    <li role="presentation"><a href="#">information</a> </li>
</ul>

{% block usercenterbody %}{% endblock %}

{% endblock %}

</html>
技术分享图片

 

3.让上次作业完成的个人中心页面,继承userbase.html,原个人中心就自动有了标签页导航。

4.制作个人中心的三个子页面,重写userbase.html中定义的user块,分别用于显示问答、评论、个人信息。

技术分享图片
{% extends ‘userbase.html‘ %}

{% block user %}
<div class="page-header">
    <h3><span class="glyphicon glyphicon-user" aria-hidden="true"></span>
    {{username}} <br> <small>全部问答><span class="badge"></span> </small></h3>
    <ul class="list-group" style="">
        {% for foo in question %}
            <li class="list-group-item">
                <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>
                <a href="#">{{foo.author.username }}</a>
                <span class="badge">{{foo.creat_time}}</span>
                <p style="">{{foo.detail}}</p>
            </li>
    {% endfor %}
    </ul>
</div>

{% endblock %}
技术分享图片
技术分享图片
{% extends ‘userbase.html‘ %}

{% block user %}
    <div class="page-header">
        <h3><span class="glyphicon glyphicon-user" aria-hidden="true"></span>{{ user }}<br><small>全部评论<span class="badge>"></span> </small> </h3>
        <ul class="list-group"style="margin:10px">
            {% for foo in comments %}
                <li class="list-group-item">
                    <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>
                    <a href="#">{{ foo.author.username }}</a>
                    <span class="badge">{{ foo.creat_time }}</span>
                    <p style="align-content: center">{{ foo.detail }}</p>
                </li>
            {% endfor %}
        </ul>

    </div>

{% endblock %}
技术分享图片
技术分享图片
{% extends ‘userbase.html‘ %}

{% block user %}
    <div class="page-header">
        <h3><span class="glyphicon glyphicon-user" aria-hidden="true"></span>{{ user }}<br><small>个人信息<span class="badge>"></span> </small> </h3>
        <ul class="list-group"style="margin:10px">
            <li class="list-group-item">用户:{{ username }}</li>
            <li class="list-group-item">编号:</li>
            <li class="list-group-item">昵称:</li>
        </ul>
    </div>

{% endblock %}
 
 
 
11.完成个人中心—导航标签

1.个人中心—视图函数带标签页面参数tag

@app.route(‘/usercenter/<user_id>/<tag>‘)
def usercenter(user_id, tag):
   if tag == ‘1‘:
       return render_template(‘usercenter1.html‘, **context)

技术分享图片
@app.route(‘/usercenter/<user_id>/<tag>‘)
@loginFirst
def usercenter(user_id,tag):
    user=User.query.filter(User.id==user_id).first()
    context={
        ‘user‘:user,
        ‘question‘:user.question,
        ‘comments‘:user.comments
    }
    if tag == ‘1‘:
        return render_template(‘user_com.html‘, **context)
    elif tag == ‘2‘:
        return render_template(‘user_ques.html‘, **context)
    else:
        return render_template(‘user_info.html‘, **context)
技术分享图片

 

2.个人中心—导航标签链接增加tag参数
<li role=“presentation”><a href=“{{ url_for(‘usercenter’,user_id = user.id,tag = ‘1’) }}">全部问答</a></li>

 

技术分享图片
{% extends "index.html" %}
{% block title %}usercenter {% endblock %}
{% block head %}
    <style>
        .nav_ul li{
            list-style: none;
            float: left;
            margin: 25px;
        }

    </style>
{% endblock %}

{% block main %}
    <h3><span class="glyphicon glyphicon-user" aria-hidden="true"></span>{{ user.username }}</h3>
    <ul class="nav_ul">
    <li role="presentation"><a href="{{ url_for(‘usercenter‘,user_id=user.id,tag=1) }}">全部问答</a></li>
    <li role="presentation"><a href="{{ url_for(‘usercenter‘,user_id=user.id,tag=2) }}">全部评论</a></li>
    <li role="presentation"><a href="{{ url_for(‘usercenter‘,user_id=user.id,tag=3) }}">个人信息</a></li>
    </ul>

    {% block user %}{% endblock %}

{% endblock %}
技术分享图片

 

3.个人中心—有链接到个人中心页面的url增加tag参数

 <a href="{{ url_for(‘usercenter‘,user_id = session.get(‘userid‘), tag=1) }}">{{ session.get(‘user‘) }}</a>

 

base.html:

<a href="{{ url_for(‘usercenter‘,user_id=foo.author_id,tag=3) }}">{{ foo.author.username }}</a></li><br>

index.html:

<a href="{{ url_for(‘usercenter‘,user_id=session.get(‘userid‘),tag=3) }}" style="margin-right: -10px;color:deepskyblue">{{ session.get(‘user‘)  }}</a>

detail.html:

<a href="{{ url_for(‘usercenter‘,user_id=ques.author_id,tag=3) }}">{{ ques.author.username }}</a>

 技术分享图片

 

 
12.密码保护
 

1.更新User对象,设置对内的_password

class User(db.Model):

    __tablename__ = ‘user‘ 

    _password = db.Column(db.String(200), nullable=False) #内部使用

 

class User(db.Model):
    __tablename__ = ‘User‘
    _password = db.Column(db.String(200),nullable=False)

 

2.编写对外的password

from werkzeug.security import generate_password_hash, check_password_hash

    @property

    def password(self):  #外部使用,取值

        return self._password

    @password.setter

    def password(self, row_password):#外部使用,赋值

        self._password = generate_password_hash(row_password)

 

技术分享图片
    @property
    def password(self):  #外部使用,取值
        return self._password

    @password.setter
    def password(self, row_password):#外部使用,赋值
        self._password = generate_password_hash(row_password)
技术分享图片

 

3.密码验证的方法:

    def check_password(self, row_password): #密码验证

        result = check_password_hash(self._password,row_password)

        return result

 

def check_password(self, row_password): #密码验证
    result = check_password_hash(self._password,row_password)
    return result

 

4.登录验证:

        password1 = request.form.get(‘password‘)

        user = User.query.filter(User.username == username).first()

        if user:

            if user.check_password(password1):

 

技术分享图片
def sign_in():
    if request.method == ‘GET‘:
        return render_template(‘sign_in.html‘)
    else:
        username = request.form.get(‘username‘)
        password1 = request.form.get(‘password‘)
        user = User.query.filter(User.username == username).first()
        if user:
            if user.check_password(password1):
                session[‘user‘]=username
                session[‘userid‘]=user.id
                session.permanent = True
                return redirect(url_for(‘base‘))
            else:
                return ‘密码错误‘
        else:
            return ‘用户名不存在‘
技术分享图片

 技术分享图片

 

 
13.实现搜索功能

 

1.准备视图函数search()

@app.route(‘/search/‘)
def search():

 

2.修改base.html 中搜索输入框所在的

     a.<form action="{{ url_for(‘search‘) }}" method="get">

     b. <input name="q" type="text" placeholder="请输入关键字">

        <form action="{{ url_for(‘search‘) }}" method="get">
            <li><input name =‘q‘ type="text"  placeholder="请输入您要搜索的关键字...">
            <button type="submit"></button></li>
         </form>

 

3.完成视图函数search()

    a.获取搜索关键字
       q = request.args.get(‘q’)

    b.条件查询
       qu = Question.query.filter(Question.title.contains(q)).order_by(‘-creat_time’)

    c.加载查询结果:
       return render_template(‘index.html‘, question=qu)

@app.route(‘/search/‘)
def search():
    qu=request.args.get(‘q‘)
    ques = Question.query.filter(Question.title.contains(qu)).order_by(‘-creat_time‘)
    return render_template("base.html",questions=ques)

 

4.组合条件查询

    from sqlalchemy import or_, and_ 

ques = Question.query.filter(or_(Question.title.contains(qu), Question.detail.contains(qu))).order_by(‘-creat_time‘)
 
 
 
 
 
 

期末作品检查

标签:tom   第三方   修改密码   prim   搜索   dex   文章   config   button   

原文地址:https://www.cnblogs.com/arashinoj/p/8176349.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!