表的模型实现

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. SpringMVC注解方式与文件上传

    目录: springmvc的注解方式 文件上传(上传图片,并显示) 一.注解 在类前面加上@Controller 表示该类是一个控制器在方法handleRequest 前面加上 @RequestMap ...

  2. Eucalyptus——EC2的开源实现(转载)

    Eucalyptus[22]是加利福尼亚大学的 Daniel Nurmi 等人实现的,是一个用于实现云计算的开源软件基础设施.Eucalyptus 是 Amazon EC2 的一个开源实现,它与 EC ...

  3. Beginning Python Chapter 2 Notes

    Python基本数据类型用Python官方说法应该叫Python内建数据类型,英文叫built-in type.下面稍微总结了一下我看到过的Python内建数据类型. Python基本数据类型 数据类 ...

  4. WinForm form属性

    一.布局 Autostroll   控件内容大于可见区域是否自动显示滚动条 Maximumsize 窗体可调到最大尺寸 minimumsize  窗体可调到最小尺寸 size  窗体看到的尺寸 Sta ...

  5. 洛谷 P1345 [USACO5.4]奶牛的电信Telecowmunication

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  6. xcode技巧

    1.统计ios开发代码,包括头文件的,终端命令进入项目目录下,命令如下 find . -name "*.m" -or -name "*.h" -or -name ...

  7. SAP C4C Opportunity和SAP ERP Sales流程的集成

    首先在C4C里创建一个新的Opportunity: 给这个Opportunity添加一个新的产品: 点按钮:Request Pricing, 从ERP抓取pricing数据,点按钮之前Negotiat ...

  8. FMDB浅析(思想)

    http://www.cnblogs.com/OTgiraffe/p/5931800.html 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQLite的API进行了封装,加上了面向 ...

  9. [web开发] Vue+Spring Boot 上海大学预约系统开发记录

    前端界面 使用Quasar将组件都排好,用好css. Quasar 入门 # 确保你在全局安装了vue-cli # Node.js> = 8.9.0是必需的. $ npm install -g ...

  10. linux readahead

    blockdev --getra /dev/sda blockdev --setra 2048 /dev/sda 必须将其写入配置文件/etc/rc.local,否则重启就会失效.[root@loca ...