表的模型实现

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)

 

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')

关注关系的辅助方法

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

 在资料页中显示关注者

app/templates/user.html

    {% 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-default">关注</a>
{% else %}
<a href="{{ url_for('.unfollow',username=user.username) }}"
class="btn btn-default">取消关注</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 %}

app/main/views.py: ‘关注’路由和视图函数

@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(u'用户不存在')
return redirect(url_for('.index'))
if current_user.is_following(user):
flash(u'已关注')
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('/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)

使用数据库联结查询所关注用户的文章

 要想只查看关注用户的文章需要把posts表和follows表联结起来查询

class User(UserMixin,db.Model):

    #..

    @property
def followed_posts(self):
return Post.query.join(Follow,Follow.followed_id == Post.author_id)\
.filter(Follow.follower_id == self.id)

Post表联结Follow表  Follow表被关注 = 文章作者的id  查找 Follow表中关注者的id

在首页显示所关注用户的文章

app/main/views.py:显示所有博客文章或只显示所关注用户的文章

@main.route('/', methods=['GET', 'POST'])
def index(): #... 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', form=form, posts=posts,show_followed=show_followed,
pagination=pagination)

决定显示所有文章还是只显示所关注用户文章的选项存储在cookie的show_followed字段中,如果其值为非空字符串,则表示只显示所关注用户的文章。

query的值决定最终获取所有博客的查询,或是获取过滤后的博客文章查询

app/main/views.py:查询所有文章还是所关注用户的文章

@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

resp返回一个响应,然后为它的cookie设置为 show_followed为空,过期时间为一个月

@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

resp返回一个响应,然后为它的cookie设置为 show_followed不为空,过期时间为一个月,表示只显示只看所关注用户的文章

接下来改动模板

    <div class="post-tabs">
<ul class="nav nav-tabs">
<li {% if not show_followed %}class="active"{% endif %} ><a href="{{ url_for('.show_all') }}" >全部</a></li>
{% if current_user.is_authenticated %}
<li {% if show_followed %}class="active"{% endif %}><a href="{{ url_for('.show_followed') }}">关注</a> </li>
{% endif %}
</ul>

app/model.py:构建用户时把用户设为自己的关注者

def __init__(self,**kwargs):

    self.follow(self)

app/models.py:把用户设为自己的关注者

    @staticmethod
def add_self_follows():
for user in User.query.all():
if not user.is_following(user):
user.follow(user)
db.session.add(user)
db.session.commit()

  

(venv) >python manage.py shell

>>> User.add_self_follows()

把关注者数量减一

    <a href="{{ url_for('.followers',username=user.username)}}">j
Followers:<span class="badge">{{ user.followers.count() - 1 }}</span>

  

·

flask_关注者的更多相关文章

  1. flask_关注者,联系人和好友

    在这节我们实现的功能比较复杂,就是实现用户"关注"和"取消关注"的功能. 一个用户可以关注多个其他的用户,一个用户也可以被其他多个用户所关注,这样看的话,在数据 ...

  2. 【开源毕设】一款精美的家校互动APP分享——爱吖校推 [你关注的,我们才推](持续开源更新3)附高效动态压缩Bitmap

    一.写在前面 爱吖校推如同它的名字一样,是一款校园类信息推送交流平台,这么多的家校互动类软件,你选择了我,这是我的幸运.从第一次在博客园上写博客到现在,我一次一次地提高博文的质量和代码的可读性,都是为 ...

  3. C#开发微信门户及应用(4)--关注用户列表及详细信息管理

    在上个月的对C#开发微信门户及应用做了介绍,写过了几篇的随笔进行分享,由于时间关系,间隔了一段时间没有继续写这个系列的博客了,并不是对这个方面停止了研究,而是继续深入探索这方面的技术,为了更好的应用起 ...

  4. .NET开发人员值得关注的七个开源项目 .

    NET开发人员值得关注的七个开源项目 软近几年在.NET社区开源项目方面投入了相当多的时间和资源,不禁让原本对峙的开源社区阵营大吃一惊,从微软.NET社区中的反应来看,微软.NET开发阵营对开源工具的 ...

  5. [从产品角度学EXCEL 00]-为什么要关注EXCEL的本质

    前言 Hello 大家好,我是尾巴,从今天开始,在这里连载<从产品角度学EXCEL>的系列文章.本文不接受无授权转载,如需转载,请先联系我,非常感谢. 与世面上的大部分EXCEL教程不同的 ...

  6. C# asp.net 搭建微信公众平台(可实现关注消息与消息自动回复)的代码以及我所遇到的问题

    [引言] 利用asp.net搭建微信公众平台的案例并不多,微信官方给的案例是用PHP的,网上能找到的代码很多也是存在着这样那样的问题或者缺少部分方法,无法使用,下面是我依照官方文档写的基于.net 搭 ...

  7. [已招满,谢谢关注]Sogou招聘C#开发人员,有意者请进

    职位名称:c#开发工程师 工作地点:搜狐网络大厦 职责:搜狗商业平台桌面产品 职位要求: 1. 计算机或者相关专业本科或以上学历 2. 精通c#,两年以上实际项目开发经验 3. 熟悉C/S开发架构和设 ...

  8. Worktile协同特色之一:无处不在的关注

    团队沟通中常见问题 在回答这个问题之前,我们不妨先来思考一下,团队成员之间互相配合沟通的几个问题:1. 任务的执行者在完成这个任务时,如何通知到此任务相关联的其他成员,比如该任务的后续任务执行者?2. ...

  9. fir.im Weekly - 除了新 MacBook Pro,近期值得关注的移动开发好资源

    最近,最引人瞩目的莫过于 Apple 产品发布会,MacBook Pro 的更新可能是四年来变化最大的一版.除了更轻.更薄.性能更好.电力更足之外,最大的变化是加入了Touch Bar,被定义为 Ma ...

随机推荐

  1. HttpListener Start 拒绝访问

    HttpListener Start 拒绝访问 以管理员权限运行cmd 输入: netsh http add urlacl url=http://127.0.0.1:8080/ user=HuQing

  2. swift 第三方库迁移错误解决“Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choo

    先看看错误提示 这里Alamofire库报错,原因打开工程会Xcode会提示你覆盖到最新的3.0版本.但是仍然有些框架会出现一些问题 解决办法: 选择Pods - ReactiveCocoa - Sw ...

  3. @vue/cli 3.x项目脚手架 webpack 配置

    @vue/cli  是一个基于 Vue.js 进行快速开发的完整系统. @vue/cli   基于node服务  需要8.9以上版本 可以使用 nvm等工具来控制node版本  构建于 webpack ...

  4. rest_framework组件之认证,权限,访问频率

    共用的models from django.db import models # Create your models here. class User(models.Model): username ...

  5. TCP的三次握手以及TCP状态转换图详解

    今天来讨论一下TCP的三次握手以及TCP的状态转换图.首先发一个三次握手的流程图如下: 圖 2.4-3.三向交握之封包连接模式A:封包发起当用戶端想要对服务器端发起连接时,就必須要送出一個要求连线的封 ...

  6. 对卷积(convolution)的理解

    参考文章 https://www.jianshu.com/p/daaaeb718aed https://blog.csdn.net/bitcarmanlee/article/details/54729 ...

  7. js操作文档对象的节点

    好吧,为了能让大家不至于睡着,我们先回顾先前面的东东吧~ 1.首先我们写了javaScriput的是一门弱类型的解释性的脚本语言:弱类型:我们的变量不用申明其具体的数据类型,在使用的时候浏览器根据其存 ...

  8. External Pricing in C4C and ERP

    从下图可以看出,C4C的Opportunity,Sales Quote和Sales Order这些business transaction没有自己的pricing engine,使用的是在ERP Pr ...

  9. 如何处理SAP云平台错误消息 there is no compute unit quota for subaccount

    当我试图部署一个应用到SAP云平台的neo环境时: 指定Compute Unit Size为Lite: 点击Deploy按钮,遇到如下错误消息:there is no compute unit quo ...

  10. oracle的clob转换varchar2

    time: 2008/02/29 author: skate oracle的clob转换varchar2 今天在做一个表的数据转移的时候,发现要他通过比较clob字段,但大家都知道clob字段是无法比 ...