zoukankan      html  css  js  c++  java
  • Python框架之Django学习笔记(十六)

    Django框架之表单(续)

      今天简直无力吐槽了,去了香山,结果和网上看到的简直是天壤之别啊,说好的香山的枫树呢?说好的香山的红叶呢?说好的漫山遍野一片红呢?本以为在山上,一口气爬上去,沿路基本都是翠绿的松柏,松柏啊亲,难道我不仅红绿色盲,还是一个松枫不辨星人!更坑爹的是回来的时候,排队等公交等了近三个小时,你说为什么不自驾游?没办法,穷人开不起撒。总之,一句话总结香山之旅:

      如果你恨他/她,就让他/她周末去香山吧,如果他/她爱你,就让他/她周末带你去香山吧!恩,闲扯到此为止,虽然挺累,不过学习还是要接着进行滴,况且学习本就需要坚持,没点点毅力,三天打鱼,两天晒网,哪能学到什么东西呢。

    表单改进

      首先,我们在基于上次的基础上,对表单进行一些小的改进,上次的search()视图对于空字符串的处理相当薄弱——仅显示一条”Please submit a search term.”的提示信息。 若用户要重新填写表单必须自行点击“后退”按钮, 这种做法既糟糕又不专业。如果在现实的案例中,我们这样子编写,那么Django的优势将荡然无存。

      在检测到空字符串时更好的解决方法是重新显示表单,并在表单上面给出错误提示以便用户立刻重新填写。 最简单的实现方法既是添加else分句重新显示表单,代码如下:

     1 from django.http import HttpResponse
     2 from django.shortcuts import render_to_response
     3 from books.models import Book
     4 
     5 def search_form(request):
     6     return render_to_response('search_form.html')
     7 
     8 def search(request):
     9     if 'q' in request.GET and request.GET['q']:
    10         q = request.GET['q']
    11         books = Book.objects.filter(title__icontains=q)
    12         return render_to_response('search_results.html',
    13             {'books': books, 'query': q})
    14     else:
    15         **return render_to_response('search_form.html', {'error': True})**

       PS:将search_form()视图也包含进来以便查看

      这段代码里,我们改进来search()视图:在字符串为空时重新显示search_form.html。 并且给这个模板传递了一个变量error,记录着错误提示信息。 现在我们编辑一下search_form.html,检测变量error:  

     1 <html>
     2 <head>
     3     <title>Search</title>
     4 </head>
     5 <body>
     6     **{% if error %}**
     7         **<p style="color: red;">Please submit a search term.</p>**
     8     **{% endif %}**
     9     <form action="/search/" method="get">
    10         <input type="text" name="q">
    11         <input type="submit" value="Search">
    12     </form>
    13 </body>
    14 </html>

       我们修改了search_form()视图所使用的模板,因为search_form()视图没有传递error变量,所以在条用search_form视图时不会显示错误信息。

      通过上面的一些修改,现在程序变的好多了,但是现在出现一个问题: 是否有必要专门编写search_form()来显示表单? 按实际情况来说,当一个请求发送至/search/(未包含GET的数据)后将会显示一个空的表单(带有错误信息)。 所以,只要我们改变search()视图:当用户访问/search/并未提交任何数据时就隐藏错误信息,这样就移去search_form()视图以及对应的URLpattern。 

     1 def search(request):
     2     error = False
     3     if 'q' in request.GET:
     4         q = request.GET['q']
     5         if not q:
     6             error = True
     7         else:
     8             books = Book.objects.filter(title__icontains=q)
     9             return render_to_response('search_results.html',
    10                 {'books': books, 'query': q})
    11     return render_to_response('search_form.html',
    12         {'error': error}) 

       在改进后的视图中,若用户访问/search/并且没有带有GET数据,那么他将看到一个没有错误信息的表单; 如果用户提交了一个空表单,那么它将看到错误提示信息,还有表单; 最后,若用户提交了一个非空的值,那么他将看到搜索结果。

      最后,我们再稍微改进一下这个表单,去掉冗余的部分。 既然已经将两个视图与URLs合并起来,/search/视图管理着表单的显示以及结果的显示,那么在search_form.html里表单的action值就没有必要硬编码的指定URL。 原先的代码是这样: 

    1 <form action="/search/" method="get">

       现在改成这样:

    1 <form action="" method="get">

       action=”“意味着表单将提交给与当前页面相同的URL。 这样修改之后,如果search()视图不指向其它页面的话,你将不必再修改action

    简单的验证

      我们的搜索示例仍然相当地简单,特别从数据验证方面来讲;我们仅仅只验证搜索关键值是否为空。 然后许多HTML表单包含着比检测值是否为空更为复杂的验证。 我们都有在网站上见过类似以下的错误提示信息:

    • 请输入一个有效的email地址, foo’ 并不是一个有效的e-mail地址。
    • 请输入5位数的U.S 邮政编码, 123并非是一个有效的邮政编码。
    • 请输入YYYY-MM-DD格式的日期。
    • 请输入8位数以上并至少包含一个数字的密码。

      我们来调整一下search()视图,让她能够验证搜索关键词是否小于或等于20个字符。 (为来让例子更为显著,我们假设如果关键词超过20个字符将导致查询十分缓慢)。那么该如何实现呢? 最简单的方式就是将逻辑处理直接嵌入到视图里,就像这样:

     1 def search(request):
     2     error = False
     3     if 'q' in request.GET:
     4         q = request.GET['q']
     5         if not q:
     6             error = True
     7         **elif len(q) > 20:**
     8             **error = True**
     9         else:
    10             books = Book.objects.filter(title__icontains=q)
    11             return render_to_response('search_results.html',
    12                 {'books': books, 'query': q})
    13     return render_to_response('search_form.html',
    14         {'error': error})

      现在,如果尝试着提交一个超过20个字符的搜索关键词,系统不会执行搜索操作,而是显示一条错误提示信息。 但是,search_form.html里的这条提示信息是:”Please submit a search term.”,这显然是错误的, 所以我们需要更精确的提示信息:

     1 <html>
     2 <head>
     3     <title>Search</title>
     4 </head>
     5 <body>
     6     {% if error %}
     7         <p style="color: red;">Please submit a search term 20 characters or shorter.</p>
     8     {% endif %}
     9     <form action="/search/" method="get">
    10         <input type="text" name="q">
    11         <input type="submit" value="Search">
    12     </form>
    13 </body>
    14 </html>

      但像这样修改之后仍有一些问题。 我们包含万象的提示信息很容易使人产生困惑: 提交一个空表单怎么会出现一个关于20个字符限制的提示? 所以,提示信息必须是详细的,明确的,不会产生疑议。

      问题的实质在于我们只使用来一个布尔类型的变量来检测是否出错,而不是使用一个列表来记录相应的错误信息。 我们需要做如下的调整:

     1 def search(request):
     2     **errors = []**
     3     if 'q' in request.GET:
     4         q = request.GET['q']
     5         if not q:
     6             **errors.append('Enter a search term.')**
     7         elif len(q) > 20:
     8             **errors.append('Please enter at most 20 characters.')**
     9         else:
    10             books = Book.objects.filter(title__icontains=q)
    11             return render_to_response('search_results.html',
    12                 {'books': books, 'query': q})
    13     return render_to_response('search_form.html',
    14         {**'errors': errors** })

      接着,我们要修改一下search_form.html模板,现在需要显示一个errors列表而不是一个布尔判断。

     1 <html>
     2 <head>
     3     <title>Search</title>
     4 </head>
     5 <body>
     6     **{% if errors %}**
     7         **<ul>**
     8             **{% for error in errors %}**
     9             **<li>{{ error }}</li>**
    10             **{% endfor %}**
    11         **</ul>**
    12     **{% endif %}**
    13     <form action="/search/" method="get">
    14         <input type="text" name="q">
    15         <input type="submit" value="Search">
    16     </form>
    17 </body>
    18 </html>
    评论
  • 相关阅读:
    Algorithm Of Swift -- 4.合并两个有序数组
    Algorithm Of Swift -- 3.链表反转
    Algorithm Of Swift -- 2.字符串反转
    Algorithm Of Swift -- 1.两数之和
    1850984: Fix: crash when running am.jar without parameters
    微信公众号关联小程序,实现消息推送。
    NPOI根据Excel数据导入导出到Datatable中--帮助类
    OpenCvSharp+ZXing实现多个DataMatrix解析
    多数据源导致事务不生效
    android theme之Material的默认色和夜晚模式
  • 原文地址:https://www.cnblogs.com/voidy/p/4052953.html
Copyright © 2011-2022 走看看