web应用
基于浏览器的应用程序
cs/bs架构
cs:客户端,服务端
bs:浏览器,服务端
import socket #socket的对象 sco=socket.socket() #绑定地址端口 sco.bind(('127.0.0.1',8008)) #监听 sco.listen(5) while True: conn,addr=sco.accept() data=conn.recv(1024) print(data) conn.send(b'HTTP/1.1 200 OK\r\ncontent-type:text/json\r\n\r\nhello') conn.close()
请求:
浏览器http://127.0.0.1:8008/test/ 请求,服务器响应日志:
//第一行:http协议请求首行(请求方式)--->空格--->请求路径--->空格--->协议版本号
b'GET /test/ HTTP/1.1\r\n
//第二行:key:value--->请求头
// \r\n\r\n 请求体,向服务器发送数据
Host: 127.0.0.1:8008\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
响应:
// ---响应首行--->响应协议,版本号--->空格---->状态码---》空格--->状态的简单描述
HTTP/1.1 200 OK\r\n
//--->响应头 hello--->响应体
content-type:text/json\r\n\r\nhello
web框架
wsgiref:按照某种协议,封装了socket
django,flask.tornado
a:socket
b:路由和视图的映射关系
c:模板的替换
django: a:使用别人封装socket b:自己写的映射 c:自己写的模板
flask: a:使用别人封装socket b:自己写的映射 c:jianjia2
tornado: a:自己写的socket b:自己写的映射 c:自己写的模板
wsgiref未拆分代码:
from wsgiref.simple_server import make_server def time(): return 'time'.encode('utf-8') def index(): return 'index'.encode('utf-8') def error(): return '404'.encode('utf-8') urls=[('/time',time),('/index',index)] def myrun(env,res): res('200 OK',[('Content-Type','text/html')]) # print(env) path=env.get('PATH_INFO') #访问地址路径 print(path) func=None for url in urls: if path==url[0]: func=url[1] break if func: data=func() else: data=error() return [data] #if-elese便于理解 # if path=='/time': # return [b'time'] # elif path=='/index': # return [b'index'] # else: # return [b'404'] if __name__ == '__main__': app=make_server('127.0.0.1',8009,myrun) app.serve_forever()
拆分后代码
Wsgiref_server.py
from wsgiref.simple_server import make_server from urls import * def myrun(env,res): res('200 OK',[('Content-Type','text/html')]) path=env.get('PATH_INFO') #访问地址路径 print(path) func=None for url in my_urls: if path==url[0]: func=url[1] break if func: data=func() else: data=error() return [data] if __name__ == '__main__': app=make_server('127.0.0.1',8006,myrun) app.serve_forever()
urls.py
from views import * my_urls=[('/time',mytime),('/index',index)]
views.py
import time def mytime(): ctim=time.time() with open('templates/time.html','r')as f: data=f.read() data=data.replace('@@time@@',str(ctim)) return data.encode('utf-8') def index(): with open('templates/index.html','rb')as f: data=f.read() return data def error(): return '404'.encode('utf-8')
templates-index.html
<body> 我是首页 </body>
telplates-time.html
<body> @@time@@ </body>
django的安装与使用:
python pip国内镜像:https://www.cnblogs.com/wqpkita/p/7248525.html
安装:
1.pip3 install django==1.11.9 指定版本号
pip3 install django==1.11.9 -i http://mirrors.aliyun.com/pypi/simple 指定版本,国内资源
2.pycharm安装
注意:
1.项目和文件夹是英文名
2.电脑主机名是英文名
3.一个工程就是一个项目
3.用命令创建项目:
1、安装完成django后,在多django-admin.exe
2、用命令创建django(指定的目录下):django-admin startproject 项目名字
3、创建app:python3 manage.py startapp app的名字 //django-admin startproject myseconddjango
4、运行项目:python3 manage.py runserver 127.0.0.1 8005
python3 manage.py runserver 8005
python3 manage.py runserver
5、用pycharm创建,运行项目
-file-->new project--->django--->可以指定app的名字
-运行项目:点击pycharm上方的绿色箭头(点击它,相当于执行了上面的运行项目的命令)
4.目录结构:
app名字的文件夹:
-migrations--->放数据库迁移的数据
-admin.py--->后台管理相关
-apps.py--->app配置相关
-models.py--->orm相关(数据库相关)
-test--->测试相关
-views--->视图函数放在里面
项目名字的文件夹
-settings.py--->项目全局配置相关
-urls.py--->路由和视图的映射关系
-wsgi.py--->socket服务相关
templates
-所有的模板文件(html页面)
manage.py
-所有命令的入口
举例:
urls.py
from app01 import views
urlpatterns = [
url(r'^admin/',
admin.site.urls),
url(r'^index/',
views.index),
]
views.py
from django.shortcuts import render,HttpResponse
# Create your views here.
#视图函数至少有一个参数,request对象,浏览器请求过来的所有数据(地址,头,体)
def index(request):
return HttpResponse('index')
访问地址:http://127.0.0.1:8000/index/
6.路由层:
-路由的作用:地址和视图函数的对应关系
-简单的路由配置
-第一个参数:传一个正则表达式,第二个参数:视图函数
# url(r'^index', views.index),
-无名分组
-url(r'^index/([0-9]{4})/([0-9]{2})/$', views.index),
-分组分出几个数据,视图函数就要用几个参数来接收
-有名分组
-url(r'^index/(?P<year>[0-9]{4})/(?P<mon>[0-9]{2})/$', views.index),
-分组分出几个数据,会以关键字形式,传到视图函数
举例:
Urls.py
urlpatterns = [
# url(r'^admin/', admin.site.urls),
#第一参数:传一个正则
# url(r'^index', views.index),
#如果只想匹配index
# url(r'^index/$', views.index),
#无名分组,分组出来的数据,会当着参数,传到视图函数中
# url(r'^index/([0-9]{4})/([0-9]{2})/$',
views.index),
#有名分组
url(r'^index/(?P<year>[0-9]{4})/(?P<mon>[0-9]{2})/$', views.index),
]
views.py
from django.shortcuts import render,HttpResponse
# Create your views here.
#视图函数至少有一个参数,request对象,浏览器请求过来的所有数据(地址,头,体)
#无名分组
# def index(request,year,month):
# def index(request, *args):
# # print(year)
# # print(month)
# print(args)
# return HttpResponse('index')
#有名分组
def index(request,mon,year):
print(year)
print(mon)
return HttpResponse('index')
7.路由的分发
-1.在不同的app中创建urls.py子路由
-2.总路由有导入from django.conf.urls import url,include
-3.url(r'^app01/', include('app01.urls')),
步骤:
1.myfirstjango-setting.py
INSTALLED_APPS = [
'app01',
'app02',
]
2.myfirstjango-urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
#路由分发
urlpatterns = [
url(r'^app01/',
include('app01.urls')),
url(r'^app02/',
include('app02.urls')),
]
3.app01-urls.py
from django.conf.urls import url,include
from app01 import views
urlpatterns = [
url(r'^index/',
views.index),
]
4.app02-urls.py
from django.conf.urls import url,include
from app02 import views
urlpatterns = [
url(r'^index/',
views.index),
]
5.app01-views.py
from django.shortcuts import render,HttpResponse
def index(request):
return HttpResponse('index')
6.app02-views.py
from django.shortcuts import render,HttpResponse
def index(request):
return HttpResponse('app02-index')
7.状态码:
1开头--->服务器正在处理我的请求
2开头--->处理成功
3开头--->重定向
4开头--->客户端错误
5开头--->服务端错误
举例:
render使用
app01-urls.py
from django.conf.urls import url,include
from app01 import views
urlpatterns = [
url(r'^index/',
views.index),
url(r'^test/',
views.test),
]
app01-views.py
from django.shortcuts import render,HttpResponse
def index(request):
return HttpResponse('index')
def test(request):
return render(request,'app01/test.html')
templates-app01-test.html
测试地址:127.0.0.1:8000/app01/test
HttpResponseRedirect使用
app01-urls.py
from django.conf.urls import url,include
from app01 import views
urlpatterns = [
url(r'^re_test/',
views.re_test),
]
app01-views.py
from django.shortcuts import render,HttpResponse,HttpResponseRedirect
def re_test(request):
return HttpResponseRedirect('https://www.baidu.com')
测试地址:http://127.0.0.1:8000/app01/re_test/
下图是重定向示意图
反向解析
-给路径名:url(r'^index888/', views.index,name='index'),
-在视图函数里用:
url=reverse('index')
-在模板里用:
<a href="{% url 'index' %}">点我</a>
举例:
app01-urls.py
from django.conf.urls import url,include
from app01 import views
urlpatterns = [
url(r'^re_test/',
views.re_test),
url(r'^index888/', views.index,name='index'),
url(r'^test/',
views.test),
]
app01-views.py
from django.shortcuts import render,HttpResponse,HttpResponseRedirect,reverse
def re_test(request):
# return HttpResponseRedirect('https://www.baidu.com')
url=reverse('index')
print(url)
return HttpResponseRedirect(url)
def index(request):
return HttpResponse('index')
def test(request):
return render(request,'app01/index.html')
templates-app01-index.html
<body>
我是index
<a href="/app01/index">点我</a>
<a href="{% url
'index' %}">点我</a>
</body>
视图层
请求对象
# def myview(request):
# #属性
# #请求方式
# print(request.method)
# #请求体的内容(当成字典)
# print(request.POST)
# #浏览器窗口传来的数据
# print(request.GET)
# #上传的文件
# print(request.FILES)
# #请求的路径
# print(request.path)
# 请求原生数据
# print(request.body)
# #方法
# #请求的路径,带着数据
# print(request.get_full_path())
# return HttpResponse('ok')
举例:
app01-urls.py
from django.conf.urls import url,include
from app01 import views
urlpatterns = [
url(r'^re_test/',
views.re_test),
url(r'^index/',
views.index,name='index'),
url(r'^test/',
views.test),
url(r'^myview',views.myview)
]
app01-views.py
from django.shortcuts import render,HttpResponse,HttpResponseRedirect,reverse
def re_test(request):
# return HttpResponseRedirect('https://www.baidu.com')
url=reverse('app01:index')
print(url)
return HttpResponseRedirect(url)
def index(request):
return HttpResponse('index')
def test(request):
return render(request,'app01/index.html')
def myview(request):
if request.method=='GET':
print(request.GET.get('name'))
print(request.GET.get('age'))
return render(request,'app01/test.html')
elif request.method=='POST':
#以form表单post形式提交的数据,都可以重request.POST这个字典中提取出来
name=request.POST['name']
password=request.POST.get('password')
if name =='frank' and password=='123':
return HttpResponseRedirect('/app01/index/')
else:
return HttpResponse('用户密码错误')
template-app01-test.html
<body>
{#1.写全路径#}
{#<form action="http://127.0.0.1:8000/app01/myview"
method="post">#}
{#1.写请求地址--推荐第二种#}
{#<form action="/app01/myview" method="post"> #}
{#1.写空#}
<form action="/app01/myview" method="post">
<p>用户名:<input type="text" name="name"></p>
<p>密码:<input type="password" name="password"></p>
<input type="submit" value="提交">
</form>
</body>