期末作品检查

       本学期我学习了使用Flask框架搭建一个web service,并在其中加上一些简单的css,js,html等。Python是一种高级动态,完全面向对象的语言,方便快捷。关于web的建设,前端页面我们做了导肮页面、登录注册页面、发布问答页面,在后端建设过程中我们引入了flask库中的Flask, render_template,用于创建一个Flask对象以及页面的跳转,引入flask_sqlalchemy库进行数据库的关联映射等,在后端设计过程我们学了对数据的增删改查等操作,利用对数据库的查询添加功能实现了页面的登陆、注册以及发布功能,这些功能的实现根据前端页面的name属性名,后台请求接收同名name的值,再将接收的值做一系列增删查改操作。在对这些name属性命名时要注意前后端对应且同一页面不能出现相同名,否则会出现数据传递出错,在做发布详情中我们在页面跳转请求时带上需要用到的‘id’,利用该‘id’去后台查询数据,在做用户详情时我们用三个页面跳转同一个请求,不同的是在请求中用if语句判断,判断各自实现的功能并跳转不同页面。在这些过程中,其实遇到过很多的问题,css总是无法调整成自己想要的样子,就查阅参考了很多网页,模仿他们的div构造。并且在实行增删改查功能时也会出现name属性名不一致而导致功能无法实现的问题。

1.使用工具:pycharm64.exe 、Python 3.6 、MySQL 

Python

Python是一种面向对象的解释型计算机程序设计语言,Python是纯粹的自由软件, 源代码和解释器CPython遵循 GPL(GNU General Public License)协议。Python语法简洁清晰,特色之一是强制用空白符(white space)作为语句缩进。Python具有丰富和强大的库。它常被昵称为胶水语言,能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起。常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写,比如3D游戏中的图形渲染模块,性能要求特别高,就可以用C/C++重写,而后封装为Python可以调用的扩展类库。需要注意的是在您使用扩展类库时可能需要考虑平台问题,某些可能不提供跨平台的实现。

Flask

Flask是一个面向简单需求小型应用的“微框架(microframework)”,Flask选择组件的额外工作给那些使用案例不适用标准ORM的开发者提供了更多的灵活性,同样也给使用不同工作流和模版化系统的开发者们带来了灵活性。
虽然Flask历史相对更短,但它能够学习之前出现的框架并且把注意力放在了微小项目上。它大多数情况被使用在一些只有一两个功能的小型项目上。例如 httpbin,一个简单的(但很强大的)调试和测试HTTP库的项目。Flask没有bootstrapping工具的原因:没有它们的需求。从Flask主页上的Hello World特性看,没有构建Python web应用经验的开发者可以立即开始hacking。对于各部分需要更多分离的项目,Flask有blueprints。例如,你可以将所有用户相关的函数放在users.py中,然后在site.py中添加引用它们来结构化你的Flask应用。我们不会深入这个功能,因为它超出了我们展示demo应用的需求。Flask对于那些开发小项目、需要快速制作一个简单的Python支撑的网站的开发者很有用。它提供小型的统一工具,或者在已有的API上构建的简单网络接口。可以快速开发需要简单web接口并不怎么配置的后端项目使用Flask将会在前端获益,如jitviewer提供了一个web接口来检测PyPy just-in-time的编译日志。

MySQL

关于数据库,上学期我们学习了sql server,它和MySQL有一点不一样,MySQL不支持事务处理,没有视图,没有存储过程和触发器,没有数据库端的用户自定义函数,不能完全使用标准的SQL语法。 MySQL是一个关系型数据库管理系统MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。

2.功能实现过程

{% extends "bootstrap_base.html" %}

{% block head %} <!-- headstart -->

{% block metas %}
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> 
<title>BLOG</title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
{% endblock%}
<link rel="icon" href="{{ url_for('static', filename = 'img/favicon.ico') }}"
type="image/x-icon">
    
{% block styles %}
    <script src="http://tjs.sjs.sinajs.cn/open/api/js/wb.js?appkey=1523741413" type="text/javascript" charset="utf-8"></script>
    <link rel="stylesheet" href="{{url_for('static',filename='css/styles.css')}}">
    <link rel="stylesheet" href="{{url_for('static',filename='css/bootstrap.min.css')}}">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css"> <!-- 提供通知小图标 -->
    <!-- Ionicons -->
    <link rel="stylesheet" href="{{url_for('static',filename='css/ionicons.min.css')}}"> 
    <!-- Theme style -->
    <link rel="stylesheet" href="{{url_for('static',filename='css/AdminLTE.min.css')}}">
    
    <link rel="stylesheet" href="{{url_for('static',filename='css/skin-blue.min.css')}}">
<!--     <script>var _hmt = _hmt || [];(function() {  var hm = document.createElement("script");  hm.src = "//hm.baidu.com/hm.js?4ef56ac18f75724ce187ba84286f0c6d";  var s = document.getElementsByTagName("script")[0];   s.parentNode.insertBefore(hm, s);})();</script> -->
{% endblock %}
{% endblock %} <!-- headend -->

{% block navbar %}
<header class="main-header" style="position: fixed;top: 0px;width:100%;max-height:100px;z-index:1030"> <!-- 固定置顶 -->
    <a href="{{ url_for('main.index') }}" class="logo">
      <!-- mini logo for sidebar mini 50x50 pixels -->
      <span class="logo-mini"><b>B</b>log</span>
    </a>
    <nav class="navbar navbar-static-top" role="navigation">
        <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
        <span class="sr-only">Toggle navigation</span>
        </a>
              <div class="navbar-header">
                <ul class="nav navbar-nav">
                    <li><a href="{{ url_for('main.index') }}">博客主页</a></li>
                    {% if current_user.is_authenticated %}
                    <li><a href="{{ url_for('main.user', username=current_user.username) }}">个人中心</a></li>
                    {% endif %}
                </ul>
                    <ul class="nav navbar-nav">
                    {% if current_user.can(Permission.MODERATE_COMMENTS) %}
                    <li><a href="{{ url_for('main.moderate') }}">管理评论</a></li>
                    {% endif %}

                    {% if not current_user.is_authenticated %} 
                    <li><a href="{{ url_for('auth.register') }}">注册</a> </li>
                    <li><a href="{{ url_for('auth.login') }}">登录</a> </li>
                    {% endif %}

                </ul>

              </div>

 

首页:

index.html:

def deletenoneuser():
    noneuser = User.query.filter_by(username=None).all()
    for user in noneuser:
        db.session.delete(user)
    db.session.commit()

@main.before_app_request
def before_request(): #定义全局变量
    g.search_form = SearchForm()
    g.hot_post=Post().hotpost()
    g.current_time=datetime.utcnow()
    g.categorys=Category.query.all() 
    



@main.after_app_request
def after_request(response):
    for query in get_debug_queries():
        if query.duration >= current_app.config['FLASKY_SLOW_DB_QUERY_TIME']:
            current_app.logger.warning(
                'Slow query: %s\nParameters: %s\nDuration: %fs\nContext: %s\n'
                % (query.statement, query.parameters, query.duration,
                   query.context))
    return response


@main.route('/shutdown')
def server_shutdown():
    if not current_app.testing:
        abort(404)
    shutdown = request.environ.get('werkzeug.server.shutdown')
    if not shutdown:
        abort(500)
    shutdown()
    return 'Shutting down...'

@main.route('/search', methods = ['POST'])
def search():
    if not g.search_form.validate_on_submit():
        return redirect(url_for('.index'))
    return redirect(url_for('.search_results', query = g.search_form.search.data))

@main.route('/search_results/<query>')
def search_results(query):
    posts = Post.query.filter(Post.head.like('%'+query+'%')).all()
    # query=Post.query.filter(Post.head.like("%文%")).all()
    return render_template('search_results.html',query = query, posts = posts,  )


@main.route('/', methods=['GET', 'POST'])
def index(): 
    deletenoneuser()   
    user = User() 
    message = Message() 
    category = Category()   
    page = request.args.get('page', 1, type=int)
    show_followed = False    
    if current_user.is_authenticated:
        show_followed = bool(request.cookies.get('show_followed', ''))
    if show_followed:
        query = current_user.followed_posts
    else:
        query = Post.query
    pagination = query.order_by(Post.timestamp.desc()).paginate(
        page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
        error_out=False)
    posts = pagination.items[:] #分页显示

    return render_template('index.html',  posts=posts,user=user,message=message,category=category,
                            show_followed=show_followed, pagination=pagination,hot_post=Post().hotpost())


@main.route('/writepost', methods=['GET', 'POST'])
@login_required
def writepost():    
    form = PostForm()
    if current_user.can(Permission.WRITE_ARTICLES) and \
            form.validate_on_submit():
        post = Post(body=form.body.data,head=form.head.data,category=Category.query.get(form.category.data),
                    author=current_user._get_current_object())                  
                     #内容、标题、作者、类别
        db.session.add(post)
        db.session.commit()
        #flash("博客已发布")
        return redirect(url_for('.index'))
    return render_template('writepost.html', form=form, )


@main.route('/user/<username>')
def user(username):
    user = User.query.filter_by(username=username).first_or_404()
    page = request.args.get('page', 1, type=int)
    pagination = user.posts.order_by(Post.timestamp.desc()).paginate(
        page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
        error_out=False)
    posts = pagination.items
    return render_template('user.html', user=user, posts=posts,
                           pagination=pagination,   )

#分类路由
@main.route('/category/<int:id>')
def category(id):
    category = Category.query.get_or_404(id)
    page = request.args.get('page', 1, type=int)
    pagination = category.posts.order_by(Post.timestamp.desc()).paginate(
        page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
        error_out=False)
    posts = pagination.items
    return render_template('category.html',category=category,posts=posts,pagination=pagination,  )


@main.route('/edit-profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
    form = EditProfileForm()
    if form.validate_on_submit():
        current_user.name = form.name.data
        current_user.location = form.location.data
        current_user.about_me = form.about_me.data
        db.session.add(current_user)
        flash('Your profile has been updated.')
        return redirect(url_for('.user', username=current_user.username))
    form.name.data = current_user.name
    form.location.data = current_user.location
    form.about_me.data = current_user.about_me
    return render_template('edit_profile.html', form=form, )


@main.route('/edit-profile/<int:id>', methods=['GET', 'POST'])
@login_required
@admin_required
def edit_profile_admin(id):
    user = User.query.get_or_404(id)
    form = EditProfileAdminForm(user=user)
    if form.validate_on_submit():
        user.email = form.email.data
        user.username = form.username.data
        user.confirmed = form.confirmed.data
        user.role = Role.query.get(form.role.data)
        user.name = form.name.data
        user.location = form.location.data
        user.about_me = form.about_me.data
        db.session.add(user)
        flash('The profile has been updated.')
        return redirect(url_for('.user', username=user.username))
    form.email.data = user.email
    form.username.data = user.username
    form.confirmed.data = user.confirmed
    form.role.data = user.role_id
    form.name.data = user.name
    form.location.data = user.location
    form.about_me.data = user.about_me
    return render_template('edit_profile.html', form=form, user=user, )



@main.route('/post/<int:id>', methods=['GET', 'POST'])
def post(id):
    hot_post=Post().hotpost()
    post = Post.query.get_or_404(id)
    form = CommentForm() 
    post.visits+=1
    print ("visits+1")
    
    if form.validate_on_submit():
        comment = Comment(body=form.body.data,post=post,sendto=post.author,
            author=current_user._get_current_object())
        db.session.add(comment)
        flash(u'你的评论已提交.')
        return redirect(url_for('.post', id=post.id, page=-1))
    page = request.args.get('page', 1, type=int)
    if page == -1:
        page = (post.comments.count() - 1) // \
            current_app.config['FLASKY_COMMENTS_PER_PAGE'] + 1
    pagination = post.comments.order_by(Comment.timestamp.asc()).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    comments = pagination.items
    return render_template('post.html', posts=[post], form=form,
                           comments=comments, pagination=pagination, hot_post=hot_post)

@main.route('/post/delete/<int:id>')
def post_delete(id):
    post=Post.query.get_or_404(id)
    db.session.delete(post)
    for comment in post.comments:
        db.session.delete(comment)
    for webpush in post.webpushs:
        db.session.delete(webpush)
    flash(u'博客以及相关的评论、推送已删除')
    return redirect(url_for('.user', username=post.author.username))



@main.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
def edit(id):
    post = Post.query.get_or_404(id)
    if current_user != post.author and \
            not current_user.can(Permission.ADMINISTER):
        abort(403)
    form = PostForm()
    if form.validate_on_submit():
        post.body = form.body.data
        post.head = form.head.data
        post.category=Category.query.get(form.category.data)
        #博客内容和标题
        db.session.add(post)
        flash('The post has been updated.')
        return redirect(url_for('.post', id=post.id))
    form.body.data = post.body
    form.head.data = post.head
    form.category.data = post.category_id
    return render_template('edit_post.html', form=form)


#收藏
@main.route('/star/<int:id>')
@login_required
@permission_required(Permission.FOLLOW)
def star(id):
    post=Post.query.get_or_404(id)
    if current_user.staring(post):
        flash('你已经收藏了这篇文章')
        return redirect(url_for('.post',id=post.id))
    current_user.star(post)
    flash('收藏完成')
    return redirect(url_for('.post',id=post.id))

@main.route('/unstar/<int:id>')
@login_required
@permission_required(Permission.FOLLOW)
def unstar(id):
    post=Post.query.get_or_404(id)
    if not current_user.staring(post):
        flash('你没有收藏这篇文章')
        return redirect(url_for('.post',id=post.id))
    current_user.unstar(post)
    flash('你不收藏这篇旷世奇文,太可惜了')
    return redirect(url_for('.post',id=post.id))


@main.route('/deletestar/<int:id>')
@login_required
@permission_required(Permission.FOLLOW)
def deletestar(id):
    post=Post.query.get_or_404(id)
    if not current_user.staring(post):
        flash('你没有收藏这篇文章')
        return redirect(url_for('.starposts',username=current_user.username))
    current_user.unstar(post)
    flash('你不再收藏这篇旷世奇文了,太可惜了')
    return redirect(url_for('.starposts',username=current_user.username))



@main.route('/user/<username>/starposts')
def starposts(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    page = request.args.get('page', 1, type=int)
    # pagination = user.starposts.paginate(
    #     page, per_page=current_app.config['FLASKY_FOLLOWERS_PER_PAGE'],
    #     error_out=False)
    posts = user.starposts
    return render_template('user_starposts.html', user=user, title="收藏的文章",
                           posts=posts)




@main.route('/follow/<username>')
@login_required
@permission_required(Permission.FOLLOW)
def follow(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    if current_user.is_following(user):
        flash('You are already following this user.')
        return redirect(url_for('.user', username=username))
    current_user.follow(user)
    flash('You are now following %s.' % username)
    return redirect(url_for('.user', username=username))


@main.route('/unfollow/<username>')
@login_required
@permission_required(Permission.FOLLOW)
def unfollow(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    if not current_user.is_following(user):
        flash('You are not following this user.')
        return redirect(url_for('.user', username=username))
    current_user.unfollow(user)
    flash('You are not following %s anymore.' % username)
    return redirect(url_for('.user', username=username))


@main.route('/followers/<username>')
def followers(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    page = request.args.get('page', 1, type=int)
    pagination = user.followers.paginate(
        page, per_page=current_app.config['FLASKY_FOLLOWERS_PER_PAGE'],
        error_out=False)
    follows = [{'user': item.follower, 'timestamp': item.timestamp}
               for item in pagination.items]
    return render_template('followers.html', user=user, title="Followers of",
                           endpoint='.followers', pagination=pagination,
                           follows=follows,   )


@main.route('/followed-by/<username>')
def followed_by(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    page = request.args.get('page', 1, type=int)
    pagination = user.followed.paginate(
        page, per_page=current_app.config['FLASKY_FOLLOWERS_PER_PAGE'],
        error_out=False)
    follows = [{'user': item.followed, 'timestamp': item.timestamp}
               for item in pagination.items]
    return render_template('followers.html', user=user, title="Followed by",
                           endpoint='.followed_by', pagination=pagination,
                           follows=follows,   )


@main.route('/all')
@login_required
def show_all():
    resp = make_response(redirect(url_for('.index')))
    resp.set_cookie('show_followed', '', max_age=30*24*60*60)
    return resp


@main.route('/followed')
@login_required
def show_followed():
    resp = make_response(redirect(url_for('.index')))
    resp.set_cookie('show_followed', '1', max_age=30*24*60*60)
    return resp

@main.route('/moderate/enable/<int:id>')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate_enable(id):
    comment = Comment.query.get_or_404(id)
    comment.disabled = False
    db.session.add(comment)
    return redirect(url_for('.moderate',
                            page=request.args.get('page', 1, type=int)), )


@main.route('/moderate/disable/<int:id>')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate_disable(id):
    comment = Comment.query.get_or_404(id)
    comment.disabled = True
    db.session.add(comment)
    return redirect(url_for('.moderate',
                            page=request.args.get('page', 1, type=int)), )



@main.route('/moderate')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate():
    page = request.args.get('page', 1, type=int)
    pagination = Comment.query.order_by(Comment.timestamp.desc()).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    comments = pagination.items
    return render_template('moderate.html', comments=comments,
                           pagination=pagination, page=page,   )


@main.route('/shownotice')
@login_required
@permission_required(Permission.COMMENT)
def shownotice():
    page = request.args.get('page', 1, type=int)
    pagination = Comment.query.order_by(Comment.timestamp.desc()).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    comments = pagination.items
    return render_template('shownotice.html', comments=comments,
                           pagination=pagination, page=page,   )


@main.route('/shownotice/unconfirmed/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def shownotice_unconfirmed(id):
    comment = Comment.query.get_or_404(id)
    comment.confirmed = True
    db.session.add(comment)
    return redirect(url_for('.shownotice',
                            page=request.args.get('page', 1, type=int)), )


@main.route('/shownotice/confirmed/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def shownotice_confirmed(id):
    comment = Comment.query.get_or_404(id)
    comment.confirmed = False
    db.session.add(comment)
    return redirect(url_for('.shownotice',
                            page=request.args.get('page', 1, type=int)), )



@main.route('/user/<username>/comments')
def usercomments(username):
    user=User.query.filter_by(username=username).first()
    page = request.args.get('page', 1, type=int)
    pagination = Comment.query.order_by(Comment.timestamp.desc()).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    comments = pagination.items
    return render_template('user_comments.html', comments=comments,user=user,
                           pagination=pagination, page=page,   )

@main.route('/usercomments/delete/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def usercomments_delete(id):
    comment = Comment.query.get_or_404(id)
    db.session.delete(comment)
    flash("评论已删除")
    return redirect(url_for('.usercomments',username=current_user.username,
                            page=request.args.get('page', 1, type=int)))


@main.route('/sendmessage/<username>', methods=['GET', 'POST'])
@login_required
@permission_required(Permission.COMMENT)
def sendmessage(username):
    user = User.query.filter_by(username=username).first()
    form = SendmessageForm()
    if form.validate_on_submit():
        message = Message(body=form.body.data, \
                    author=current_user,
                    sendto=user)
        db.session.add(message)
        db.session.commit()
        flash('私信发送成功')
        return redirect(url_for('.user', username=username))
        
    return render_template('sendmessage.html', form=form,  )


@main.route('/<username>/showwebpush')
@login_required
@permission_required(Permission.COMMENT)
def showwebpush(username):
    page = request.args.get('page', 1, type=int)
    pagination = Webpush.query.order_by(Webpush.timestamp.desc()).filter_by(sendto=current_user).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    webpushs = pagination.items
    return render_template('user_showwebpush.html',webpushs=webpushs,pagination=pagination,page=page)

@main.route('/webpush/unconfirmed/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def webpush_unconfirmed(id):
    webpush = Webpush.query.get_or_404(id)
    webpush.confirmed = True
    db.session.add(webpush)    
    return redirect(url_for('.showwebpush',page=request.args.get('page', 1, type=int),username=request.args.get('username')))

@main.route('/webpush/confirmed/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def webpush_confirmed(id):
    webpush = Webpush.query.get_or_404(id)
    webpush.confirmed = False
    db.session.add(webpush)
    return redirect(url_for('.showwebpush',page=request.args.get('page', 1, type=int),username=request.args.get('username')))

@main.route('/showwebpush/delete/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def webpush_delete(id):
    webpush = Webpush.query.get_or_404(id)   
    db.session.delete(webpush)    
    flash('消息删除成功')
    return redirect(url_for('.showwebpush',page=request.args.get('page', 1, type=int),username=request.args.get('username')))


@main.route('/showmessage')
@login_required
@permission_required(Permission.COMMENT)
def showmessage():
    page = request.args.get('page', 1, type=int)
    pagination = Message.query.order_by(Message.timestamp.desc()).filter_by(sendto=current_user).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    messages = pagination.items
    return render_template('showmessage.html', messages=messages,
                           pagination=pagination, page=page )


@main.route('/showmessage/unconfirmed/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def showmessage_unconfirmed(id):
    message = Message.query.get_or_404(id)
    message.confirmed = True
    db.session.add(message)
    return redirect(url_for('.showmessage',
                            page=request.args.get('page', 1, type=int)))


@main.route('/showmessage/confirmed/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def showmessage_confirmed(id):
    message = Message.query.get_or_404(id)
    message.confirmed = False
    db.session.add(message)
    return redirect(url_for('.showmessage',
                            page=request.args.get('page', 1, type=int)))


@main.route('/showmessage/delete/<int:id>')
@login_required
@permission_required(Permission.COMMENT)
def message_delete(id):
    message = Message.query.get_or_404(id)    
    db.session.delete(message)
    flash('私信删除成功')
    return redirect(url_for('.showmessage',
                            page=request.args.get('page', 1, type=int)))


@main.route('/about', methods=['GET', 'POST'])
def firstpage():
    return render_template('aboutme.html',  )

@main.route('/video', methods=['GET', 'POST'])
def video():
    return render_template('video.html',  )

index.css:

profile-thumbnail {
    position: absolute;
}
.profile-header {
    min-height: 260px;
    margin-left: 280px;
}
div.post-tabs {
    margin-top: 16px;
}
ul.posts {
    list-style-type: none;
    padding: 0px;
    margin: 16px 10px 10px 10px;
    border-top: 1px solid #e0e0e0;
}
div.post-tabs ul.posts {
    margin: 0px;
    border-top: none;
}
ul.posts li.post {
    padding: 8px;
    border-bottom: 1px solid #e0e0e0;
}
ul.posts li.post:hover {
    background-color: #f0f0f0;
}
div.post-date {
    float: right;
}
div.post-author {
    font-weight: bold;
}
div.post-thumbnail {
    position: absolute;
}
div.post-content {
    margin-left: 48px;
    min-height: 48px;
}
div.post-footer {
    text-align: right;
}
ul.comments {
    list-style-type: none;
    padding: 0px;
    margin: 16px 0px 0px 0px;
}
ul.comments li.comment {
    margin-left: 32px;
    padding: 8px;
    border-bottom: 1px solid #e0e0e0;
}
ul.comments li.comment:nth-child(1) {
    border-top: 1px solid #e0e0e0;
}
ul.comments li.comment:hover {
    background-color: #f0f0f0;
}
div.comment-date {
    float: right;
}
div.comment-author {
    font-weight: bold;
}
div.comment-thumbnail {
    position: absolute;
}
div.comment-content {
    margin-left: 48px;
    min-height: 48px;
}
div.comment-form {
    margin: 16px 0px 16px 32px;
}
div.pagination {
    width: 100%;
    text-align: right;
    padding: 0px;
    margin: 0px;
}
div.flask-pagedown-preview {
    margin: 10px 0px 10px 0px;
    border: 1px solid #e0e0e0;
    padding: 4px;
}
div.flask-pagedown-preview h1 {
    font-size: 140%;
}
div.flask-pagedown-preview h2 {
    font-size: 130%;
}
div.flask-pagedown-preview h3 {
    font-size: 120%;
}
.post-body h1 {
    font-size: 140%;
}
.post-body h2 {
    font-size: 130%;
}
.post-body h3 {
    font-size: 120%;
}
.table.followers tr {
    border-bottom: 1px solid #e0e0e0;

登录页面:
class LoginForm(Form):
    email = StringField(u'邮箱', validators=[Required(), Length(1, 64),
                                             Email()])
    password = PasswordField(u'密码', validators=[Required()])
    remember_me = BooleanField(u'记住我')
    submit = SubmitField(u'登录')


class RegistrationForm(Form):
    email = StringField(u'邮箱', validators=[Required(), Length(1, 64),
                                           Email()])
    username = StringField(u'用户名', validators=[
        Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
                                          'Usernames must have only letters, '
                                          'numbers, dots or underscores')])
    password = PasswordField(u'密码', validators=[
        Required(), EqualTo(u'password2', message='Passwords must match.')])
    password2 = PasswordField(u'确认密码', validators=[Required()])
    submit = SubmitField(u'注册')

    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first():
            raise ValidationError(u'Email已经被注册过.请更换')

    def validate_username(self, field):
        if User.query.filter_by(username=field.data).first():
            raise ValidationError(u'用户名已存在')


class ChangePasswordForm(Form):
    old_password = PasswordField(u'旧密码', validators=[Required()])
    password = PasswordField(u'新密码', validators=[
        Required(), EqualTo('password2', message='Passwords must match')])
    password2 = PasswordField(u'确认新的密码', validators=[Required()])
    submit = SubmitField(u'更新密码')


class PasswordResetRequestForm(Form):
    email = StringField(u'邮箱', validators=[Required(), Length(1, 64),
                                             Email()])
    submit = SubmitField(u'重置密码')


class PasswordResetForm(Form):
    email = StringField(u'邮箱', validators=[Required(), Length(1, 64),
                                             Email()])
    password = PasswordField(u'新密码', validators=[
        Required(), EqualTo('password2', message='Passwords must match')])
    password2 = PasswordField(u'确认新的密码', validators=[Required()])
    submit = SubmitField(u'重置密码')

    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first() is None:
            raise ValidationError(u'不合法的Email地址')


class ChangeEmailForm(Form):
    email = StringField(u'新邮箱', validators=[Required(), Length(1, 64),
                                                 Email()])
    password = PasswordField(u'密码', validators=[Required()])
    submit = SubmitField(u'更新邮箱')

    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first():
            raise ValidationError(u'邮箱已被使用')

发布评论定义评论的视图函数

@app.route('/comment/',methods=['GET','POST'])
@loginFirst
def comment():
    if request.method == 'GET':
        return render_template('question_detail.html')
    else:
        detail = request.form.get('detail')
        author_id =User.query.filter(User.username == session.get('user')).first().id
        question_id=request.form.get('question_id')
        comments = Comment(detail=detail,author_id=author_id,question_id=question_id)
        db.session.add(comments)
        db.session.commit()
        return redirect(url_for('question_detail',question_id=question_id))

显示评论次数,要求评论前登录

{% extends 'index.html' %}
{% block title %}问答详情{% endblock %}
{% block main %}
    <body style="url(../image/picture.jpg) no-repeat" >
         <div class="container">

             <div>
                 <h2>{{ ques.question }}<br><small>{{ ques.author.username }} <span class="badge">{{ ques.creat_time }}</span></small></h2></div>
             问题详情:<p class="lead">{{ ques.questionDetail }}</p>
             <p class="location">评论</p>

        <hr>
        <form action="{{ url_for('comment') }}" method="post">
            <div class="form-group">
                <textarea name="new_comment" class="form-control" id="new_comment" rows="3" placeholder="write your comment"style="height:200px;width:800px" ></textarea><br>
                <input name="question_id" type="hidden" value="{{ ques.id }}"/>
            </div>
                <button type="submit" class="fabu"style="width:100px">发布</button>
        </form>

             <h4>评论:({{ ques.comments|length }})</h4>
         </div>

         <ul class="list-group"style="width:700px;height:auto;border-style:groove;">
        {% for b in ques.comments %}
        <li class="list-group-item"style="list-style: none">
            <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>
            <a href="#">{{ b.author.username }}</a>
            <span class="badge">{{b.creat_time}}</span>
            <p style="">{{b.detail}}</p>
        </li>
{% endfor %}
        </ul>
    </body>
{% endblock %}



搜索功能:
<form action="{{url_for('search')}}" method="get" class="form-inline" > <input name="q" class="form-control mr-sm-2" type="search" placeholder="请输入关键字"style="border-radius: 25px" > <button class="btn btn-outline-success my-2 my-sm-0" type="submit">搜索</button> </form> </ul>
posted @ 2018-01-07 21:58  107梁艺康  阅读(254)  评论(0编辑  收藏  举报