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

21次阅读
没有评论

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() }}
  <span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span>></span><span class="css">
    <span class="hljs-selector-class">.important</span> { <span class="hljs-attribute">color</span>: <span class="hljs-number">#336699</span>; }
  </span><span class="hljs-tag"></<span class="hljs-name">style</span>></span>
{% endblock %}
{% block content %}
  <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>About<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"important"</span>></span>
    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 %}
<span class="copy-code-btn">复制代码</span>

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

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

about.html

{% extends "layout.html" %}
{% block title %}Index{% endblock %}
{% block head %}
  {{ super() }}
  <span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span>></span><span class="css">
    <span class="hljs-selector-class">.important</span> { <span class="hljs-attribute">color</span>: <span class="hljs-number">#336699</span>; }
  </span><span class="hljs-tag"></<span class="hljs-name">style</span>></span>
{% endblock %}
{% block content %}
  <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>About<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"important"</span>></span>
    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 %}
<span class="copy-code-btn">复制代码</span>

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

更多Flask模板的使用可以看这里https://flask.palletsprojects.com/en/1.1.x/patterns/templateinheritance/

创建404页面

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

not_found.html

{% extends 'layout.html' %} 
{% block title %}Page Not Found{% endblock %}
{% block content %}
  <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>Page Not Found<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"important"</span>></span>
    Sorry, this page does not exist!
{% endblock %}
<span class="copy-code-btn">复制代码</span>

server.py

<span class="hljs-meta">@app.errorhandler(<span class="hljs-params"><span class="hljs-number">404</span></span>)</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">page_not_found</span>(<span class="hljs-params">error</span>):</span>
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">'not_found.html'</span>), <span class="hljs-number">404</span>
<span class="copy-code-btn">复制代码</span>

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

添加帖子

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

post.py

<span class="hljs-keyword">import</span> os

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_all_post_names</span>():</span>
    <span class="hljs-keyword">try</span>:
        post_files = os.listdir(<span class="hljs-string">'templates/posts'</span>)
        post_names = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">map</span>(<span class="hljs-keyword">lambda</span> x: x.split(<span class="hljs-string">'.'</span>)[<span class="hljs-number">0</span>], post_files))
        <span class="hljs-keyword">return</span> post_names
    <span class="hljs-keyword">except</span>:
        print(<span class="hljs-string">'An error occurred while fetching posts'</span>)
        <span class="hljs-keyword">return</span> []
<span class="copy-code-btn">复制代码</span>
{% extends <span class="hljs-string">"layout.html"</span> %} 
{% block title %}Index{% endblock %} 
{% block head%}
{{ <span class="hljs-built_in">super</span>() }}
 {% endblock %} 
{% block content %}

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

{% <span class="hljs-title">endblock</span> %}
</span><span class="copy-code-btn">复制代码</span>

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

<span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/posts/<string:post_name>'</span></span>)</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">show_post</span>(<span class="hljs-params">post_name</span>):</span>
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">f'posts/<span class="hljs-subst">{post_name}</span>.html'</span>)
<span class="copy-code-btn">复制代码</span>

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

生成一个requirement.txt文件

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

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

$ pip freeze > requirements.txt
<span class="copy-code-btn">复制代码</span>

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

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

参考链接

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

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

原文链接

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

admin
版权声明:本站原创文章,由admin2021-01-08发表,共计3346字。
转载提示:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。