Flask框架 之 学生管理分析

先看模板吧。

index.html

<body>
    <h1>学生列表</h1>
    <table border="1">
        <thead>
            <tr>
                <th>ID</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>选项</th>
            </tr>
        </thead>
        <tbody>
            {% for k,v in  stu_dic.items() %}
                <tr>
                    <td>{{k}}</td>
                    <td>{{v.name }}</td>
                    <td>{{v.age}}</td>
                    <td>{{v.gender}}</td>
                    <td>
                        <a href="/detail/{{k}}">查看详细</a>
                        |
                        <a href="/delete/{{k}}">删除</a>

                    </td>
                </tr>
            {% endfor %}
        </tbody>
    </table>

detail.html  

<body>
    <h1>学生详细</h1>
    <ul>

        {% for item in info.values() %}
        <li>{{item}}</li>
        {% endfor %}
    </ul>
</body>

app.py  

from flask import Flask,render_template,request,redirect,session,url_for,jsonify,make_response,Markup,flash,get_flashed_messages

app = Flask(__name__)

STUDENT_DICT = {
    1:{'name':'王龙泰','age':38,'gender':'中'},
    2:{'name':'小东北','age':73,'gender':'男'},
    3:{'name':'田硕','age':84,'gender':'男'},
} 

我们如何对这些数据进行操作呢?

@app.route('/index')
def index():
    print('index')
    return render_template('index.html',stu_dic=STUDENT_DICT)

@app.route('/delete/<int:nid>')  #指定为Int,否则为str
def delete(nid):
    del STUDENT_DICT[nid]
    return redirect(url_for('index'))

@app.route('/detail/<int:nid>')
def detail(nid):
    info = STUDENT_DICT[nid]
    return render_template('detail.html',info=info)

后台管理是随便可以看的吗?是不是应该先登录后进行操作呢?

@app.route('/login',methods=["GET","POST"])
def login():
    print('login')
    if request.method == 'GET':
        return render_template('login.html')
    user = request.form.get('user')
    pwd = request.form.get('pwd')
    if user == 'oldboy' and pwd == '666':
        session['user'] = user      #存入session
        return redirect('/index')
    return render_template('login.html',error='用户名或密码错误')  

不要忘了存入session需要加盐。app.secret_key="xxxxx"

然后呢?

从session中取到随机字符串,判断是否登录。每个操作都要校验,每个函数都要加(以index为例)。

版本一:

@app.route('/index')
def index():
	if not session.get('user'):
		return redirect(url_for('login'))
	return render_template('index.html',stu_dic=STUDENT_DICT)

每个函数都要加,是不是太麻烦了。我们可以写个装饰器。

版本二:

#装饰器
def auth(func):
				
	def inner(*args,**kwargs):
		if not session.get('user'):
			return redirect(url_for('login'))
		ret = func(*args,**kwargs)
		return ret
	return inner
		
@app.route('/index')
@auth
def index():
	return render_template('index.html',stu_dic=STUDENT_DICT)   

结果你发现会报错。

这是因为每个函数执行装饰器,函数名都会变为inner,重名出错不是很正常吗?关键是我们如何解决?

这里就用到了functools模块。

这个模块加入装饰器,我们执行函数时,虽然看似是inner,但本质是各函数名。

这样就解决了这个问题。可是如果用到装饰器的地方少,可以这样写,如果多呢?我们总不能还是每个函数都加。

装饰器应用场景:比较少的函数中需要额外添加功能。

注意:以后写装饰器时,都要记得使用functools模块。

版本三:

我们需要写一个函数,这个函数执行代表所有的操作,下面的操作就可以简单明了。

before_request装饰的这个函数,在我们的视图函数执行之前,无论哪个请求,都会先执行一下。就跟django中间件中的process_request有点像。每个请求进来都要经过它。

所以在要操作的函数之前再写一个函数。

@app.before_request
def xxxxxx():
	if request.path == '/login':
		return None    #可以通过

	if session.get('user'):
		return None    #已登录,可以通过

	return redirect('/login')  #否则,回到登录页面  

这种方法使用于批量添加操作时。 

posted @ 2018-06-23 20:01  高~雅  阅读(906)  评论(0编辑  收藏  举报