Flask--微博客

这篇博客介绍了如何使用Python的Flask框架构建一个微博客应用,包括登录、表单验证、数据库模型、模板、分页、密码重置等功能。作者详细讲解了每个部分的实现,如使用LoginForm处理登录,定义数据库模型User和Post,以及如何实现分页和密码更改的邮箱确认过程。此外,还讨论了项目结构的组织方式,如使用blueprint进行模块化管理,并提到了Serializer在处理token令牌中的作用。
摘要由CSDN通过智能技术生成

结合作者的教程,也是加了个人的总结与精炼,源作者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>
                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值