11.7 其他操作

1.更好的使用枚举

我们的数据库中pending存储的是数字类型,但是我们在代码中使用的是枚举类型。这肯定是匹配不上的,一种最优雅的解决方式就是为我们的Drift模型的pending属性编写getter/setter方法

    # 状态
    _pending = Column('pending', SmallInteger, default=1)

    @property
    def pending(self):
        return PendingStatus(self._pending)

    @pending.setter
    def pending(self, status):
        self._pending = status.value

这样就能在外部使用枚举类型操作我们的属性了

2.撤销操作业务逻辑

@web.route('/drift/<int:did>/redraw')
@login_required
def redraw_drift(did):
    with db.auto_commit():
        # 横向越权:一个用户访问另一个用户的数据并进行修改
        # requester_id=current_user.id 防止横向越权
        drift = Drift.query.filter_by(
            id=did, requester_id=current_user.id).first_or_404()
        drift.pending = PendingStatus.Redraw
        current_user.beans += 1

    return redirect(url_for('web.pending'))

3.拒绝操作业务逻辑

@web.route('/drift/<int:did>/redraw')
@login_required
def redraw_drift(did):
    with db.auto_commit():
        # requester_id=current_user.id 防止超权现象
        drift = Drift.query.filter_by(
            id=did, requester_id=current_user.id).first_or_404()
        drift.pending = PendingStatus.Redraw
        current_user.beans += 1

    return redirect(url_for('web.pending'))

4.完成邮寄

@web.route('/drift/<int:did>/mailed')
def mailed_drift(did):
    with db.auto_commit():
        # 更改鱼漂状态位成功
        drift = Drift.query.filter_by(
            id=did, gifter_id=current_user.id).first_or_404()
        drift.pending = PendingStatus.Success

        # 赠送一个鱼豆
        current_user.beans += 1

        # 完成赠送
        gift = Gift.query.get_or_404(drift.gift_id)
        gift.launched = True

        # 完成心愿
        Wish.query.filter_by(
            isbn=drift.isbn, uid=drift.requester_id, launched=False)\
            .update({Wish.launched: True})
    return redirect(url_for('web.pending'))

5.撤销赠送

@web.route('/gifts/<gid>/redraw')
def redraw_from_gifts(gid):
    gift = Gift.query.filter_by(id=gid, launched=False).first_or_404()
    # 思维逻辑要严谨 
    drift = Drift.query.filter_by(gift_id=gid, pending=PendingStatus.Waiting).first()

    if drift:
        flash('这个礼物正处于交易状态,请先千万鱼漂完成该交易')
    else:
        with db.auto_commit():
            gift.delete()
            current_user.beans -= current_app.config['BEANS_UPLOAD_ONE_BOOK']

    return redirect(url_for('web.my_gifts'))

6.撤销心愿

@web.route('/wish/book/<isbn>/redraw')
def redraw_from_wish(isbn):
    wish = Wish.query.filter_by(isbn=isbn, launched=False).first_or_404()

    with db.auto_commit():
        wish.delete()

    return redirect(url_for('web.my_wish'))

7.赠送书籍

    """
        向想要这本书的人发送一封邮件
        注意,这个接口需要做一定的频率限制
        这接口比较适合写成一个ajax接口
    """
    wish = Wish.query.get_or_404(wid)
    gift = Gift.query.filter_by(uid=current_user.id, isbn=wish.isbn).first()
    if not gift:
        flash('你还没有上传此书,请点击“加入到赠送清单”添加此书。添加前,请确保自己可以赠送此书')
    else:
        send_mail(wish.user.email, '有人想送你一本书', 'email/satisify_wish.html', wish=wish,
                   gift=gift)
        flash('已向他/她发送了一封邮件,如果他/她愿意接受你的赠送,你将收到一个鱼漂')
    return redirect(url_for('web.book_detail', isbn=wish.isbn))

email/satisify_wish.html的内容

<p><stong>亲爱的 {{ wish.user.nickname }},</stong></p>
<p>{{ gift.user.nickname }} 有一本《{{ wish.book.title }}》可以赠送给你</p>
{# 将用户导向send_drift索要数据的试图函数#}
<p>点击<a
        href="{{ url_for('web.send_drift', gid=gift.id, _external=True) }}">这里</a>填写书籍邮寄地址,
    等待{{ gift.user.nickname }}将书籍寄送给你
</p>
<p>如果无法点击,你也可以将下面的地址复制到浏览器中打开:</p>
<p>{{ url_for('web.send_drift', gid=gift.id, _external=True) }}</p>
<p>你的,</p>
<p>鱼书</p>
<p>
    <small>注意,请不要回复此邮件哦</small>
</p>

Last updated