Python的Flask框架中实现分页功能的教程

论坛 期权论坛     
niminba   2021-5-22 18:35   209   0
<p><strong>Blog Posts的提交</strong></p>
<p>让我们从简单的开始。首页上必须有一张用户提交新的post的表单。</p>
<p>首先我们定义一个单域表单对象(fileapp/forms.py):<br>
&nbsp;<br>
</p>
<div class="blockcode">
<pre class="brush:py;">
class PostForm(Form):
  post = TextField('post', validators = [Required()])
</pre>
</div>
<p>下面,我们把这个表单添加到template中(fileapp/templates/index.html):<br>
&nbsp;<br>
</p>
<div class="blockcode">
<pre class="brush:py;">
&lt;!-- extend base layout --&gt;
{% extends "base.html" %}

{% block content %}
&lt;h1&gt;Hi, {{g.user.nickname}}!&lt;/h1&gt;
&lt;form action="" method="post" name="post"&gt;
  {{form.hidden_tag()}}
  &lt;table&gt;
    &lt;tr&gt;
      &lt;td&gt;Say something:&lt;/td&gt;
      &lt;td&gt;{{ form.post(size = 30, maxlength = 140) }}&lt;/td&gt;
      &lt;td&gt;
      {% for error in form.errors.post %}
      &lt;span style="color: red;"&gt;[{{error}}]&lt;/span&gt;&lt;br&gt;
      {% endfor %}
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;/td&gt;
      &lt;td&gt;&lt;input type="submit" value="Post!"&gt;&lt;/td&gt;
      &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
&lt;/form&gt;
{% for post in posts %}
&lt;p&gt;
{{post.author.nickname}} says: &lt;b&gt;{{post.body}}&lt;/b&gt;
&lt;/p&gt;
{% endfor %}
{% endblock %}
</pre>
</div>
<p>到目前为止没啥新的东西,你可以看到,我们仅仅添加了另一表单,就像我们上一次做的那样。<br>
&nbsp;</p>
<p>最后,功能试图把所有东西都联系在一起,并被扩展来处理这个表单(fileapp/views.py):<br>
&nbsp;<br>
</p>
<div class="blockcode">
<pre class="brush:py;">
from forms import LoginForm, EditForm, PostForm
from models import User, ROLE_USER, ROLE_ADMIN, Post

@app.route('/', methods = ['GET', 'POST'])
@app.route('/index', methods = ['GET', 'POST'])
@login_required
def index():
  form = PostForm()
  if form.validate_on_submit():
    post = Post(body = form.post.data, timestamp = datetime.utcnow(), author = g.user)
    db.session.add(post)
    db.session.commit()
    flash('Your post is now live!')
    return redirect(url_for('index'))
  posts = [
    {
      'author': { 'nickname': 'John' },
      'body': 'Beautiful day in Portland!'
    },
    {
      'author': { 'nickname': 'Susan' },
      'body': 'The Avengers movie was so cool!'
    }
  ]
  return render_template('index.html',
    title = 'Home',
    form = form,
    posts = posts)
</pre>
</div>
<p>下面让我们逐一回顾一下这个功能中的变动:</p>
<ul>
  <li>&nbsp;&nbsp;&nbsp; 我们导入了Post和PostForm类</li>
  <li>&nbsp;&nbsp;&nbsp; 我们接收了来自两个路径下的index和视图的POST请求,因为那就是我们如何接收提交的请求。</li>
  <li>&nbsp;&nbsp;&nbsp; 当我们通过表单提交到功能视图后,我们会把新的Post记录录入数据库。然后就像之前做的一样,通过常规的GET请求来访问它。</li>
  <li>&nbsp;&nbsp;&nbsp; Templat会收到一条额外的内容--表单,所以它会提交给文本域。</li>
  <li></li>
</ul>
<p>在我们继续之前还有最后一点提醒:注意下面我们如何添加一条新的Post请求到数据库中:<br>
&nbsp;<br>
</p>
<div class="blockcode">
<pre class="brush:py;">
return redirect(url_for('index'))
</pre>
</div>
<p>我们可以很容易的跳过重定向,并且允许它跳到模板渲染部分,而且效率更高。因为所做的所有重定向在经过web浏览器之后,都返回到这个相同的功能视图中来。</p>
<p>所以,为什么选择重定向?考虑到当用户写下一个blog post请求之后,它只需提交然后点击浏览器刷新按钮。“Refresh”命令能做什么呢?浏览器会重新发送最后发布的请求作为一个“Refresh”命令的结果。(译者注:由于个人水平有限,如果您发现译处与原文有出入敬请指正。谢谢!)</p>
<p><br>
如果没有重定向,那么最后提交给表单的就是POST请求,所以一个“Refresh Action”会重新提交那个表单,将会导致第二次提交的post记录和第一次写入数据库中的是相同的。这样的行为Not so good.</p>
<p>若是有了重定向,我们可以强制浏览器在表单提交之后发出另一个请求,它抓取了重定向的页面。这是一个简单的“GET”请求,所以“Refresh”动作会重复“GET”请求而不是再次提交表单。</p>
<p>这个简单的小技巧避免用户在提交一个blog post请求之后,不小心刷新页面导致重复写入post请求。</p>
<p><strong>展现blog post请求</strong></p>
<p>下面我们来说点有意思的东西。我们要从数据库中抓取blog post请求并失之显示。</p>
<p>如果你回忆一下之前部分文章,我们曾创建了许多所谓“虚假的”的请求并且在首页上面显示了很长时间。这些“虚假的”对象是作为Python list在索引视图中创建的。<br>
&nbsp;<br>
</p>
<div class="blockcode">
<pre class="brush:py;">
posts = [
    {
      'author': { 'nickname': 'John' },
      'body': 'Beautiful day in Portland!'
    },
    {
      'author': { 'nickname': 'Susan' },
      'body': 'The Avengers movie was so cool!'
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP