Django学习---Web框架
web框架的本质
我们在学socket,我们创建一个socketserver,然后运行起来,有一个client客户端要连接socket服务端,连接上之后,如果两边都没有close,就一直不断开,可以不断的进行请求。
我们下面写一个socket服务端:
1 import socket 2 3 def handle_request(client): 4 buf = client.recv(1024) 5 client.send(bytes("HTTP/1.1 200 ok\r\n\r\n",encoding="utf-8")) 6 client.send(bytes("Hello,Charles",encoding="utf-8")) 7 8 9 def main(): 10 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 11 sock.bind(('localhost',8000)) 12 sock.listen(5) 13 14 while True: 15 connection,addr = sock.accept() 16 handle_request(connection) 17 connection.close() 18 19 if __name__ == '__main__': 20 main()
运行之后主程序运行main(),main中创建了socket,监听了8000端口,最多排队五个,只要有来连接就获得这个链接,然后调用handle_requset方法处理请求。处理完之后关掉连接。
处理请求:接受一下客户端端发过来的值,send值。
所有的web框架的本质就是上述20行代码!!!
在python中还提供一个其他的模块,帮我们封装socket,即wsgiref:
1 from wsgiref.simple_server import make_server 2 3 4 def RunServer(environ, start_response): 5 start_response('200 OK', [('Content-Type', 'text/html')]) 6 return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]#返回的内容 7 8 9 if __name__ == '__main__': 10 httpd = make_server('', 8000, RunServer) 11 print("Serving HTTP on port 8000...") 12 httpd.serve_forever()
只要有请求,就会触发RunServer函数,
environ封装了客户端发来的所有数据,
start_response封装要返回给用户的数据,比如:响应头,状态等
现在我们访问localhost:8000,显示出来的都是hello,web,一般的网站的url都会有什么/data,/index等,用来显示不同的页面内容,那我们应该怎么做呢?
我们设置断点,进入调试模式,在运行浏览器可以看到:
environ中有很多的参数,我们找到一个叫做PATH_INFO的参数,那个就是显示我们url后面有什么。
这样我们就能够通过url进行判断,然后进入相应的页面:
from wsgiref.simple_server import make_server def handle_index(): return [bytes('<h1>Hello, Index!</h1>', encoding='utf-8'), ] def hanle_date(): return [bytes('<h1>Hello, Date!</h1>', encoding='utf-8'), ] def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) currnet_url = environ['PATH_INFO']; if currnet_url =='/index': return handle_index() elif currnet_url =='/date': return hanle_date() else: return [bytes('<h1>404,error!</h1>', encoding='utf-8'), ] if __name__ == '__main__': httpd = make_server('', 8000, RunServer) print("Serving HTTP on port 8000...") httpd.serve_forever()
通过这个我们完成了一些基本的操作。
那如果说url很多,我们不可能一个一个去判断吧,那我们应该怎么做呢?python中几乎所以的web框架都是把所有的url放在一个列表中: 然后一类的url可以通过正则表达式进行匹配
URL_DICT = { "/index":handle_index, "/date":handle_date, } def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) currnet_url = environ['PATH_INFO']; func = None if currnet_url in URL_DICT: func = URL_DICT[currnet_url] if func: return func() else: return [bytes('<h1>404,error!</h1>', encoding='utf-8'), ]
我们看上面的代码,如果我们把return里的html放在一个html文件中,并放在View文件夹中;把handle_index等处理业务逻辑的函数写在一个py文件中并放在Controller文件夹中。从数据库读取的方法放在Model文件夹中。
我们需要html的时候就打开html文件f=open("html文件",mode="rb")然后read读取就可以了。
我们需要用函数的时候就直接from Controller import 文件名,然后用文件名.函数名就可以了。
我们在html中想要用一些特殊的符号,数据从数据库中获取替换,也只要引入model文件家中的方法,读出数据之后用replace函数替换符号和函数就可以了。
MVC:
Model数据库 View模板文件 Controller业务处理
MTV:(Django是基于MTV的框架)
Model数据库 Template模板文件 View业务处理
Django
安装:pip install django;
安装完之后就多了一个可执行文件
创建django程序:
运行着个Django程序:python manage.py runserver (127.0.0.1:8001),默认端口号为8000
django就算创建完了!!
工程目录:
mysite
- mysite #对整个程序进行配置
-__init__.py:
-setting.py: #配置文件
-url.py #url对应关系
-wsgi.py #遵循WSGI规范
-manage.py #管理Django程序
pycharm创建django程序:
1.新建django
2.运行django
要注意要运行你的项目名称,而不是manage.py或者是其他的文件
如果要改运行的url和端口名:
直接在host和port中设置就可以了
创建app:
例如抽屉网:
-chouti
-配置
-主站 app
-后台管理 app
创建app:
python manage.py startapp cmdb
app目录:
cmdb
-migrations:数据库操作的记录(修改表记录的操作)
-__init__.py:
-admin.py:django为我们提供的后台管理
-apps.py:配置当前app
-models.py:orm,写指定的类,通过命令可以创建数据库结构
-tests.py:单元测试
-views.py:业务代码
下面我们写一个登陆页面:
1.首先创建一个login.html页面:放在templates文件夹下面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <link rel="stylesheet" href="/static/commons.css" /> 7 <style> 8 label{ 9 width:80px; 10 text-align: right; 11 display: inline-block; 12 } 13 </style> 14 </head> 15 <body> 16 <form action="/login/" method="post"> 17 <p> 18 <label for="username">用户名:</label> 19 <input id="username" type="text" /> 20 </p> 21 <p> 22 <label for="password">密码:</label> 23 <input id="password" type="password" /> 24 <input type="submit" value="提交"/> 25 </p> 26 27 </form> 28 <script src="/static/jquery.min.js"></script> 29 </body> 30 </html>
2.在url文件中设置login页面的路径:
3.在cmdb这个app的view下写业务代码:
这里django中有render模块直接封装了文件的打开读取关闭的过程。传入的login.html的路径名是由django_study下面的setting中的templates决定的:
配置模板的目录:
配置静态目录:
<link rel="stylesheet" href="/static/commons.css" />
<script src="/static/jquery.min.js"></script>
我们现在没有做数据处理,我们点击提交:出现了CSRF的错误
如果我们不想要这个错误的话可以把settings中的代码注释了:
知识点整理:
1.创建django工程
django-admin startproject 工程名
2.创建app
cd 工程名
python manage.py startapp cmdb
3.静态文件
project.setting.py
STATICFILES_DIRS = (os.path.join(BASE_DIR,"static"),)
4.模板路径
DIRS ==>os.path.join(BASE_DIR,"templates"),
5.setting中找middleware 注释csrf
6.定义路由规则
url.py
"login/"->函数名
7.写视图函数
app下的view.py
def func(request):
#request.method==POST/GET
#request.POST.get(' ',None) request.GET.get(' ',None)
#返回数据:HttpResponse("str") return render(request,"html文件路径","html中要替换的变量":USER_LIST) return redirect("/只能填URL路径")
8.模板渲染
模板语言:
--{{变量名}} def func(request): return render(request,'index.html',{'current_user':"alex"}) index.html中 <html> ........ <body> <div>{{current_user}}</div>#这样用alex替换了current_user </body> </html> --For循环 def func(request): return render(request,'index.html',{
'current_user':"alex",
'user_list':{'k1':'v1','k2':'v2'}}) index.html中 <html> ........ <body> <div>{{current_user}}</div>#这样用alex替换了current_user <ul> {%for row in user_list %} <li>{{row.k1}}</li> {%endfor%} </ul> </body> </html>
--索引
def func(request):
return render(request,'index.html',{
'current_user':"alex",
'user_list':['xiaoming','liangliang']
'user_dict':{'k1':'v1','k2':'v2'}}) index.html中 <html> ........ <body> <a>{user_list.0/1}</a>
</body> </html>
--条件
{%if age %}
<a>有年龄</a>
{% else %}
<a>无年龄</a>
{% endif %}
--循环字典
{%for k,row in dict.items%}#同时获得key和value
<li>{{k}}-{{row}}</li>
{%endfor%}
{%for row in dict.keys%}#获得字典中的key
<li>{{row}}</li>
{%endfor%}
{%for row in dict.values%}#获得字典中的value
<li>{{row}}</li>
{%endfor%}