(翻译)30天学习Python👨‍💻第二十五天——Web开发基础2

417 阅读4分钟

30天学习Python👨‍💻第二十五天——Web开发基础2

从Flask应用的基本结构开始,今天我实现了一些基础的功能来完善我们极简的博客应用。首先使用flask模板继承模式,我复用了通用模板的代码,并且添加了两篇虚拟的帖子来动态渲染它们。最后,生成了一个requirements.txt文件将所有的包依赖存储在一个文件中,这样就可以使用只使用一条命令下载所需要的所有包。

模板继承

现在,index.htmlabout.html模板包含了重复的HTML代码。因为Flask使用了Jinja作为模板引擎,我们可以使用模板继承的强大能力,创建一个包含所有通用HTML代码的基础模板,比如HTML骨架、导航栏、通用底部样式等。其他模板可以继承这个基础模板,这样可以使我们代码的重用性更高。如下我创建了一个基础的模板文件layout.html来包含通用的模板结构。

layout.html

{% extends "layout.html" %}
{% block title %}Index{% endblock %}
{% block head %}
  {{ super() }}
  <style type="text/css">
    .important { color: #336699; }
  </style>
{% endblock %}
{% block content %}
  <h1>About</h1>
  <p class="important">
    Hi. I am Arindam. I love building User Interfaces. I am currently learning
    Python and created this simple blog using the Flask web development
    framework.
{% endblock %}

创建可重复使用的模板块,该块的代码需要放在{% block block_name %}``{% endblock %}中。{% block %}通知模板引擎子模板可以覆盖模板的这些部分。

其他文件可以像这样继承这个基础模板

about.html

{% extends "layout.html" %}
{% block title %}Index{% endblock %}
{% block head %}
  {{ super() }}
  <style type="text/css">
    .important { color: #336699; }
  </style>
{% endblock %}
{% block content %}
  <h1>About</h1>
  <p class="important">
    Hi. I am Arindam. I love building User Interfaces. I am currently learning
    Python and created this simple blog using the Flask web development
    framework.
{% endblock %}

这里super()用于呈现父模板中定义的块的内容。

更多Flask模板的使用可以看这里flask.palletsprojects.com/en/1.1.x/pa…

创建404页面

在Flask中我们可以处理各种各样的异常,当路由找不到时,加载从服务器获取的资源时会显示一个自定义的404页面,当服务器内部500错误时会显示一个自定义的页面等等。我创建了一个简单的not_found.html文件当路由找不到的时候会把这个文件渲染出来。

not_found.html

{% extends 'layout.html' %} 
{% block title %}Page Not Found{% endblock %}
{% block content %}
  <h1>Page Not Found</h1>
  <p class="important">
    Sorry, this page does not exist!
{% endblock %}

server.py

@app.errorhandler(404)
def page_not_found(error):
    return render_template('not_found.html'), 404

更多关于Flaks错误处理的内容请看这里ttps://flask.palletsprojects.com/en/1.1.x/patterns/errorpages/

添加帖子

类似的,我在模板目录内部创建了一个帖子文件夹,并且创建了两个假的帖子文件first-post.htmlsecond-post.html。然后我创建类一个posts.py文件来读取所有的帖子文件,并且将文件名称存储在一个列表中,在主页面可以把它渲染出来。

post.py

import os

def get_all_post_names():
    try:
        post_files = os.listdir('templates/posts')
        post_names = list(map(lambda x: x.split('.')[0], post_files))
        return post_names
    except:
        print('An error occurred while fetching posts')
        return []
{% extends "layout.html" %} 
{% block title %}Index{% endblock %} 
{% block head%}
{{ super() }}
 {% endblock %} 
{% block content %}

<h1 class="title">
  Welcome to the Python Blog.
</h1>
<h2>Recent Posts</h2>
<ul class="post-list">
  {% for post in post_names %}
  <li><a href="posts/{{post}}.html">{{post}}</a></li>
  {% endfor %}
</ul>

{% endblock %}

按照Jinja的模板语法,所有的Python语句都应该被写在{% %}块中。动态值写入{{ }}中。现在我们应该在主页面能够看到两篇文章。现在当我们点击一篇文章时,它应该打开相应的文章页面。我们必须创建一个动态处理文章页面的路由。

@app.route('/posts/<string:post_name>')
def show_post(post_name):
    return render_template(f'posts/{post_name}.html')

这个路由将会处理页面名称,并且动态的渲染出来各自的文章页面。

生成一个requirement.txt文件

在Python项目中,我们会使用很多第三方的包。如果我们想把这个项目分享给其他人,我们需要分享整个项目文件,以及运行这个项目所需要的所有包的正确版本。这并不是很实用。

在项目中使用的下载的依赖都会列入一个单独的requirement.txt文件中(按照惯例),并使用下面的命令可以列出它们的版本

$ pip freeze > requirements.txt

这将为项目生成requirement.txt文件。这个文件可以上传到任意的GIT仓库。当有人下载这个项目时,它们只需要运行pip install -r requirement.txt文件,所有的项目依赖都会以正确的版本自动的下载。

这个项目的完整代码可以在 这里找到

参考链接

上面的项目是使用Python创建web应用的一个非常小的示例。我在下面列出了一些进一步探索的链接

这就是今天的全部了。这个系列剩下的部分,我会探索一些高级主题,比如机器学习和数据科学基础。

原文链接

30 Days of Python 👨‍💻 - Day 25 - Web Development Extras