Frank的学习之路

Day_17_总结_web应用

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>


返回顶部