Flask Vue.js全栈开发|第12章:黑名单

  • 原创
  • Madman
  • /
  • 2018-11-26 09:46
  • /
  • 0
  • 60 次阅读

flask vuejs 全栈开发-min.png

Synopsis: 实现用户屏蔽其它用户,阻止对方给自己发送骚扰私信,这个功能还是有必要的,毕竟网络骚扰和暴力危害挺大的,眼不见为净

代码已上传到 https://github.com/wangy8961/flask-vuejs-madblog/tree/v0.12 ,欢迎star

1. 数据库模型

一个用户可以 拉黑/屏蔽 多个其它用户,一个用户也可以被多个其它用户拉黑,所以是 自引用多对多 关系

修改 back-end/app/models.py

# 黑名单(user_id 屏蔽 block_id)
blacklist = db.Table(
    'blacklist',
    db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('block_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('timestamp', db.DateTime, default=datetime.utcnow)
)


class User(PaginatedAPIMixin, db.Model):
    ...
    # harassers 骚扰者(被拉黑的人)
    # sufferers 受害者
    harassers = db.relationship(
        'User', secondary=blacklist,
        primaryjoin=(blacklist.c.user_id == id),
        secondaryjoin=(blacklist.c.block_id == id),
        backref=db.backref('sufferers', lazy='dynamic'), lazy='dynamic')
    ...
    def is_blocking(self, user):
        '''判断当前用户是否已经拉黑了 user 这个用户对象,如果拉黑了,下面表达式左边是1,否则是0'''
        return self.harassers.filter(
            blacklist.c.block_id == user.id).count() > 0

    def block(self, user):
        '''当前用户开始拉黑 user 这个用户对象'''
        if not self.is_blocking(user):
            self.harassers.append(user)

    def unblock(self, user):
        '''当前用户取消拉黑 user 这个用户对象'''
        if self.is_blocking(user):
            self.harassers.remove(user)

数据库迁移:

(venv) D:\python-code\flask-vuejs-madblog\back-end>flask db migrate -m "add blacklist"
(venv) D:\python-code\flask-vuejs-madblog\back-end>flask db upgrade

2. API

修改 back-end/app/api/users.py

2.1 Block User

@bp.route('/block/<int:id>', methods=['GET'])
@token_auth.login_required
def block(id):
    '''开始拉黑一个用户'''
    user = User.query.get_or_404(id)
    if g.current_user == user:
        return bad_request('You cannot block yourself.')
    if g.current_user.is_blocking(user):
        return bad_request('You have already blocked that user.')
    g.current_user.block(user)
    db.session.commit()
    return jsonify({
        'status': 'success',
        'message': 'You are now blocking %s.' % (user.name if user.name else user.username)
    })

2.2 Unblock User

@bp.route('/unblock/<int:id>', methods=['GET'])
@token_auth.login_required
def unblock(id):
    '''取消拉黑一个用户'''
    user = User.query.get_or_404(id)
    if g.current_user == user:
        return bad_request('You cannot unblock yourself.')
    if not g.current_user.is_blocking(user):
        return bad_request('You are not blocking this user.')
    g.current_user.unblock(user)
    db.session.commit()
    return jsonify({
        'status': 'success',
        'message': 'You are not blocking %s anymore.' % (user.name if user.name else user.username)
    })

3. 前端拉黑/取消拉黑

用户可以在 收到的新私信 提醒页面,拉黑其它用户或取消拉黑

修改 front-end/src/components/Notifications/Messages/List.vue 组件:

<template>
  <div>
    ...
    <li v-if="!message.is_blocking" class="list-inline-item g-mr-5">
      <button v-on:click="onBlock(message.sender.id)" class="btn btn-block u-btn-outline-red g-rounded-20 g-px-10">拉黑</button>
    </li>
    <li v-else class="list-inline-item g-mr-5">
      <button v-on:click="onUnblock(message.sender.id)" class="btn btn-block u-btn-outline-aqua g-rounded-20 g-px-10">取消拉黑</button>
    </li>
  </div>
</template>

<script>
  ...
export default {
  ...
  methods: {
    ...
    onBlock (id) {
      this.$swal({
        title: "Are you sure?",
        type: "warning",
        showCancelButton: true,
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: 'Yes, block he!',
        cancelButtonText: 'No, cancel!'
      }).then((result) => {
        if(result.value) {
          const path = `/api/block/${id}`
          this.$axios.get(path)
            .then((response) => {
              // handle success
              this.$swal('Successed', response.data.message, 'success')
              this.getUserMessagesSenders(this.sharedState.user_id)
            })
            .catch((error) => {
              // handle error
              console.log(error.response.data)
              this.$toasted.error(error.response.data.message, { icon: 'fingerprint' })
            })
        } else {
          this.$swal('Cancelled', 'You are not blocking this user yet :)', 'error')
        }
      })
    },
    onUnblock (id) {
      const path = `/api/unblock/${id}`
      this.$axios.get(path)
        .then((response) => {
          // handle success
          this.$swal('Successed', response.data.message, 'success')
          this.getUserMessagesSenders(this.sharedState.user_id)
        })
        .catch((error) => {
          // handle error
          console.log(error.response.data)
          this.$toasted.error(error.response.data.message, { icon: 'fingerprint' })
        })
    }
  }
}
</script>

怎么判断你当前有没有拉黑一个用户呢?后端修改 back-end/app/api/users.py 中的 get_user_messages_senders ()

@bp.route('/users/<int:id>/messages-senders/', methods=['GET'])
@token_auth.login_required
def get_user_messages_senders(id):
    ...
    for item in data['items']:
        # 判断我有没有拉黑他
        if user.is_blocking(User.query.get(item['sender']['id'])):
            item['is_blocking'] = True
    ...

4. 限制被拉黑者发送私信

比如,用户 B 被用户 A 拉黑了,那么用户 B 再也无法发送骚扰私信给用户 A

修改 back-end/app/api/messages.py 中的 create_message()

@bp.route('/messages/', methods=['POST'])
@token_auth.login_required
def create_message():
    ...
    if user.is_blocking(g.current_user):
        return bad_request('You are in the blacklist of {}'.format(user.name if user.name else user.username))
    ...

5. 提交代码

$ git add .
$ git commit -m "12. 黑名单"
$ git checkout master
$ git merge dev
$ git branch -d dev

将本地 master 分支代码上传到 Github 代码仓库中的 master 分支:

$ git push -u origin master

打上标签 tag并上传:

$ git tag v0.12
$ git push origin v0.12

代码已上传到 https://github.com/wangy8961/flask-vuejs-madblog/tree/v0.12 ,欢迎star

未经允许不得转载: LIFE & SHARE - 王颜公子 » Flask Vue.js全栈开发|第12章:黑名单

分享

作者

作者头像

Madman

如果博文内容有误或其它任何问题,欢迎留言评论,我会尽快回复; 或者通过QQ、微信等联系我

0 条评论

暂时还没有评论.

发表评论前请先登录