Flask小博客与Stormpath结合

开头声明,此次学习由

在公众号里面看到的一篇文章赞助,基本流程和代码都是从这里来的。而我在这里加的最主要的就是关于Stormpath的用户使用。ps:这个网站是国外的,全英文,所以学习起来还是蛮有意思的。

进入官网之前需注册:https://api.stormpath.com/register。当时注册这里密码要求让我感受到英语的重要性。

注册成功登录之后,就进入主页home,给列举了好多好多语言选择,没有使用到这里。不过看起来好像是从页面这里进行语言的选择和用户其他等。

我们首先需要做的是下载API Keys,在具体项目里面放一份自己另放一份。这里借用作者的话:“注意:不要把apiKey.properties文件检入你的版本控制系统(如果你在用的话)!这个文件存储着你的Stormpath证书,应该被妥善保管。”


然后点击create会出来让你下载api的提示,即可。这个位置存在于你登录的Stormpath用户的详情下面。之后创建的其他用户,都是在接下来这个项目里面:


Applications即为创建项目的地方,瞩目的蓝色create按钮即可创建一个,最好是和python项目名一样。

接下来点击项目名称,就会进入项目详情、用户等等的此项目页面。我们需要的是在这个项目下创建几个用户。


可以看到这些用户将在博客登录时可以完成登陆,没有存在的用户无法登陆。


对于这次项目的需求已经完成了,其他关于Stormpath的功能还有


Account是查看用户,左侧有根据条件查看的选项。


点击每一个用户都有其对应的用户详情,像这个我测试的数据也就同样保存在这块。此功能是我觉得Stormpath不错的地方之一,可以提供数据保存。当然对我们练手的来说是真极好的哟(^U^)ノ~YO

最后就是代码的实现。首先想使用Stormpath,那么首先必然是安装第三方库啦,flask-stormpath

其次就是在初始化的时候很重要

app.config['DEBUG']=True
app.config['SECRET_KEY']='some_really_long_random_string_here'
app.config['STORMPATH_API_KEY_FILE']='apiKey-2X1CWIPCBO6CPBHA9DXAVYLAK.properties'
app.config['STORMPATH_APPLICATION']='flaskr'
就是确保能链接到Stormpath的初始设置

项目的框架结构就是flaskr.py、templates、static基本的路由视图、模版和静态文件,当然这里还要加之前下载的api到项目框架里面即可。

最后的成功就是这样。

我自己加入的是,显示博客的作者。不知道为什么用user就会出现数据类型错误,遂改成了user.email,可是在模版里面用{{user}}是可以显示出登录者的名称。

最后,就附上代码。

# -*- coding: utf-8 -*-
from datetime import datetime

from flask import (
    Flask,
    abort,
    flash,
    redirect,
    render_template,
    request,
    url_for
)

from flask.ext.stormpath import (
    StormpathError,
    StormpathManager,
    User,
    login_required,
    login_user,
    logout_user,
    user
)

app=Flask(__name__)
app.config['DEBUG']=True
app.config['SECRET_KEY']='some_really_long_random_string_here'
app.config['STORMPATH_API_KEY_FILE']='apiKey-2X1CWIPCBO6CPBHA9DXAVYLAK.properties'
app.config['STORMPATH_APPLICATION']='flaskr'

stormpath_manager=StormpathManager(app)


@app.route('/')
def show_posts():
    posts=[]
    for account in stormpath_manager.application.accounts:
        if account.custom_data.get('posts'):
            posts.extend(account.custom_data['posts'])

    posts=sorted(posts,key=lambda k:k['date'],reverse=True)
    return render_template('show_posts.html',posts=posts)


@app.route('/add',methods=['POST'])
@login_required
def add_post():
    if not user.custom_data.get('posts'):
        user.custom_data['posts']=[]

    user.custom_data['posts'].append({
        'date':datetime.utcnow().isoformat(),
        'title':request.form['title'],
        'text':request.form['text'],
        'author':user.email,
    })
    user.save()
    flash(u'添加成功')
    return redirect(url_for('show_posts'))


@app.route('/login',methods=['GET','POST'])
def login():
    error=None

    if request.method=='POST':
        try:
            _user=User.from_login(
                request.form['email'],
                request.form['password'],
            )

            login_user(_user,remember=True)
            flash(u'登录成功')
            return redirect(url_for('show_posts'))
        except StormpathError,err:
            error=err.message

    return render_template('login.html',error=error)


@app.route('/logout')
def logout():
    logout_user()
    flash(u'退出登录')

    return redirect(url_for('show_posts'))


if __name__=='__main__':
    app.run()
body            { font-family: sans-serif; background: #eee; }
a, h1, h2       { color: #377ba8; }
h1, h2          { font-family: 'Georgia', serif; margin: 0; }
h1              { border-bottom: 2px solid #eee; }
h2              { font-size: 1.2em; }

.page           { margin: 2em auto; width: 35em; border: 5px solid #ccc;
                  padding: 0.8em; background: white; }
.entries        { list-style: none; margin: 0; padding: 0; }
.entries li     { margin: 0.8em 1.2em; }
.entries li h2  { margin-left: -1em; }
.add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
.add-entry dl   { font-weight: bold; }
.metanav        { text-align: right; font-size: 0.8em; padding: 0.3em;
                  margin-bottom: 1em; background: #fafafa; }
.flash          { background: #cee5F5; padding: 0.5em;
                  border: 1px solid #aacbe2; }
.error          { background: #f0d6d6; padding: 0.5em; }




<!doctype html>
<head>
  <title>Flaskr</title>
  <link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
  <div class=page>
    <h1>Flaskr</h1>
    <h>{{user}}</h>
    <div class=metanav>
    {% if user.email %}
      <a href="{{ url_for('logout') }}">log out</a>
    {% else %}
      <a href="{{ url_for('login') }}">log in</a>
    {% endif %}
    </div>
    {% for message in get_flashed_messages() %}
      <div class=flash>{{ message }}</div>
    {% endfor %}
    {% block body %}{% endblock %}
  </div>
</body>


{% extends "layout.html" %}
{% block body %}
        {% if user.email %}
        <form action="{{url_for('add_post')}}" method="post" class="add-entry">
            <dl>
                <dt>Title:
                <dd><input type="text" size=40 name="title">
                <dt>Text:
                <dd><textarea name="text" rows=5 cols=40></textarea>
                <dd><input type="submit" value="Share">
            </dl>
        </form>
        {% endif%}

<ul class="entries">
    {% for post in posts %}
        <li><h2>{{post['title']}}</h2><h2>{{post['author']}}</h2>{{post['text']|safe}}
        <br>
    {% endfor %}
</ul>
{% endblock%}


{% extends "layout.html" %}
{% block body %}
    <h2>Login</h2>
     {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
     <form action="{{ url_for('login') }}" method=post>
        <dl>
         <dt>Email:
         <dd><input type=text name=email>
         <dt>Password:
         <dd><input type=password name=password>
         <dd><input type=submit value=Login>
        </dl>
    </form>
{% endblock%}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值