本學期我學習了使用Flask框架搭建一個web service,並在其中加上一些簡單的css,js,html等。Python是一種高級動態,徹底面向對象的語言,方便快捷。關於web的建設,前端頁面咱們作了導骯頁面、登陸註冊頁面、發佈問答頁面,在後端建設過程當中咱們引入了flask庫中的Flask, render_template,用於建立一個Flask對象以及頁面的跳轉,引入flask_sqlalchemy庫進行數據庫的關聯映射等,在後端設計過程咱們學了對數據的增刪改查等操做,利用對數據庫的查詢添加功能實現了頁面的登錄、註冊以及發佈功能,這些功能的實現根據前端頁面的name屬性名,後臺請求接收同名name的值,再將接收的值作一系列增刪查改操做。在對這些name屬性命名時要注意先後端對應且同一頁面不能出現相同名,不然會出現數據傳遞出錯,在作發佈詳情中咱們在頁面跳轉請求時帶上須要用到的‘id’,利用該‘id’去後臺查詢數據,在作用戶詳情時咱們用三個頁面跳轉同一個請求,不一樣的是在請求中用if語句判斷,判斷各自實現的功能並跳轉不一樣頁面。在這些過程當中,其實遇到過不少的問題,css老是沒法調整成本身想要的樣子,就查閱參考了不少網頁,模仿他們的div構造。而且在實行增刪改查功能時也會出現name屬性名不一致而致使功能沒法實現的問題。javascript
1.使用工具:pycharm64.exe 、Python 3.6 、MySQL css
Pythonhtml
Python是一種面向對象的解釋型計算機程序設計語言,Python是純粹的自由軟件, 源代碼和解釋器CPython遵循 GPL(GNU General Public License)協議。Python語法簡潔清晰,特點之一是強制用空白符(white space)做爲語句縮進。Python具備豐富和強大的庫。它常被暱稱爲膠水語言,可以把用其餘語言製做的各類模塊(尤爲是C/C++)很輕鬆地聯結在一塊兒。常見的一種應用情形是,使用Python快速生成程序的原型(有時甚至是程序的最終界面),而後對其中有特別要求的部分,用更合適的語言改寫,好比3D遊戲中的圖形渲染模塊,性能要求特別高,就能夠用C/C++重寫,然後封裝爲Python能夠調用的擴展類庫。須要注意的是在您使用擴展類庫時可能須要考慮平臺問題,某些可能不提供跨平臺的實現。前端
Flaskjava
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的編譯日誌。web
MySQLsql
關於數據庫,上學期咱們學習了sql server,它和MySQL有一點不同,MySQL不支持事務處理,沒有視圖,沒有存儲過程和觸發器,沒有數據庫端的用戶自定義函數,不能徹底使用標準的SQL語法。 MySQL是一個關係型數據庫管理系統,MySQL 是最流行的關係型數據庫管理系統之一,在 WEB 應用方面,MySQL是最好的 RDBMS (Relational Database Management System,關係數據庫管理系統) 應用軟件。MySQL是一種關係數據庫管理系統,關係數據庫將數據保存在不一樣的表中,而不是將全部數據放在一個大倉庫內,這樣就增長了速度並提升了靈活性。MySQL所使用的 SQL 語言是用於訪問數據庫的最經常使用標準化語言。MySQL 軟件採用了雙受權政策,分爲社區版和商業版,因爲其體積小、速度快、整體擁有成本低,尤爲是開放源碼這一特色,通常中小型網站的開發都選擇 MySQL 做爲網站數據庫。數據庫
2.功能實現過程flask
{% 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>
首頁:bootstrap
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>