30、Python之web框架django进阶篇
一、路由系统URL
我们知道路由url主要用于管理url和方法之间的映射关系,像这样就是把index页面映射到index方法进行处理。也就是说,每次请求一个url就会到django的url文件中进行查找,找到了就会将请求转向对应的处理方法,找不到就会not found。既然是匹配查找,那么我们可不可以将我们的映射关系的url部分写成一个正则表达式呢?这样一来,凡是请求过来的url只要符合这个正则表达式就能够映射到对应的方法进行处理,答案当然是阔以的啦。
那下面咱们就来写一个简单的例子:我们先建立映射关系:这个正则表达式表示需匹配sos/数字这样的url,其中数字会放到uid中传递给处理方法views.sos。新建一个test页面,写上简单的一句代码我们知道这个url是可以匹配我们上面的正则表达式的。编写处理函数如下:
点击链接"点击我",即可看到这样的效果
这表示我们发送的请求被“sos/(?P<uid>\d+)”匹配上了。
之前我们创建的django项目自动生成了url文件,然而当我们在做项目时,可能有很多模块,这时候,我们想让不同模块的路由映射关系由各自模块自己管理,那我们就需要用到多级路由了,其实原理很简单,
举例:以前送快递的时候由快递公司直接配送,快递公司压力太大,且不方便管理,现在很多区域都有了代收点,方便管理,各自代收点只要负责自己的区域就好了。那么具体如何实现呢?
第一步:
在django生成的urls.py中添加路由关系,这里有三个模块,admin,interface以及mylearn。admin是django的后台管理模块,后面会重点说,interface和mylearn是我项目的模块。
第二步:
在mylearn这个模块中新建urls.py文件,添加路由映射关系。
这样就完成了一个多级路由的功能,这时候我们访问XXXX/mylearn/index1就可以将请求数据发送到views.index的方法中了。
二、后台数据获取
如何获取前控件的值,也是一个非常重要的知识,下面给出一个demo展示后台如何获取这些控件的值。
主要涉及的控件是:单选框,复选框和文件。这也就对应了后台如何获取单个值,多个值以及文件。代码如下:前端的页面为:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 9 <form action="/test" method="POST" id="f1" enctype="multipart/form-data"> 10 <div id="sexid"> 11 <div><input type="radio" value="1" name="sex" id="boyid"/><label for="boyid">男</label></div> 12 <div><input type="radio" value="2" name="sex" id="girlid"/><label for="girlid">女</label></div> 13 </div> 14 <div id="favorid"> 15 <div><input type="checkbox" value="1" name="favor" id="footballid"/><label for="footballid">足球</label></div> 16 <div><input type="checkbox" value="2" name="favor" id="baskballid"/><label for="baskballid">篮球</label></div> 17 </div> 18 <div> 19 <input type="file" name="file"/> 20 </div> 21 <div><input id="bt" type="submit"/></div> 22 23 24 <ul> 25 {% for key,value in test_dict.items %} 26 <li>{{ key}}-{{ value.k11 }}</li> 27 {% endfor %} 28 </ul> 29 30 </form> 31 <script src="static/jquery-3.3.1.js"></script> 32 <script> 33 $("#bt").bind('click', function () { 34 console.log($("#sexid").find(":checked")); 35 console.log($("#favorid").find(":checked")); 36 $("#f1").submit(); 37 return false; 38 }); 39 </script> 40 </body> 41 </html>
后台的代码为:
1 def test(request): 2 if request.method == "POST": 3 print(request.POST.get('sex',None)) 4 print(request.POST.getlist('favor',None)) 5 # print(request.POST.get('file',None)) 6 obj = request.FILES.get('file',None) 7 UPLOADPATH = os.path.join("upload",obj.name) 8 f = open(UPLOADPATH,'wb') 9 for line in obj.chunks(): #获取文件内容 10 f.write(line) 11 f.close() 12 13 print(obj,obj.name) 14 return render(request,'test.html')
三、FBV&CBV
FBV全称function base view,之前我们学习的路由关系都是将url映射到函数,也就是FBV,CBV全称是class base view顾名思义就是将url映射到类,那下面我们学习一下,如果使用CBV来完成一个页面的请求和处理。
1、新建一个类Controller,该类必须继承于View类,同时该类必须包含get方法和post方法,具体如下:
2、创建路由关系:其中Process是我们的类,其他都是固定写法。
3、创建一个页面sos.html,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="test" method="post"> <input type="submit"/> </form> </body> </html>
启动项目,访问XXXX/test,则发现get请求进入了我们的get方法,post请求进入了我们post方法,这样一来我们再也不用自己判断请求到底是get还是post了。其实我们可以大致回味一下这个过程,大致推测应该是这样的:
也就是说请求最先进入了View类中的某个方法,然后这个方法判断一下来的请求是get还是post,如果是get就调用我们的get方法,如果是post就调用我们的post方法。最后我们发现,在View类中有一个dispatch方法,就是干这事的。那我们可以在Process方法中重写这个方法试一试,so,我们在Process类中重写了dispatch方法。
然后我们再发一下请求,发现请求失败了,因为我们重写了父类的dispatch方法,导致父类的dispatch方法无法被调用了,所以还需要在Process类中添加调用父类的dispatch方法。代码为:
这样一来整个请求的顺序就是:请求->Process.dispatch->View.dispatch->Process.get/Process.post
四、Django的ORM操作
Django的ORM框架非常牛逼,且其提供了后台功能也很方便,那下面我们就来学习一下这个牛逼的功能。具体步骤如下:
一、数据库配置
在项目的settings.py中更改数据库连接配置,因为我用的是mysql所以我的配置如下:
二、编写类
在我们自己模块的models.py中编写类。
三、注册APP
在setting.py文件中注册我们自己的模块,
四、执行创建命令
执行如下2条命令即可:1、python manage.py makemigrations 2、python manage.py migrate 完成以上步骤后将创建数据库表,不过这里要注意的是1、Django不会自己创建数据库,所以数据库还是要手动创建,2、django除了创建我们的表外,还会创建额外的十张表,给django自己使用。
在创建类的字段时,有一些额外的参数,主要如下:
根据类对数据库表中的操作如下,后学将会关于orm操作的详细学习:
1 # ----------------增------------------- 2 user = request.POST.get('user',None) 3 pwd = request.POST.get('pwd',None) 4 # models.UserInfo.objects.create( 5 # username=user, 6 # password=pwd, 7 # ) 8 obj = models.UserInfo(username=user,password=pwd) 9 obj.save() 10 message = '注册成功' 11 12 # ----------------查---------------------- 13 result = models.UserInfo.objects.filter().all() 14 # result = models.UserInfo.objects.filter(username='root',password=123)#筛选 15 print(result.count()) 16 #删除 17 # models.UserInfo.objects.filter().delete()#全部删除 18 # res = models.UserInfo.objects.filter(username='root').delete() 19 #更新 20 # models.UserInfo.objects.filter(username='gwx').update(username='root',password='123')