web框架
所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。
1 import socket 2 3 4 def handle_request(client): 5 buf = client.recv(1024) 6 client.send(b"HTTP/1.1 200 OK ") 7 client.send(b"Hello, Seven") 8 9 10 def main(): 11 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 12 sock.bind(('localhost', 8000)) 13 sock.listen(5) 14 15 while True: 16 connection, address = sock.accept() 17 handle_request(connection) 18 connection.close() 19 20 21 if __name__ == '__main__': 22 main()
上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。
WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。
python标准库提供的独立WSGI服务器称为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()
1 from wsgiref.simple_server import make_server 2 3 4 def index(): 5 return ['<h1>hello,index</h1>'.encode('utf-8'),] 6 7 8 def login(): 9 return ['<h1>hello,login</h1>'.encode('utf-8'),] 10 11 12 def routers(): 13 urlpatterns = ( 14 ('/index/', index), #可以在这加正则表达式,匹配多个域名 15 ('/login/', login), 16 ) 17 18 return urlpatterns 19 20 21 def RunServer(environ, start_response): 22 start_response('200 OK', [('Content-Type', 'text/html')]) 23 url = environ['PATH_INFO'] 24 urlpatterns = routers() 25 func = None 26 for item in urlpatterns: 27 if item[0] == url: 28 func = item[1] 29 break 30 if func: 31 return func() 32 else: 33 return '404 not found' 34 35 36 if __name__ == '__main__': 37 httpd = make_server('', 8000, RunServer) 38 print("Serving HTTP on port 8000...") 39 httpd.serve_forever()
两种网络框架模型
MVC Model View Controller 数据库 模板文件 业务处理 MTV Model Template View 数据库 模板文件 业务处理
大而全的web框架——Django
创建Django工程
创建app
配置模板和静态文件路径
配置模板路径 settings.TEMPLATES添加 'DIRS': [os.path.join(BASE_DIR, 'templates')] 配置静态文件路径 在settings文件的最后添加 STATICFILES_DIRS=( os.path.join(BASE_DIR,'static'), #一定要写逗号 ) 提交时报403的错 将settings.MIDDLEWARE'django.middleware.csrf.CsrfViewMiddleware',注释掉
定义路由规则(URL)
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login', views.login), url(r'^home', views.home), ]
定义视图函数(app下的view.py)
def func(request): # request.method ==> GET / POST # http://127.0.0.1:8009/home?nid=123&name=alex # request.GET.get('',None) # 获取请求发来的而数据 # request.POST.get('',None) # return HttpResponse("字符串") #返回字符串 # return render(request, "HTML模板的路径") #返回HTML模板 # return redirect('/只能填URL') #去通过URL直接启动要跳转的网页
Django请求生命周期
-> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串
-> URL对应关系(匹配) -> 视图函数 -> 打开一个HTML文件,读取内容(其实也是字符串)
模板语言
1、-- {{ 变量名 }}
view.py
def func(request): return render(request, "index.html", {'current_user': "alex"}) index.html <html> .. <body> <div>{{current_user}}</div> </body> </html> ====> 最后生成的字符串 <html> .. <body> <div>alex</div> </body> </html>
1 urls.py 2 3 urlpatterns = [ 4 url(r'^admin/', admin.site.urls), 5 url(r'^login',views.login), 6 ] 7 8 views.py 9 10 def login(request): 11 erro="" 12 if request.method == "POST": 13 if request.POST.get('user') =='root' and request.POST.get('pwd') =='123': 14 return redirect('/home') #跳转到home页面 15 else : 16 erro = "用户名或密码输入错误" 17 return render(requset,'login.html',{'erro_msg':erro}) 18 19 login.html 20 21 <!DOCTYPE html> 22 <html lang="en"> 23 <head> 24 <meta charset="UTF-8"> 25 <title>Title</title> 26 <link rel="stylesheet" href="/static/abc.css" /> 27 <style> 28 label{ 29 80px; 30 text-align: right; 31 display: inline-block; 32 } 33 </style> 34 </head> 35 <body class="c1"> 36 <form action="/login" method="post"> 37 <p> 38 <label for="username">用户名:</label> 39 <input id="username" type="text" name="user"/> 40 </p> 41 <p> 42 <label for="password">密码:</label> 43 <input id="password" type="password" name="pwd" /> 44 <input type="submit" value="提交" /> 45 <span style="color: gold">{{ erro_msg }}</span> 46 </p> 47 <script src="/static/jquery-1.12.4.js"></script> 48 </form> 49 </body> 50 </html>
2、-- For循环 { % for i in list % } {% endfor %}
for循环中的序号
{{ forloop.counter }} //从1开始往后排 {{ forloop.revcounter }} //倒着排排到1 {{ forloop.last }} //判断是否是最后一个循环 {{ forloop.first }} //判断是否是第一个循环 {{ forloop.counter0 }} //从0开始往后排 {{ forloop.revcounter0 }} //倒着排排到0 {{ parentloop }} //展示父循环的上面6个信息
列表循环
view.py def func(request): return render(request, "index.html", {'current_user': "alex", 'user_list': ['alex','eric']}) index.html <html> .. <body> <div>{{current_user}}</div> #直接赋值 "alex" <ul> {% for row in user_list %} #支持循环的嵌套 {% if row == "alex" %} <li>{{ row }}</li> {% endif %} #一定要结束 {% endfor %} #同上 </ul> </body> </html>
1 urls.py 2 3 urlpatterns = [ 4 url(r'^admin/', admin.site.urls), 5 url(r'^login',views.login), 6 url(r'^home',views.home), 7 ] 8 9 views.py 10 11 USER_LIST = [ 12 {'id': 1, 'username': 'alex', 'email': 'asdfasdf', "gender": '男'}, 13 {'id': 2, 'username': 'eriuc', 'email': 'asdfasdf', "gender": '男'}, 14 {"id": 3,'username': 'seven', 'email': 'asdfasdf', "gender": '男'}, 15 ] 16 17 for i in range(20): 18 temp={'id': 1, 'username': 'alex'+str(i), 'email': 'asdfasdf', "gender": '男'} 19 USER_LIST.append(temp) 20 21 def home(request): 22 if request.method=="POST": 23 u = request.POST.get('username') 24 e = request.POST.get('email') 25 g = request.POST.get('gender') 26 temp={'username':u,'email':e,'gender':g,} 27 USER_LIST.append(temp) 28 return render(request,'home.html',{'user_list':USER_LIST}) 29 30 home.html 31 32 <!DOCTYPE html> 33 <html lang="en"> 34 <head> 35 <meta charset="UTF-8"> 36 <title>Title</title> 37 </head> 38 <body> 39 <div> 40 <form action="/home" method="post"> 41 <input type="text" name="username" placeholder="用户名"/> 42 <input type="text" name="email" placeholder="邮箱"/> 43 <input type="text" name="gender" placeholder="性别"/> 44 <input type="submit" value="添加"/> 45 </form> 46 </div> 47 <div> 48 <table> 49 {% for row in user_list %} 50 <tr> 51 <td>{{ row.username }}</td> 52 <td>{{ row.gender }}</td> 53 <td>{{ row.email }}</td> 54 </tr> 55 {% endfor %} 56 </table> 57 </div> 58 </body> 59 </html>
字典循环
view.py USER_DICT = { 'k1':"user1", 'k2':"user2", 'k3':"user3", 'k4':"user4", } def index(request): return render(request,'index.html',{"user_dict":USER_DICT}) index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for k,row in user_dict.items %} <li>{{ k }},{{ row }}</li> {% endfor %} </ul> <ul> {% for k in user_dict.keys %} <li>{{ k }}</li> {% endfor %} </ul> <ul> {% for row in user_dict.values %} <li>{{ row }}</li> {% endfor %} </ul> </body> </html>
3、索引get值的方法
def func(request): return render(request, "index.html", { 'current_user': "alex", 'user_list': ['alex','eric'], 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) index.html <html> .. <body> <div>{{current_user}}</div> <a> {{ user_list.1 }} </a> <a> {{ user_dict.k1 }} </a> <a> {{ user_dict.k2 }} </a> </body> </html>
4、判断
def func(request): return render(request, "index.html", { 'current_user': "alex", "age": 18, 'user_list': ['alex','eric'], 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) index.html <html> .. <body> <div>{{current_user}}</div> <a> {{ user_list.1 }} </a> <a> {{ user_dict.k1 }} </a> <a> {{ user_dict.k2 }} </a> {% if age %} <a>有年龄</a> {% if age > 16 %} <a>老男人</a> {% else %} <a>小鲜肉</a> {% endif %} {% else %} <a>无年龄</a> {% endif %} </body> </html>