表的模型实现

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. Error: Can't set headers after they are sent.

    Error: Can't set headers after they are sent. 错误:无法设置头信息后发送. 具体报错: 看到了一下代码,自己写错了 没有进行错误判断,两个条件都直接返回, ...

  2. Aspose.word组件介绍

    阅读目录 1.基本介绍 2.文档对象模型概述        本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html 本博客其他.NET开 ...

  3. nodejs 实践:express 最佳实践(八) egg.js 框架的优缺点

    nodejs 实践:express 最佳实践(八) egg.js 框架的优缺点 优点 所有的 web开发的点都考虑到了 agent 很有特色 文件夹规划到位 扩展能力优秀 缺点 最大的问题在于: 使用 ...

  4. DOM操作(二)对元素的操作(创建,追加,删除)

    1 创建新的 HTML 元素 (节点) var divDom=document.createElement('div'); 2 添加新元素到尾部 element.appendChild(para); ...

  5. java初探之初始化

    首先明确,变量初始化是在任何方法(包括构造器)被调用之前进行的. 1.实例变量的初始化 实例变量只有当它所属的类实例化后才会存在,构造器被执行就意味着对象就被创建. 1.1.指定初始化. class ...

  6. html5 新增表单控件和表单属性

    新的输入型控件 email:电子邮箱文本框,跟普通的没什么区别 当输入不是邮箱的时候,验证通不过 移动端的键盘会有变化         tel:电话号码 一般用于手机端,是一个键盘切换 url:网页的 ...

  7. Android笔记--LayoutInflator源码和使用分析

    LayoutInflator源码分析 获取LayoutInflator对象 获取LayoutInflator的方式有两种: 使用LayoutInflator.from(Context context) ...

  8. Python 中 创建类方法为什么要加self

    Python的类方法和普通的函数有一个明显的区别,在类的方法必须有一个额外的第一个参数(self),但在调用这个方法的时候不必为这个参数数值(显胜于隐的引发).在Python的类方法中这个特别的参数指 ...

  9. UVA 10382 Watering Grass (区间覆盖,贪心)

    问题可以转化为草坪的边界被完全覆盖.这样一个圆形就换成一条线段. 贪心,从中选尽量少的线段把区间覆盖,按照把线段按左端点排序,记录一个当前已经覆盖区间的位置cur, 从左端点小于等于cur选一个右端点 ...

  10. 2018.4.10 Ubuntu cat命令解答、用法

    cat命令是linux下的一个文本输出命令,通常是用于观看某个文件的内容的: cat主要有三大功能: 1.一次显示整个文件. $ cat filename 2.从键盘创建一个文件. $ cat > ...