日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開源 > php教程 > Flask Web 開發(fā) 關(guān)注者

Flask Web 開發(fā) 關(guān)注者

來源:程序員人生   發(fā)布時(shí)間:2016-10-10 08:46:17 閱讀次數(shù):2903次

學(xué)到這1章,感覺有點(diǎn)回到第8章的味道......有幾個(gè)坑還是后期需要靜下心來補(bǔ)的


對(duì)模型間的關(guān)系,準(zhǔn)備另外單獨(dú)拎出來寫1篇測(cè)試文章,這里留個(gè)位置給鏈接吧

#

# 留位置給番外篇

#

上圖是1個(gè)自援用的關(guān)系圖,就用于像關(guān)注和被關(guān)注這樣,關(guān)聯(lián)表兩邊只有1個(gè)實(shí)體(用戶)的情況的。


本例的關(guān)聯(lián)表是follows,其中每行都表示1個(gè)用戶關(guān)注了另外一個(gè)用戶。圖中左側(cè)表示的1對(duì)多關(guān)系把用戶和follows 表中的1組記錄聯(lián)系起來,用戶是關(guān)注者。圖中右側(cè)表示
的1對(duì)多關(guān)系把用戶和follows 表中的1組記錄聯(lián)系起來,用戶是被關(guān)注者。

上面這句話甚么意思呢?

就是在follows表格里面,他的組成情勢(shì)是2個(gè)列,follower_id和followed_id,里面的id分別是主動(dòng)關(guān)注的人的id被關(guān)注者的id

class Follow(db.Model): __tablename__ = 'follows' follower_id = db.Column(db.Integer, db.ForeignKey('users.id'),primary_key=True) followed_id = db.Column(db.Integer, db.ForeignKey('users.id'),primary_key=True) timestamp = db.Column(db.DateTime, default=datetime.utcnow)

從Follow類的屬性定義里面我們就可以看到,follower_id作為外鍵,對(duì)應(yīng)的是users.id, 而followed_id作為外鍵,對(duì)應(yīng)的也是user.id



再來看對(duì)應(yīng)的users表,也就是User類。

需要特別注意的是foreign_keys的值,

followed表示已關(guān)注的人,他對(duì)應(yīng)的是Follow類里面的follower_id這個(gè)屬性,也就是,關(guān)注了哪些人,具體的值是id號(hào)

followers表示自己的粉絲,對(duì)應(yīng)的是Follow類里面的followed_id,這個(gè)有點(diǎn)拗口,這個(gè)實(shí)際上是自己粉絲的id

關(guān)于lazy,已轉(zhuǎn)載了其他先輩的1篇文章,而關(guān)于cascade,是和刪除對(duì)象時(shí)候,關(guān)聯(lián)表格里面的內(nèi)容會(huì)不會(huì)1起刪掉有關(guān)系的,后續(xù)再說

class User(UserMixin,db.Model): #... followed = db.relationship('Follow',foreign_keys=[Follow.follower_id], backref=db.backref('follower', lazy='joined'), lazy='dynamic',cascade='all, delete-orphan') followers = db.relationship('Follow',foreign_keys=[Follow.followed_id], backref=db.backref('followed', lazy='joined'), lazy='dynamic',cascade='all, delete-orphan')





接著是給User實(shí)例添加方法

關(guān)注的話,你肯定最少要做1個(gè)按鈕給用戶,那這個(gè)按鈕設(shè)計(jì)到2個(gè)功能,關(guān)注和取消關(guān)注,2個(gè)狀態(tài),是不是已關(guān)注,是不是已被關(guān)注

class User(UserMixin,db.Model): #... def follow(self, user): if not self.is_following(user): f = Follow(follower=self, followed=user) db.session.add(f) def unfollow(self, user): f = self.followed.filter_by(followed_id=user.id).first() if f: db.session.delete(f) def is_following(self, user): return self.followed.filter_by(followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by(follower_id=user.id).first() is not None
follow() 方法手動(dòng)把Follow 實(shí)例插入關(guān)聯(lián)表,從而把關(guān)注者和被關(guān)注者聯(lián)接起來,并讓程序有機(jī)會(huì)設(shè)定自定義字段的值。聯(lián)接在1起的兩個(gè)用戶被手動(dòng)傳入Follow 類的構(gòu)造器,創(chuàng)建1個(gè)Follow 新實(shí)例,然后像平常1樣,把這個(gè)實(shí)例對(duì)象添加到數(shù)據(jù)庫(kù)會(huì)話中。注意,這里無需手動(dòng)設(shè)定timestamp 字段,由于定義字段時(shí)指定了默許值,即當(dāng)前日期和時(shí)間。unfollow() 方法使用followed 關(guān)系找到聯(lián)接用戶和被關(guān)注用戶的Follow 實(shí)例。若要燒毀這兩個(gè)用戶之間的聯(lián)接,只需刪除這個(gè)Follow 對(duì)象便可。is_following() 方法和is_followed_by() 方法分別在左右兩邊的1對(duì)多關(guān)系中搜索指定用戶,如果找到了就返回True。

以上文字是書上的,可以看到,follow()方法最后通過db.session.add來插入新對(duì)象f,而unfollow()方法則是通過db.session.delete來刪除這個(gè)實(shí)例


分步講授下,在follow方法內(nèi),他通過self.is_following(user)來檢查,當(dāng)前用戶針對(duì)user是不是已是關(guān)注的狀態(tài),下面的is_following方法你可以看到,return出來的是not None

也就是說,follow方法在檢查結(jié)果是not (not None)的情況下,會(huì)繼續(xù)插入新的Follow實(shí)例,最后插入數(shù)據(jù)庫(kù)


而unfollow方法則是,通過self對(duì)象的followed屬性查找關(guān)注了多少人,然后通過followed_id=user.id這句,找出目前這個(gè)user對(duì)象并賦予給f

如果f存在,則通過session刪除f對(duì)象


is_following方法,通過self對(duì)象的關(guān)注人里面,用user.id來檢查自己是不是已關(guān)注這個(gè)人,返回結(jié)果not None,非空

is_followed_by,1樣,看self對(duì)象自己的粉絲群里面,通過user.id找找是不是有這個(gè)人,返回結(jié)果也是not None,非空

以上2個(gè)方法是表示1個(gè)狀態(tài),而不是功能性方法。


{% if current_user.can(Permission.FOLLOW) and user != current_user %} {% if not current_user.is_following(user) %} <a href="{{url_for('.follow',username=user.username)}}" class = "btn btn-primary">Follow</a> {% else %} <a href="{{url_for('.unfollow',username=user.username)}}" class = "btn btn-default">Unfollow</a> {% endif %} {% endif %} <a href="{{url_for('.followers',username=user.username)}}"> Followers: <span class="badge">{{ user.followers.count() }}</span> </a> <a href="{{ url_for('.followed_by',username=user.username) }}"> Following: <span class="badge">{{ user.followed.count() }}</span> </a> {% if current_user.is_authenticated and user != current_user and user.is_following(current_user)%} | <span class="label label-default">Follows you</span> {% endif %}


前端渲染寫好以后,就要寫路由控制了

@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 now unfollow %s'%username) return redirect(url_for('.user',username=username))

follow和unfollow為1組

follow的邏輯是:有2個(gè)條件,需要已登錄狀態(tài),需要有FOLLOW權(quán)限,通過url里面的username,過濾出該對(duì)象用戶,隨落后行判斷

如果用戶不存在,則提示flash消息,無功效戶

如果用戶已關(guān)注了該用戶,則提示flash消息,已關(guān)注該用戶

如果沒有關(guān)注,則履行當(dāng)前用戶的follow方法,關(guān)注該用戶

unfollow的邏輯1樣




@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.follower,'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)


隨后2個(gè)是該用戶的粉絲頁(yè)面和所關(guān)注的人的頁(yè)面

邏輯和上面差不多,也是通過username來過濾出該用戶

如果用戶沒有,則提示flash消息

否則,則進(jìn)行分頁(yè)顯示你的粉絲隊(duì)伍和偶像隊(duì)伍



先來看看整體效果圖



點(diǎn)了關(guān)注以后的變化



粉絲頁(yè)面













生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 日韩精品在线看 | 欧美日韩一区二区三区视频 | 久久综合九九 | 久久午夜视频 | 成人免费毛片高清视频 | 国产精品中文在线 | 在线视频一区二区三区 | 不用播放器看av | 欧美乱操| 动漫精品一区二区三区 | 久久精品网 | 精品综合久久 | 国产成人精品一区二 | 亚洲激情欧美激情 | 成人爽a毛片免费啪啪动漫 成人欧美一区二区三区黑人孕妇 | 一个色av | 久久中文免费 | 韩日一级片 | 国产精品99 | 免费一区二区三区 | 亚洲精品一区在线 | 日韩在线精品强乱中文字幕 | 久久久看片 | 国产区在线 | 久久久一 | 99热只有精品在线观看 | 国产成人精品午夜 | 日本亚洲欧美 | 成人动漫在线免费观看 | 伊人国产在线 | 亚洲黄色在线视频 | 免费亚洲网站 | 国产精品九九 | 国产精品一区二区在线看 | 精品伦精品一区二区三区视频 | 欧美一区二区三区啪啪 | 男人天堂网在线 | 91精品国产91久久综合桃花 | 欧美黄绝片| 九九精品视频在线观看 | 91麻豆精品一区二区三区 |