期末作品检查

1.个人学期总结

Python作为近几年流行起来的语言, 是一种不受局限、跨平台的开源编程语言,它功能强大且简单易学。因而得到了广泛应用和支持。 Python作为动态语言更适合初学编程者。Python可以让初学者把精力集中在编程对象和思维方法上,而不用去担心语法、类型等等外在因素。Python的库很庞大。它可以帮助处理各种工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其他与系统有关的操作。这被称作Python的“功能齐全”理念。除了标准库以外,还有许多其他高质量的库,如wxPython、Twisted和Python图像库等等。

第一次接触python,我们首先学的是简单的输出输入计算,到引入 turtle库,绘制多种多样的图形,接着学习了字符串基本操作,进行了中英文词频统计,直到最后我们学习了Python+Flask+MysqL的web建设,做出了自己的网页。通过本学对python基础知识的学习,发现其实python语言比起其他语言的学习要好入手很多。比如python有很库、获取数据方便、数据运算方便、表达的语句简而易懂、与其他语言交互很方便、信息处理也很方便。总的来说,python语言非常简单,阅读一个良好的Python程序就感觉像是在读英语一样,尽管这个对英语的要求非常严格!Python的这种伪代码本质是它最大的优点之一。它使你能够专注于解决问题而不是去搞明白语言本身。在当今的大数据时代,更是需要这种易懂、方便学习的编程语言来处理大数据和得出最优的结论出来。但是python也有缺点,很多时候不能将程序连写成一行,如import sys;for i in sys.path:print i。而perl和awk就无此限制,可以较为方便的在shell下完成简单程序,不需要如Python一样,必须将程序写入一个主.py文件。既是优点也是缺点,python的开源性是的Python语言不能加密。总体来说,python语言还算是比较优秀的,吸引的人才多,项目也多。

2.总结Python+Flask+MysqL的web建设技术过程

下面以简单的页面设计为例简单介绍Python+Flask+MysqL的web建设技术过程

一、首先,创建并连接数据库,代码如下:

import os
DEBUG = True
SECRET_KEY = os.urandom(24)

SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:@localhost:3306/xingzuo?charset=utf8'
SQLALCHEMY_TRACK_MODIFICATTONS = False

在数据库中创建所需要的表:

class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(100), nullable=False)
    _password = db.Column(db.String(500), nullable=False)#内部使用

    @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)
    create_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'))
    create_time = db.Column(db.DateTime, default=datetime.now)
    detail = db.Column(db.Text, nullable=False)
    question = db.relationship('Question',backref=db.backref('comments',order_by=create_time.desc))
    author = db.relationship('User',backref=db.backref('comments'))

db.create_all()

创建得到的数据库表如下:

二、建一个父模板,其中导航条如下:

 

<nav class="navbar navbar-default" role="navigation">
    <div class="container-fluid">
        <div class="navbar-header">
                <a class="navbar-brand" style="color: cornflowerblue;font-weight: bold;font-size: 30px;font-family: 华文行楷;">星座屋</a>

                <a class="navbar-brand" href="{{ url_for('shouye') }}"style="color: purple;background-color: white;font-size: 25px;margin-top:10px">首页</a>
                <a class="navbar-brand" href="{{ url_for('wenda') }}"style="color: rebeccapurple;background-color: white;font-size: 20px;margin-top:10px">星座问答区</a></div>


                <form action="{{ url_for('search') }}" class="navbar-form navbar-left" role="search"method="get">
                <div class="form-group"><input type="text" name="q" class="form-control" placeholder="输入您感兴趣的"><button type="submit" class="btn btn-default" style="width: 70px">查询</button></div>
            </form>

 <ul class="nav navbar-nav navbar-right">
            {% if username %}
        <li><a href="{{  url_for('usercenter',user_id = session.get('id'),tag=3)}}" style="background-color: white">{{ session.get('user') }}</a></li>
             <li><a href="{{url_for('logout') }}" style="background-color: white"><span class="glyphicon glyphicon-user"></span> 注销</a></li>
            <li><a href="{{  url_for('usercenter',user_id = session.get('id'),tag=3)}}" style="background-color: white"><span class="glyphicon glyphicon-log-in"></span> {{username }}</a></li>
            {% else %}
            <li><a href="{{ url_for('zhuce') }}" style="background-color: white"><span class="glyphicon glyphicon-user"></span> 注册</a></li>
            <li><a href="{{ url_for('denglu') }}" style="background-color: white"><span class="glyphicon glyphicon-log-in"></span> 登录</a></li>
            {% endif %}

        </ul>

        </div>
    </nav>

三、图片导航

可在页面中加入一些图片导航进行美化和补充,可在图片中添加外部链接,中间的图片导航代码如下:

 

<ul>
<div>
  <div class="img">
       <a href="https://baike.baidu.com/item/白羊座/23547?fr=aladdin">
           <img src="https://static.meiguoshenpo.com/image/201412/30091426359.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/白羊座/23547?fr=aladdin">白羊座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/金牛座/23548?fr=aladdin">
           <img src="https://static.meiguoshenpo.com/image/201412/30091749406.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/金牛座/23548?fr=aladdin">金牛座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/双子座/23549?fr=aladdin">
           <img src="http://static.meiguoshenpo.com/image/201411/19135844406.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/双子座/23549?fr=aladdin">双子座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/巨蟹座/2490814?fr=aladdin">
           <img src="http://static.meiguoshenpo.com/image/201411/19135552250.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/巨蟹座/2490814?fr=aladdin">巨蟹座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/狮子座/8162?fr=aladdin">
           <img src="http://static.meiguoshenpo.com/image/201411/19135128578.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/狮子座/8162?fr=aladdin">狮子座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/室女座/3268873?fr=aladdin&fromid=31025&fromtitle=处女座">
           <img src="https://static.meiguoshenpo.com/image/201412/30093428609.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/室女座/3268873?fr=aladdin&fromid=31025&fromtitle=处女座">处女座</a></div>
  </div>

    <div class="img">
       <a href="https://baike.baidu.com/item/天秤座/2609891">
           <img src="https://static.meiguoshenpo.com/image/201412/30093731000.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/天秤座/2609891">天秤座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/天蝎座/2543199">
           <img src="http://static.meiguoshenpo.com/image/201412/30094107125.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/天蝎座/2543199">天蝎座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/射手座/126373">
           <img src="https://static.meiguoshenpo.com/image/201412/30094719515.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/射手座/126373">射手座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/摩羯座/2546779">
           <img src="https://static.meiguoshenpo.com/image/201412/30095016421.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/摩羯座/2546779">摩羯座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/水瓶座/128102">
           <img src="https://static.meiguoshenpo.com/image/201412/30095405703.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/水瓶座/128102">水瓶座</a></div>
  </div>
    <div class="img">
       <a href="https://baike.baidu.com/item/双鱼座/23550">
           <img src="https://static.meiguoshenpo.com/image/201412/30095742312.png">
       </a>
      <div class="d"><a href="https://baike.baidu.com/item/双鱼座/23550">双鱼座</a></div>
  </div>
     </div>
</ul>

四、注册功能:

 

  1. js文件: onclick函数return True时才提交表单,return False时不提交表单。
  2. html文件:
    1. <form>中设置 action和method="post"
    2. <input> 中设置 name
  3. 主py文件中:
    1. from flask import  request, redirect, url_for
    2. @app.route('/regist/', methods=['GET', 'POST’])

 

{% extends 'base.html' %}
{% block title %}
    注册
{% endblock %}

{% block main %}
    <link href="../static/css/hh.css" rel="stylesheet" type="text/css">
    <script src="../static/js/zc.js"></script>
    <div><h1>注册</h1></div><br><br><br>
    <form action="{{ url_for('zhuce') }}" method="post">
        <div class="box">

            <p class="input_box">
                账户: <input id="uname" type="text" placeholder="请输入您的昵称" name="username">
            </p>
            <p class="input_box">
                密码: <input id="upass" type="password" placeholder="请设置您的密码" name="password">
            </p>
            <p class="input_box">
                验证: <input id="upass1" type="password" placeholder="请再次输入密码" name="password">
            </p>


            <div id="error_box"><br></div>
            <div class="input_button">
                <button type="submit" onclick="return fozhuce()">立即注册</button>
            </div>

        </div>
    </form>
{% endblock %}
function fozhuce() {
            var oUname = document.getElementById("uname");
            var oError = document.getElementById("error_box");
            var oUpass = document.getElementById("upass");
            var oUpass1 = document.getElementById("upass1");
            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="首位不能为数字";
                isError = false;
                return isError;
            }else for (var i=0;i<oUname.value.length;i++){
               if((oUname.value.charCodeAt(i)<48)||(oUname.value.charCodeAt(i)>57)&&(oUname.value.charCodeAt(i)<58)&&(oUname.value.charCodeAt(i)>97)){
                oError.innerHTML="只能为数字和字母";
                isError = false;
                return isError;
               }
            }if (oUpass.value.length < 6 || oUpass.value.length > 20) {
                oError.innerHTML = "密码要6-20位";
                isError = false;
                return isError;
            }else if(oUpass.value!=oUpass1.value) {
                oError.innerHTML = "设置密码和验证密码不一致";
                isError = false;
                return isError;
            }
            return ture;
            }

五、登录功能:

 

{% extends 'base.html' %}
{% block title %}
登录
{% endblock %}
{% block main %}
    <link rel="stylesheet" type="text/css" href="../static/css/hh.css">
    <script src="../static/js/dl.js"></script>

  <div><h1>登录</h1></div>
<br><br><br>
<body><div class="box">
   <form action="{{ url_for('denglu') }}" method="post">
    <p class="input_box">
        账户: <input id="uname" type="text" placeholder="请输入您的用户名"name="username">
    </p>
    <p class="input_box">
        密码: <input id="upass" type="password" placeholder="请输入您的密码" name="password">
    </p>

    <div id="error_box"><br></div>
        <div class="input_box">
            <button onclick="return fnLogin()">登录</button>


</div>
   </form>
{% endblock %}
</body>
function foLogin() {
            var oUname = document.getElementById("uname");
            var oError = document.getElementById("error_box");
            var oUpass = document.getElementById("upass");

            var isError = true;
            oError.innerHTML = "<br>";

            if (oUname.value.length < 6 || oUname.value.length > 12) {
                oError.innerHTML = "用户名要6-12位";
                isError = false;
                return;
            }else if(oUname.value.charCodeAt(0)>=48 &&(oUname.value.charCodeAt(0)<=57)){
                oError.innerHTML="首位不能为数字";
                isError = false;
                return isError;

            }else for (var i=0;i<oUname.value.length;i++){
               if((oUname.value.charCodeAt(i)<48)||(oUname.value.charCodeAt(i)>57)&&(oUname.value.charCodeAt(i)<58)&&(oUname.value.charCodeAt(i)>97)){
                oError.innerHTML="只能为数字和字母";
                isError = false;
                return isError;
            }
            }
            if (oUpass.value.length < 6 || oUpass.value.length > 12) {
                oError.innerHTML = "密码要6-20位";
                isError = false;
                isError = false;
                return isError;
             }
            return ture;
            }

py:

  1.@app.route设置methods

  2.GET

  3.POST

    1.读取表单数据

    2.查询数据库

      1.用户名密码对:

        1.记住用户名

        2.跳转到首页

      1.用户名密码不对:

        1.提示相应错误。

 

def zhuce():
    if request.method == 'GET':
        return render_template('zc.html')
    else:
        username = request.form.get('username')  # 获取form中的数据
        password = request.form.get('password')  # 获取form中的数据
        # email = request.form.get('email')  # 获取form中的数据
        user = User.query.filter(User.username ==username).first()
        if user:
            return'用户已存在'
        else:
            user = User(username = username,password=password)
            db.session.add(user)
            db.session.commit()
            return redirect(url_for('denglu'))

@app.route('/denglu/', methods=['GET', 'POST'])
def denglu():
    if request.method == 'GET':
        return render_template('dl.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['id'] = user.id
                session.permanent = True
                return redirect(url_for('shouye'))
            else:
                return '密码错误'
        else:
            return '此用户不存在'

 

六、 登录后更新导航:

 用上下文处理器app_context_processor定义函数

  1. 获取session中保存的值
  2. 返回字典

 

app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app
@app.context_processor
def mycontext():
    usern=session.get('user')
    if usern:
        return {'username':usern}
    else:
        return{}

3.完成注销功能。

   1.清除session

    2.跳转

 

@app.route('/logout/')
def logout():
    session.clear();
    return redirect(url_for('shouye'))

七、发布功能

1.编写要求登录的装饰器

from functools import wraps

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

@wraps(func)

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

          #要求登录

          return func(*args, ** kwargs)

      return wrapper #返回一个函数

2.应用装饰器,要求在发布前进行登录,登录后可发布。

@app.route('/question/',methods=['GET','POST'])
@loginFirst
def question():

3.建立发布内容的对象关系映射。

class Question(db.Model):

4.完成发布函数。

保存到数据库。

重定向到首页

 八、在首页显示问答列表

 

1. 在首页添加显示问答的列表,并定义好相应的样式。

无序列表

<ul >

  <li>Coffee</li>

  <li>Tea</li>

  <li>Milk</li>

</ul>

 

2. 用字典向index.html传递参数。

  1. 首页列表显示全部问答:
    1. 将数据库查询结果传递到前端页面 Question.query.all()
    2. 前端页面循环显示整个列表。
    3. 问答排序
  2. 完成问答详情页布局:
    1. 包含问答的全部信息
    2. 评论区
    3. 以往评论列表显示区。
  3. 在首页点击问答标题,链接到相应详情页。

 九、从首页问答列表标题链接到问题详情页

    1. 主PY文件写视图函数,带id参数。 
      @app.route('/detail/<question_id>')
      def detail(question_id):
          quest = 
          return render_template('detail.html', ques = quest) 
    2. 首页标题的标签做带参数的链接。
            {{ url_for('detail',question_id = foo.id) }}

    3. 在详情页将数据的显示在恰当的位置。 
      {{ ques.title}}
      {{ ques.id  }}{{  ques.creat_time }}
      {{ ques.author.username }} 
      {{ ques.detail }}
    4. 建立评论的对象关系映射:

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

 十、发布评论

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

@app.route('/comment/', methods=['POST'])
@log
def comment():
    comment=request.form.get('new_comment')
    ques_id=request.form.get('question_id')
    auth_id=User.query.filter(User.username==session.get('user')).first().id
    comm=Comment(author_id=auth_id,question_id=ques_id,detail=comment)
    db.session.add(comm)
    db.session.commit()
    return redirect(url_for('detail',question_id=ques_id))

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

3.显示评论次数

4.要求评论前登录

{% extends 'base.html' %}
{% block title %}
    问答详情
{% endblock %}
{% block main %}
    <link rel="stylesheet" type="text/css" href="../static/css/detail.css">
    <div class="box">

        <h3 href="#" style="color: black">问题标题:{{ ques.title }}</h3>
    {% for foo in ques.comments %}
        <a style="color: black;background-color: beige" href="{{  url_for('usercenter',user_id = foo.author.id,tag='1') }}">发布者: {{ ques.author.username }}<a><span class="badge" style="margin-left: 75%">发布时间{{ ques.create_time }}</span>
        {% endfor %}

        <hr>
        <p style="font-size: 18px;color: black;">问题详情:{{ ques.detail }}</p>
        <hr>
        <form action="{{ url_for('comment') }}" method="post">
            <div><textarea class="form-control" id="comment" rows="3" style="margin-left: 1%" name="new_comment" placeholder="写下你的评论吧"></textarea><br></div>
            <input type="hidden" name="question_id" value="{{ ques.id }}">
            <button type="submit" style="color: black">发送</button>
        </form>
      <h4 style="color: black">评论:({{ ques.comments|length }})</h4>
         <ul class="list-unstyled">
            {% for foo in ques.comments %}
                 <li class="list-group-item">
                    <a href="{{  url_for('usercenter',user_id = foo.author.id,tag='1') }}">{{ foo.author.username }}</a>
                    <span class="badge pull-right">{{ foo.create_time }}</span>
                    <p>{{ foo.detail }}</p>
                    <br>
                </li>
            {% endfor %}
        </ul>

    </div>
{% endblock %}

十一、个人中心

    1. 个人中心—视图函数带标签页面参数tag
    2. @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>')
@log
def usercenter(user_id,tag):

    user = User.query.filter(User.id == user_id).first()
    context = {
        'user': user,
        'questions': user.question,
        'comments': user.comments
    }
    if tag == '1':
        return render_template('user1.html', **context)
    elif tag == '2':
        return render_template('user2.html', **context)
    else:
        return render_template('user3.html', **context)

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

 

    <li><a href="{{ url_for('usercenter',user_id=user.id,tag = 1) }}" >全部问答</a></li>
    <li><a href="{{ url_for('usercenter',user_id=user.id,tag = 2) }}" >全部评论</a></li>
    <li><a href="{{ url_for('usercenter',user_id=user.id,tag = 3) }}">个人信息</a></li>

4.个人中心—有链接到个人中心页面的url增加tag参数
 <a href="{{ url_for('usercenter',user_id = session.get('userid'), tag=1) }}">{{ session.get('user') }}</a>

十二、搜索功能

 

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

  1. <form action="{{ url_for('search') }}" method="get">
  2.    <input name="q" type="text" placeholder="请输入关键字">

2.完成视图函数search()

      1. 获取搜索关键字
        q = request.args.get('q’)
      2. 条件查询
        qu = Question.query.filter(Question.title.contains(q)).order_by('-creat_time’)
      3. 加载查询结果:
        return render_template('index.html', question=qu)
@app.route('/search/')
def search():
    qu = request.args.get('q')
    ques = Question.query.filter(
        or_(
            Question.title.contains(qu),
            Question.detail.contains(qu)
        )
    ).order_by('')

    return render_template('hh.html',questions=ques)

十三、密码保护

 设置密码保护后,用户注册时输入的密码在存入数据库时转为编译后的密码,在外部从数据库看到的密码是编译后的

 

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

class User(db.Model):

    __tablename__ = 'user' 

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

class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(100), nullable=False)
    _password = db.Column(db.String(500), 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):

@app.route('/denglu/', methods=['GET', 'POST'])
def denglu():
    if request.method == 'GET':
        return render_template('dl.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['id'] = user.id
                session.permanent = True
                return redirect(url_for('shouye'))
            else:
                return '密码错误'
        else:
            return '此用户不存在'

 

posted on 2018-01-06 15:25  097吴嘉玲  阅读(161)  评论(0)    收藏  举报

导航