期末作品检查

 

    1. 期末作品检查:基本要求
      1. 检查时间:18最后四节课,上课之前必须全部完成,上课做基本部署就开始检查
      2. 方式:逐个运行演示,抽查代码
      3. 主题:选一个主题,整个网站风格统一,布局合理,尽量美观。

    2. 期末作品检查:必须完成:
      1. 网站父模板统一布局:头部导航条、底部图片导航、中间主显示区域布局
      2. 注册、登录、注销
      3. 发布、列表显示
      4. 详情页
      5. 评论、列表显示
      6. 个人中心
      7. 搜索,条件组合搜索
      8. 一篇完整的博客
        1. 个人学期总结
        2. 总结Python+Flask+MysqL的web建设技术过程,标准如下:
          1. 即是对自己所学知识的梳理
          2. 也可作为初学入门者的简单教程
          3. 也可作为自己以后复习的向导
          4. 也是一种向外展示能力的途径

    3. 期末作品检查:加分功能
      1. 文章分类、显示
      2. 点赞、收藏
      3. 修改密码、头像、上传头像
      4. 我的
      5. 高级搜索

 

 

 

  1. 个人学期总结

 经过一个学期的学习,在老师的教导之下,从一个连网页制作都不会的菜鸟,变成会用Python+Flask+MysqL的web建设技术来制作网页。

一开始是学习简单输入输出交互,算并输出两个数字之和,输入半径,计算圆的面积。到画圆,太阳花,同心圆画五角星,字符串基础操作,恺撒密码的编码,打出99乘法表,英文词频统计,用文件方式实现完整的英文词频统计,中文词频统计,datetime处理日期和时间,timestamp与timedelta,这些都是比较简单的,比较容易上手,逐渐的,web的基础,用html元素制作web网页,导航,css基础,图片导航块,到登录,登录和注册页面的前端验证再到连接myssql数据库,创建用户模型,对数据库进行增删改查操作,完成注册功能,登录后更新导航,发布功能,制作首页的显示列表,显示全部问答,完成问答详情页的布局,点击问答标题时跳转到相应的详情页,评论功能的实现,个人中心的显示,个人中心标签导航,搜索功能的实现,密码的保护等等。在学习的过程中发现了很多乐趣。

 

Python+Flask+MysqL的web建设技术过程

 主py文件:

from functools import wraps
from flask import Flask, render_template, url_for, redirect, request, session
import config
from sqlalchemy import or_,and_
from exts import db
from models import User,Question,Comment



app = Flask(__name__)
app.config.from_object(config)
db.init_app(app)


# db.create_all()


# 增加
# user = User(username='tan1997',password='19961021')
# db.session.add(user)
# db.session.commit()

# 查询
# user = User.query.filter(User.username == 'tan1997').first()
# print(user.username,user.password)

# 修改
# user=User.query.filter(User.username == 'tan1997').first()
# user.password=1234567
# db.session.commit()

# 删除
# user=User.query.filter(User.username == 'tan1997').first()
# db.session.delete(user)
# db.session.commit()

@app.route('/')
def index():
    context = {
        'question': Question.query.order_by('-create_time').all()
    }
    return render_template("index.html", **context)


@app.route('/login/', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else:
        usern = request.form.get('username')
        password1 = request.form.get('password')
        user = User.query.filter(User.username == usern).first()
        if user:
            if user.check_password(password1):
                session['user'] = usern
                session['id'] = user.id
                session.permanent = True
                return redirect(url_for('index'))
            else:
                return '密码错误'
        else:
            return '用户名不存在'


@app.context_processor
def mycontext():
    usern = session.get('user')
    if usern:
        return {
            'susername': usern,
        }
    else:
        return {}


def loginFirst(func):  # 定义需要装饰器
    @wraps(func)
    def wrapper(*args, **kwargs):  # 定义个函数将其返回
        if session.get('user'):
            return func(*args, **kwargs)
        else:
            return redirect(url_for('login'))

    return wrapper  # 返回一个函数


@app.route('/regist/', methods=['GET', 'POST'])
def regist():
    if request.method == 'GET':
        return render_template("regist.html")
    else:
        username = request.form.get('username')
        password = request.form.get('password')
        nickname = request.form.get('nickname')
        user = User.query.filter(User.username == username).first()
        if user:
            return ' 用户名已存在'
        else:
            user = User(username=username, password=password, nickname=nickname)
            db.session.add(user)  # 数据库,添加操作
            db.session.commit()
            return redirect(url_for('login'))


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


@app.route('/question/', methods=['GET', 'POST'])
@loginFirst  # 使用定义的装饰器
def question():
    if request.method == 'GET':
        return render_template('question.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)
        db.session.add(question)
        db.session.commit()  # 事务提交,将数据添加进数据库
        return redirect(url_for('index'))


@app.route('/detail/<question_id>')  # 和idea的update一样,将id带到控制器
def detail(question_id):
    quest = Question.query.filter(Question.id == question_id).first()  # 根据id查询出整条元组记录,丢进quest
    return render_template('detail.html', ques=quest)  # 把值quest丢进键quest,在detail.html页面调用


@app.route('/comment/', methods=['POST'])
@loginFirst
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))


@app.route('/user/<user_id>/<tag>')
@loginFirst
def user(user_id, tag):
    user = User.query.filter(User.id == user_id).first()
    context = {
        'user': user,
        'username': user.username,
        'questions': user.question,  # 用反向定义的question
        'comments': user.comments
    }
    if tag == '1':
        return render_template('usercenter1.html', **context)
    elif tag == '2':
        return render_template('usercenter2.html', **context)
    else:
        return render_template('usercenter3.html', **context)


#
# @app.route('/usercenter1/<user_id>')
# def usercenter1(user_id):
#     user = User.query.filter(User.id == user_id).first()
#     context = {
#         'username_id': user.id,
#         'username': user.username,
#         'questions': user.question,  # 用反向定义的question
#         'comments': user.comments
#     }
#     return render_template('usercenter1.html', **context)
#
#
# @app.route('/usercenter2/<user_id>')
# def usercenter2(user_id):
#     user = User.query.filter(User.id == user_id).first()
#     context = {
#         'username_id': user.id,
#         'username': user.username,
#         'questions': user.question,  # 用反向定义的question
#         'comments': user.comments
#     }
#
#     return render_template('usercenter2.html', **context)
#
#
# @app.route('/usercenter3/<user_id>')
# def usercenter3(user_id):
#     user = User.query.filter(User.id == user_id).first()
#     context = {
#         'username_id': user.id,
#         'username': user.username,
#         'questions': user.question,  # 用反向定义的question
#         'comments': user.comments
#     }
@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('-create_time')
    return render_template('index.html',question=ques)


if __name__ == '__main__':
    app.run(debug=True)

 

models.py文件:

from datetime import datetime
from werkzeug.security import generate_password_hash,check_password_hash
from exts import 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(50))

    @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'))  # 反向定义一个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'))

 

exit.py文件:

from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()

 

manage.py文件:

from flask_script import Manager
from flask_migrate import Migrate,MigrateCommand
from myqa import app
from exts import db
from models import User,Question,Comment


manager = Manager(app) # Manager只有一个参数:一个Flask实例
migrate = Migrate(app,db) # 使用Migrate绑定app和db

# 添加迁移脚本命令
manager.add_command('db',MigrateCommand) # 加入命令,命令行输入python manage.py db migrate

if __name__ == '__main__':
    manager.run()

 

config.py文件:

import os
DEBUG = True

SECRET_KEY = os.urandom(24)

DIALECT = 'mysql'
DRIVER = 'mysqldb'
USERNAME = 'root'
PASSWORD = 'ROOT'
HOST = '127.0.0.1'
DATABASE = 'mytest'








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

 

父模板html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>主页 {% block logintitle %}
    {% endblock %}
        {% block registtitle %}
        {% endblock %}
        {% block questiontitle %}
        {% endblock %}
        {% block indextitle %}
        {% endblock %}
        {% block detailtitle %}
        {% endblock %}
        {% block selfinfotitle %}
        {% endblock %}
        {% block usertitle %}
        {% endblock %}
    </title>

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/myweb.css') }}">
    <script src="{{ url_for('static',filename='js/switch.js') }}"></script>
    <script src="{{ url_for('static',filename='js/footerPosition.js') }}"></script>
    {% block loginhead %}
    {% endblock %}
    {% block registhead %}
    {% endblock %}
    {% block questionhead %}
    {% endblock %}
    {% block indexhead %}
    {% endblock %}
    {% block detailhead %}
    {% endblock %}
    {% block selfinfohead %}
    {% endblock %}
    {% block userhead %}
    {% endblock %}
</head>

<body id="myBody" style="background-image: url(/static/img/bg.jpg)">


<main>
    <nav class="navbar navbar-default" role="navigation">
        <div class="container-fluid">
            <div class="navbar-header">
                <a href="{{ url_for('index') }}" class="navbar-brand">首页</a>
                <button type="submit" class="btn btn-default" style="margin-top: 12px">
                    <a href="{{ url_for('question') }}">发布</a></button>
                 <form class="navbar-form navbar-left" action="{{ url_for('search') }}" method="get">
                    <div class="form-group">
                        <input name="q" type="text" class="form-control" placeholder="请输入关键字">
                    </div>
                    <button type="submit" class="btn btn-default" style="margin-top: 3px">搜索</button>
                </form>
            </div>
            <ul class="nav navbar-nav navbar-right">
                {% if susername %}
                    <li><a href="{{ url_for('user',user_id =session.get('id'),tag = 1) }}">{{ susername }}</a></li>
                    <li><a href="{{ url_for('logout') }}">注销</a></li>
                {% else %}
                    <li><a href="{{ url_for('regist') }}"><span class="glyphicon glyphicon-user"></span> 注册</a></li>
                    <li><a href="{{ url_for('login') }}"><span class="glyphicon glyphicon-log-in"></span> 登录</a>
                    </li>
                {% endif %}
                <li style="float: right"><img id="myOnOff" onclick="mySwitch()"
                                              src="http://www.runoob.com/images/pic_bulbon.gif"
                                              class="bulb"></li>
            </ul>

        </div>
    </nav>
</main>


<footer class="fixed-bottom">@版权所有</footer>
</body>
{% block loginbody %}  {% endblock %}.
{% block registbody %}  {% endblock %}
{% block questiontbody %} {% endblock %}
{% block indexbody %} {% endblock %}
{% block detailbody %} {% endblock %}
{% block selfinfobody %} {% endblock %}
{% block userbody %} {% endblock %}

</html>

 

 

 首页html:

{% extends'myweb.html' %}
{% block indextitle %}首页{% endblock %}




{% block indexhead %}
    <link rel="stylesheet" type="text/css" href="../static/css/component.css"/>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="../static/js/login.js"></script>
{% endblock %}

{% block indexbody %}
    <div class="container">
        <div class="row clearfix">
            <div class="col-md-10 column" id="rgba1">
                <h3 align="center">旅游问答区域</h3>
                <ul>
                    {% for foo in question %}
                        <li>
                            <a href="{{ url_for('user',user_id = foo.author_id,tag = 1) }}">{{ foo.author.username }}</a>
                            <br>
                            <p>标题:<a href="{{ url_for('detail',question_id=foo.id) }}">{{ foo.title }}</a></p>
                            <br>
                            <p>内容:{{ foo.detail }}</p>
                            <span>评论数: ({{ foo.comments|length }})</span>
                            <span class="badge pull-right">{{ foo.create_time }}</span>
                            <hr>
                        </li>
                    {% endfor %}
                </ul>
            </div>
        </div>
    </div>

{% endblock %}

 

 

登录页面html:

{% extends'myweb.html' %}
{% block logintitle %}登录页面{% endblock %}


{% block loginhead %}
    <link rel="stylesheet" type="text/css" href="../static/css/component.css"/>
     <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="../static/js/login.js"></script>
{% endblock %}

{% block loginbody %}

    <div class="logo_box">
        <h3 class="h3">请登录</h3>
        <form action="{{ url_for('login') }}" method="post">
            <div class="input_outer">
                <span class="u_user"></span>
                <input id="uname" class="text" style="color: gold" type="text" placeholder="请输入账号" name="username">
            </div>
            <div class="input_outer">
                <span class="us_uer"></span>
                <input id="upass" class="text" style="color:black ; position:absolute; z-index:100;"
                       value="" type="password" placeholder="请输入密码" name="password">
            </div>
            <div class="errorText" id="error_box" style="color: black"><br></div>
            <div>
                <button onclick="return fnLogin()" class="lb1" style="color:black">登录</button>
            </div>
        </form>
    </div>
{% endblock %}

 

 

注册页面html:

{% extends'myweb.html' %}
{% block registtitle %}注册页面{% endblock %}
{% block registhead %}
    <link rel="stylesheet" type="text/css" href="../static/css/component.css"/>
    <script src="../static/js/regist.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
{% endblock %}
{% block registbody %}
    <div class="logo_box">
        <h3 class="h3">欢迎注册</h3>
        <form action="{{ url_for('regist') }}" method="post">
            <div class="input_outer">
                <span class="u_user"></span>
                <input id="uname" class="text" style="color: gold" type="text" placeholder="请输入账号" name="username">
            </div>
            <div class="input_outer">
                <span class="u_user"></span>
                <input id="unickname" class="text" style="color: black" type="text" placeholder="请输入昵称"
                       name="nickname">
            </div>
            <div class="input_outer">
                <span class="us_uer"></span>
                <input id="upass" class="text" style="color:black ; position:absolute; z-index:100;"
                       value="" type="password" placeholder="请输入密码" name="password">
            </div>
            <div class="input_outer">
                <span class="us_uer"></span>
                <input id="upass1" class="text" style="color:black ; position:absolute; z-index:100;"
                       value="" type="password" placeholder="请再次输入密码">
            </div>
            <div class="errorText" id="error_box" style="color: red"><br></div>
            <div>
                <button class="lb1" style="color:black" type="submit" onclick="return fnRegist()">注册</button>
            </div>
        </form>
    </div>
{% endblock %}

 

 

发布问答页面html:

{% extends'myweb.html' %}
{% block questiontitle %}问答页面{% endblock %}


{% block questionhead %}
    <link rel="stylesheet" type="text/css" href="../static/css/myweb.css"/>
    <link rel="stylesheet" type="text/css" href="../static/css/component.css"/>
     <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
{% endblock %}

{% block questiontbody %}
<h3 class="h3">发布问答</h3>
<div class="ques">

    <form action="{{ url_for('question') }}" method="post">
        <div class="form-group">
            <label  for="questionTitle" style="color: black">标题</label><br>
            <textarea class="textareabg" rows="1"  id="questionTitle" name="title" style="width: 700px"></textarea>
            <label for="questionDatail" style="color: black">详情:</label><br>
            <textarea class="textareabg" rows="5" id="questionDatail" name="detail" style="width: 700px"></textarea>
            <br>
            <div id=""><br></div>
            <input type="submit" value="发布" class="btn btn-default" onclick="" style="margin-left: 100%">
        </div>
    </form>
</div>
{% endblock %}

 

 

问答详情页html:

{% extends 'myweb.html' %}
{% block detailtitle %}问答详情{% endblock %}
{% block detailhead %}
    <link rel="stylesheet" type="text/css" href="../static/css/component.css"/>
    <script src="../static/js/regist.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
{% endblock %}

{% block detailbody %}
    <div class="col-md-2 column "></div>
    <div class="col-md-8 column "  id="rgba1">
        <ul class="list-unstyled">
            <li>
                <h2 href="#" class="text-center">{{ ques.title }}</h2>
                <br>
                <p class="text-center">

                 <a href="{{ url_for('user',user_id = session.get('id'),tag = 1) }}">
                        <small>{{ ques.author.username }}</small></a>
                    </a>&nbsp&nbsp&nbsp
                    <span class="pull-center"><small>{{ ques.create_time }}</small></span>
                </p>
                <p>{{ ques.detail }}</p>
                <form action="{{ url_for('comment') }}" method="post">
                    <div class="form-group">
                    <textarea name="new_comment" class="form-control" rows="5" id="comment"
                              placeholder="请输入评论"></textarea>
                        <input type="hidden" name="question_id" value="{{ ques.id }}">
                    </div>
                    <button type="submit" class="btn btn-default" style="margin-left:48% ">发送</button>
                </form>
            </li>
        </ul>
        <hr>
        <h4>评论:({{ ques.comments|length }})</h4>
        <ul class="list-unstyled">
            {% for foo in ques.comments %}
                <li class="list-group-item">
                    <a href="{{ url_for('user',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>
    <div class="col-md-2 column "></div>
{% endblock %}

 

 

个人中心html:

{% extends'myweb.html' %}

{% block usertitle %}个人中心{% endblock %}

{% block userhead %}

{% endblock %}

{% block userbody %}

    <div class="container">
        <div class="row clearfix">
            <div class="col-md-2 column">
            </div>
            <div class="col-md-8 column">
                <ul class="nav nav-tabs">
                    <li>
                        <a href="{{ url_for('user',user_id = user.id,tag = 1) }}">全部问答</a>
                    </li>
                    <li>
                        <a href="{{ url_for('user',user_id = user.id,tag = 2) }}">全部评论</a>
                    </li>
                    <li>
                         <a href="{{ url_for('user',user_id = user.id,tag = 3) }}">个人信息</a>
                    </li>

                </ul>
            </div>
            <div class="col-md-2 column">
            </div>
        </div>
    </div>
    {% block user %}{% endblock %}



{% endblock %}
{% extends 'user.html' %}
{% block user %}

    <div class="container">
        <div class="row clearfix">
            <div class="col-md-2 column">
            </div>
            <div class="col-md-8 column" id="rgba1">
                <p class="text-center">
                    <small>{{ username }}</small>
                </p>
                <hr>
                <h3 align="center">
                    <small>全部问答</small>
                </h3>
                <ul class="list-unstyled">
                    {% for foo in questions %}
                        <li class="list-group-item">
                            <span class="glyphicon glyphicon-user"></span><a>{{ foo.author.username }}</a>
                            <p>标题:{{ foo.title }}</p>
                            <p>问答内容:{{ foo.detail }}</p>
                            <span class="badge pull-right">{{ foo.create_time }}</span><br>
                            <br>
                        </li>
                    {% endfor %}
                </ul>
            </div>
            <div class="col-md-2 column">
            </div>
        </div>
    </div>
{% endblock %}
{% extends 'user.html' %}
{% block user %}
<div class="container">
    <div class="row clearfix">
        <div class="col-md-2 column">
        </div>
        <div class="col-md-8 column"  id="rgba1">

    <p class="text-center"><small>{{ username }}</small></p>
        <hr>
        <h3 align="center">
            <small>全部评论</small>
        </h3>
        <ul class="list-unstyled">
            {% for foo in comments %}
                <li class="list-group-item">

                    <span class="badge pull-right">{{ foo.create_time }}</span>
                    <p>文章标题:{{ foo.question.title }}</p>
                    <p>评论内容:{{ foo.detail }}</p>
                    <span class="glyphicon glyphicon-user"></span><small ><a>{{ foo.author.username }}</a></small>
                    <br>
                </li>
            {% endfor %}
        </ul>
        </div>
        <div class="col-md-2 column">
        </div>
    </div>
</div>
{% endblock %}
{% extends 'user.html' %}
{% block user %}

    <div class="container">
        <div class="row clearfix">
            <div class="col-md-2 column">
            </div>
            <div class="col-md-8 column" id="rgba1">
                <p class="text-center">
                    <small>{{ username }}</small>
                </p>
                <hr>
                <h3 align="center">
                    <small>个人信息</small>
                </h3>
                <ul class="list-group">
                    <li class="list-group-item" style="background-color: antiquewhite"><span class="glyphicon glyphicon-user"></span>用户:{{ username }}</li>
                    <li class="list-group-item" style="background-color: wheat">昵称</li>
                    <li class="list-group-item" style="background-color: aquamarine">文章篇数:{{ questions|length }}</li>
                </ul>
            </div>
            <div class="col-md-2 column">
            </div>
        </div>
    </div>
{% endblock %

 

 

 

 

 

 

posted @ 2018-01-05 21:41  029郭媚婷  阅读(250)  评论(0编辑  收藏  举报