结合作者的教程,也是加了个人的总结与精炼,源作者github:https://github.com/CoreyMSchafer/code_snippets/tree/master/Python/Flask_Blog/03-Forms-and-Validation
#01
@app.route("/login", methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
if form.email.data == 'admin@blog.com' and form.password.data == 'password':
flash('You have been logged in!', 'success')
return redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check username and password', 'danger')
return render_template('login.html', title='Login', form=form)
@app.route("/login", methods=[‘GET’, ‘POST’]),表示请求方法的路径及允许的方法,下面定义了一个名叫login的方法。form = LoginForm(),表示生成一个loginform类的实例,也就是一张含有登录数据的表单。
紧接着,来一个判断,如果提交了并且邮箱和密码都符合我写死的数据,则输出一个信息 flash(‘You have been logged in!’, ‘success’),然后,重定向到home页面;如果,数据不对,那就也返回一个错误的信息。
#02
posts = [
{
'author': 'Corey Schafer',
'title': 'Blog Post 1',
'content': 'First post content',
'date_posted': 'April 20, 2018'
},
{
'author': 'Jane Doe',
'title': 'Blog Post 2',
'content': 'Second post content',
'date_posted': 'April 21, 2018'
}
]
数据在前期可以写死,写成字典的形式,像以上这样。
#03 templates
关于templates文件夹,这个文件夹的名字是不能乱改的,里面就是我们熟知html页面。但是页面多的话要每个都老老实实的写吗?答案显然不是,这里我们定义一个页面让它成为一个模板,就是说其他页面都可以利用或者说依赖这个模板页面。
姑且叫模板页面为layout.html,其他页面如home,about等等,这些页面往模板里面注入数据,我们把这些页面叫做活页面。
这是一个名叫about的活页面,第一行表示继承了模板页面layout,下面的block,endblock,里面就是填活数据的地方。
以下,就是两个活页面。
About.html:简单的。
{% extends "layout.html" %}
{% block content %}
<h1>About Page</h1>
{% endblock content %}
login.html:较复杂,登录表单就这样写。
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{
{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Log In</legend>
<div class="form-group">
{
{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{
{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{
{ error }}</span>
{% endfor %}
</div>
{% else %}
{
{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{
{ form.password.label(class="form-control-label") }}
{% if form.password.errors %}
{
{ form.password(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<span>{
{ error }}</span>
{% endfor %}
</div>
{% else %}
{
{ form.password(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-check">
{
{ form.remember(class="form-check-input") }}
{
{ form.remember.label(class="form-check-label") }}
</div>
</fieldset>
<div class="form-group">
{
{ form.submit(class="btn btn-outline-info") }}
</div>
<small class="text-muted ml-2">
<a href="#">Forgot Password?</a>
</small>
</form>
</div>
<div class="border-top pt-3">
<small class="text-muted">
Need An Account? <a class="ml-2" href="{
{ url_for('register') }}">Sign Up Now</a>
</small>
</div>
{% endblock content %}
再来看看模板页面长啥样,就是写的最完整的页面,仔细看,里面也有一对block,endblock,这里正好与上面的一致,是巧合吗?嘿嘿,显然不是,这里就是活数据要传的地方。
如果写页面的话,只需关注不一样的地方即活数据,剩下的引用公共的模板页面即可。
<!DOCTYPE html>
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="{
{ url_for('static', filename='main.css') }}">
{
% if title %}
<title>Flask Blog - {
{
title }}</title>
{
% else %}
<title>Flask Blog</title>
{
% endif %}
</head>
<body>
<header class="site-header">
<nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
<div class="container">
<a class="navbar-brand mr-4" href="/">Flask Blog</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarToggle">
<div class="navbar-nav mr-auto">
<a class="nav-item nav-link" href="{
{ url_for('home') }}">Home</a>
<a class="nav-item nav-link" href="{
{ url_for('about') }}">About</a>
</div>
<!-- Navbar Right Side -->
<div class="navbar-nav">
<a class="nav-item nav-link" href="{
{ url_for('login') }}">Login</a>
<a class="nav-item nav-link" href="{
{ url_for('register') }}">Register</a>
</div>
</div>
</div>
</nav>
</header>
<main role="main" class="container">
<div class="row">
<div class="col-md-8">
{
% with messages = get_flashed_messages(with_categories=true) %}
{
% if messages %}
{
% for category, message in messages %}
<div class="alert alert-{
{ category }}">
{
{
message }}
</div>
{
% endfor %}
{
% endif %}
{
% endwith %}
{
% block content %}{
% endblock %}
</div>
<div class="col-md-4">
<div class="content-section">
<h3>Our Sidebar</h3>
<p class='text-muted'>You can put any information here you'd like.
<ul class="list-group">
<li class="list-group-item list-group-item-light">Latest Posts</li>
<li class="list-group-item list-group-item-light">Announcements</li>
<li class="list-group-item list-group-item-light">Calendars</li>