看看大牛是怎么用Web接口开发与自动化测试基于Python语言

感觉这篇文章应该是非常实用的。现在给大家分享下。

这里推荐下我自己建的python群:595266089,不管你是小白还是大牛,小编我都挺欢迎,不定期分享干货,包括2017最新的python企业案例学习资料和零基础入门教程,欢迎初学和进阶中的小伙伴。

Ps:我下载了,但是和书中出入比较大,建议还是自己按照书码字吧。

5.1 Django-bootstrap3

Bootstrap:源于Twitter,是目前很受欢迎的前端框架。Bootstrap是基于HTML、CSS、JavaScript的,它简洁灵活,使得Web开发更加快捷。它由Twitter的设计师Mark Otto、Jacob Thornton合作开发,是一个CSS/HTML框架。Bootstrap提供了优雅的HTML和CSS规范,它由动态CSS语言Less写成。

Django-bootstrap3:是集成到Django的一个应用,使用如下命令安装:

pip install django-bootstrap3

修改/guest/settings.py文件,增加bootstrap3应用:

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'sign', 'bootstrap3',

5.2 发布会管理

5.2.1 发布会列表

修改/guest/sign/views.py文件:

# 从sign应用中导入models中的Event类from sign.models import Event# 发布会管理@login_requireddef event_manage(request):

修改/guest/sign/templates/event_manage.html文件:

<!DOCTYPE html><html>

通过页面访问效果如下:

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

5.2.2 搜索功能

搜索功能需要分别修改:html模板、url路径、views函数,如下:

修改/guest/sign/templats/event_manage.html文件:

 <!-- 发布会搜索表单 -->

修改/guest/urls.py文件:

urlpatterns = [

修改/guest/sign/views.py文件:

# 发布会名称搜索@login_requireddef search_name(request):

搜索功能:通过GET方法接收搜索关键字,并通过模糊查询,匹配发布会name字段,然后把匹配到的发布会列表返回给客户端。

5.3 嘉宾管理

嘉宾管理页面的开发与发布会管理页面基本一致!

5.3.1 嘉宾列表

首先修改/guest/sign/templates/guest_manage.html文件:

<!DOCTYPE html><html lang="zh_CN">

修改/guest/urls.py文件:

urlpatterns = [

修改/guest/sign/views.py文件:

# 从sign应用中导入models中的Guest类from sign.models import Event, Guest# 嘉宾管理@login_requireddef guest_manage(request):

给嘉宾管理页面增加搜索功能,可以完全参考上面发布会管理页面的,分别在如下文件中增加代码:

/guest/sign/templates/guest_manage.html:

 <!-- 发布会搜索表单 -->

/guest/sign/views.py:

# 嘉宾名称搜索@login_requireddef search_realname(request):

/guest/urls.py:

urlpatterns = [

5.3.2 分页器

对显示内容过多的情况下使用分页功能。

Django的分页功能Paginator类的基本功能演示:

root@TEST:/home/test/guest# python manage.py shell>>> from django.core.paginator import Paginator # 导入Paginator类>>> from sign.models import Guest # 导入sign应用models下的Guest表>>> guest_list = Guest.objects.all() # 获取guest的全部数据>>> p = Paginator(guest_list,2) # 创建每页2条数据的分页器>>> p.count # 查看共有多少条数据6>>> p.page_range # 查看公有多少分页(每页2条数据,循环结果为1、2、3,共3页)xrange(1, 4)>>> page1 = p.page(1) # 获取第1页数据>>> page1 # 当前是第几页<Page 1 of 3>>>> page1.object_list # 获取当前页的对象<QuerySet [<Guest: 崔宇>, <Guest: Andy>]>>>> for g in page1: # 使用for循环打印第1页嘉宾的realname... g.realname... u'\u5d14\u5b87'u'Andy'>>> >>> page2 = p.page(2) # 获取第2页数据>>> page2.start_index() # 本页第一条数据的索引3>>> page2.end_index() # 本页最后一条数据的索引4>>> page2.has_previous() # 本页是否有上一页True>>> page2.has_next() # 本页是否有下一页True>>> page2.previous_page_number() # 本页的上一页是第几页1>>> page2.next_page_number() # 本页的下一页是第几页3>>> page3 = p.page(3) # 获取第3页数据>>> page3.has_next() # 本页是否有下一页False>>> page3.has_previous() # 本页是否有上一页True>>> page3.has_other_pages() # 是否还有其他页True>>> page3.previous_page_number() # 本页的上一页是第几页2>>> 12345678910111213141516171819202122232425262728293031323334353637383940414243441234567891011121314151617181920212223242526272829303132333435363738394041424344

对嘉宾管理页面,增加分页器。

修改/guest/sign/views.py文件:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger# 嘉宾管理@login_requireddef guest_manage(request):

修改/guest/sign/templates/guest_manage.html文件:

 <!-- 列表分页器 -->

上面的代码就不做过多解释了,因为虫师在书中也没有做详细的说明,可能是觉得大家的技术水平,对于阅读HTML代码,应该不成问题,我这里,简单说明,先是判断是否有上一页,有则previous可以点击,并且url页面会跳转到上一页,当前只显示当前页和总页数,如果有下一页,则next可以点击,并且url页面会跳转到下一页。

这里,虫师又说到,如果开发了嘉宾搜索功能:“那么同样需要在搜索视图中添加分页功能。”

但是,书中并没有给出相关代码,我这里出于好奇,也是觉得既然自己开发了嘉宾搜索功能,那么这个分页器似乎也不太难,照搬应该就能给搜索功能同样添加一个分页器吧。

于是,自己参考上面的代码,开始给搜索功能增加分页器,问题就接踵而至了(Ps:笔者半路出家,对前端只了解那么可怜的一丢丢),下面就是自己遇到的问题,以及解决的办法,对于我来说,能够靠自己的仔细观察和动手实践解决这个问题,真的让自己着实开心了好一下,感觉自己的坚持学习,总算是有收获的!

首先,自己是完全没有分析,想当然的,把上面的代码直接插入到了嘉宾搜索的views.py中:

# 嘉宾名称搜索@login_requireddef search_realname(request):

然后, html代码没做任何改变,尝试是否生效,为了验证搜索结果大于一页,我在嘉宾列表里添加了如下数据:

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

这样如果我在嘉宾列表页面搜索“Andy”就会模糊匹配到三条结果,分页器的效果就能展示出来了,每页展示2条,那么会有总共2页:

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

当看到这个效果的时候,我很开心啊,显示的结果完全符合预期,这很简单啊,但是,当我点击next按钮时,按理来说,应该展示搜索结果的第二页内容,也就是只展示一条Andy3才对,可实际却是,当我点击next按钮后,页面刷新,返回到了嘉宾列表页面,嘉宾列表和分页器全部和搜索之前一样了。

神啊,为什么会这样,为什么在搜索的第一页是正确的,但是点击了next就完全不对了???

看来真的不是这么简单,完全照搬代码,是不对的!还是要分析下分页器的功能到底在嘉宾列表和嘉宾搜索结果两者之间有什么区别!

下面就是自己分析以及解决的过程:

  1. 分页器无论是在嘉宾列表页面还是在嘉宾搜索页面,分页器在展示效果上应该是同一套,只是展示结果不同,嘉宾列表要根据嘉宾总数及每页展示数量进行展示,而嘉宾搜索结果改变了嘉宾总数,对于这一点,上述代码没有问题,是符合预期的,也就是说html里的分页器代码并没错;

  2. 但是为什么会出现点击了next按钮后,页面就返回到了嘉宾列表页面呢,看来问题是出在这个next按钮上,我们仔细观察URL的变化:

  • 正常展示嘉宾列表时URL为:http://127.0.0.1:8000/guest_manage/

  • 此时next按钮的URL为:http://127.0.0.1:8000/guest_manage/?page=2

  • 当使用搜索按钮过滤“Andy”时URL为:http://127.0.0.1:8000/search_realname/?realname=Andy

  • 此时next按钮的URL为:http://127.0.0.1:8000/search_realname/?page=2

  • 如果我们在搜索结果中点击next按钮,虽然路径仍然是“/search_realname/”,但是明显是缺少了过滤条件“?realname=Andy”,所以才导致虽然点击的是下一页“?page=2”,但是最终结果仍然是全部嘉宾列表;

  • 那是不是我们把过滤条件和分页器组合一下,结果就对了呢?尝试在浏览器中输入URL:http://127.0.0.1:8000/search_realname/?page=2&realname=Andy,结果真的是只展示了搜索条件下的第二页内容:

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

现在问题是知道了,接下来就是如何去解决了:

先要理清一些对应关系:

http://127.0.0.1:8000/search_realname/?page=2&realname=Andy

  • /search_realname/:对应views.py文件里的def search_realname函数;

  • ?page=2:对应guest_manage.html里分页器a标签href指定的URL;

return render(request,"guest_manage.html", {"user": username, "guests": contacts})

  • guests:对应guest_manage.html里分页器a标签href指定的page值,即page={{ guests.next_page_number }}

理清上面这点,才能知道怎么去改,也就是说,我们要想达到在嘉宾搜索列表下分页,需要同时修改views.py以及guest_manage.html两个文件:

首先修改/guest/sign/views.py文件:

# 嘉宾名称搜索@login_requireddef search_realname(request):

然后修改/guest/sign/templates/guest_manage.html文件,不过修改之前,我们还需要理清一个点就是,分页器虽然是一段代码,但是嘉宾展示列表和嘉宾搜索结果列表,都要同时使用这一段分页器代码,所以我们就必须要区分出,什么时候该展示嘉宾列表的分页器,什么时候该展示嘉宾搜索结果列表的分页器,使用Django模板标签里的{% if %}对搜索名称来判断,应该是合理的,最终代码如下:

 <!-- 列表分页器 -->

完成上述操作后,就实现了,既能正确展示嘉宾列表的分页,也能正确展示嘉宾搜索结果的分页,并且分页内容及功能都正确了。

5.4 签到功能

5.4.1 添加签到链接

发布会与签到功能,是一一对应的关系。

给每个发布会都提供一个“签到”链接:

修改/guest/sign/templates/event_manage.html文件:

<!-- 发布会列表 -->

通过上述代码实现的功能就是:当点击“sign”链接时,路径会自动跳转到与event.id相对应的签到页面(当前还未开发)。

增加签到页面的路径:

修改/guest/urls.py文件:

from sign import views

与之前略有不同,括号内的内容匹配发布会id,限制只能是数字,匹配的数字eid将会作为sign_index()视图函数的参数。

5.4.2 签到页面

首先,创建签到页面的sign_index()视图函数:

修改/guest/sign/views.py:

from django.shortcuts import render, get_object_or_404# 签到页面@login_requireddef sign_index(request, eid):

get_object_or_404()方法:默认调用Django的table.objects.get()方法,如果查询的对象不存在,则会抛出一个HTTP 404异常,这样就省去了对table.objects.get()方法做异常断言。

然后,创建签到页面模板html:

修改/guest/sign/templates/sign_index.html文件:

<!DOCTYPE html><html>

添加完html页面后,点击sign跳转到签到页面,结果完全没有样式,才想起来,忘记加载bootstrap3了。在代码head部分加上。

html各功能解释参考备注。

5.4.3 签到动作

继续完善签到功能,上面是完成了sign_index签到页面,接下来就是对签到动作也就是sign_index_action相关功能。

首先,添加签到动作的路径:

修改/guest/urls.py文件:

from sign import views

其次,增加签到动作的视图函数:

修改/guest/sign/views.py文件:

# 签到动作@login_requireddef sign_index_action(request, eid):

签到动作最关键的就是对输入的手机号以及手机号对应的发布会的对应关系的一个判断,所以sign_index_action里最多的就是if判断,详细见备注。

这里虫师又给大家挖了个坑!!!

当我按照上面的代码进行编写后,在签到页面输入一个手机号,点击签到按钮,系统居然提示403错误:

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

这是神马情况,明显是身份认证的错误,这在之前做登录认证页面的时候,好像也见过。

虫师之前说过的一段话很好,就是要仔细阅读错误信息,也许答案就在其中,再回头看签到功能相关代码,我们发现问题出现在两个地方:

问题1:

我们在视图里定义sign相关函数的时候,都加了装饰器@login_required,但是在返回给页面的时候,没有加用户信息。

问题2:

我们在模板sign_index.html里,在定义签到功能的时候,使用了POST请求,而POST请求必须有{% csrf_token %}标签才可以。

综合以上两点,做出修改如下修改:

首先是/guest/sign/views.py文件:

# 签到页面@login_requireddef sign_index(request, eid):

然后是/guest/sign/templates/sign_index.html文件:

<!-- 签到功能 -->

经过上述修改后,再次尝试使用手机号进行签到,效果就和书中一样了:

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

虫师留的作业:

要求是:如何将当前发布的嘉宾数和已签到数显示在签到页面上。签到嘉宾数固定,每成功签到一位嘉宾,就将签到数加1,这样我们就可以实时知道当前发布会还有多少嘉宾未签到了。

首先,分析需求,需求仅要求我们将几个重要的数据展示出来:

  • 一个发布会总的嘉宾数量,固定值,通过查询嘉宾数据表,指定发布会id即可;

  • 一个已签到的嘉宾数量,可变值,每当成功签到一位嘉宾,该值就加1,已签到嘉宾可通过查询嘉宾数据表,指定sign字段为1即可;

将上述信息展示在签到页面,格式无所谓,我理解虫师的本意,初始情况,应该是先获取一个总共的嘉宾数,再获取一个已签到嘉宾数,将这两个值展示出来,但是当用户使用手机号进行签到后,就要将已签到嘉宾数加1展示,也就是已签到嘉宾数要初始获取一个固定值,每当签到成功后,该值加1,签到不成功,不加1,理清了这些需求,剩下就是实现了。

同样还是需要对两处进行改动:

  • 一是视图里的sign_indext_action函数,增加这两个值的处理;

  • 二是模板里的sign_index.html函数,增加展示的相关内容;

修改/guest/sign/views.py文件:

from django.shortcuts import render, get_object_or_404, get_list_or_404# 签到页面@login_requireddef sign_index(request, eid):

这里最关键的有三点:

第一,是我们使用了新的获取数据表对象列表的方法get_list_or_404(),该方法会返回查询数据结果列表,如果没有查询到指定数据就返回404错误页面;

第二,我们希望是进入到签到页面就展示嘉宾总数和已签到嘉宾数,当只有签到成功后,才变更已签到嘉宾数,所以在sign_index函数和sign_index_action两个函数都使用这两个变量;

第三,我们希望只在签到成功才变更已签到数量,其余时候都只是返回当前的嘉宾总数和已签到嘉宾数;

最终效果如下:

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

看看大牛是怎么用Web接口开发与自动化测试基于Python语言

5.5 退出系统

最后来实现退出系统功能。

修改/guest/urls.py文件,增加退出路径:

from sign import views

修改/guest/sign/views.py文件,增加logout()视图函数:

# 退出动作@login_requireddef logout(request):

Django的auth.login()方法用于验证登录用户信息,同时也提供了auth.logout()方法用于退出系统,它可以清除浏览器保存的用户信息,这样用户就不用考虑如何删除浏览器的cookie信息。退出成功后,页面跳转至/index/首页。

总结:

第五章可以说是对发布会、嘉宾、签到三者功能上的一个大概实现。通过本章,该功能已经初步可用。代码比较多,我自己也加了很多的注释,通过发现书中的问题,以及解决,对Django的MTV开发模式有了更清楚的认识,清楚了三者之间如何联动,如何实现。知识点主要集中在视图函数的几个库函数的使用,以及简单使用bootstrap3来装扮html的样式。

可以说,多自己动手,多自己思考,才是消化这章的最佳办法。因为有些问题是我自己处理的,如果大家在阅读过程中发现有错误,或者更好的办法,欢迎交流指正。

猜你喜欢

转载自blog.csdn.net/qq_42156420/article/details/85231072