Python Day 54 Django框架、web请求流程、状态码、自定义web框架

  ##web请求流程

#1、软件开发架构
  c/s架构
     客户端
   服务端
  b/s架构
   浏览器
   服务器
  本质:b/s架构其实也是c/s架构
#
2、问题:当我们在浏览器中输入一个url地址的时候, 按下回车的那一刹那, 比如ww.baidu.com 描述一下具体的过程. 首先我们通过DNS域名解析服务器对该域名进行解析,解析顺序先找本地dns服务器,比如window系统中host文件,找不到就找根域名解析服务器,全球总共十三台,然后依次找顶级域名服务器.com、权威域名服务器baidu.com、然后二级域名服务器www,当找到www.baidu.com对应的IP地址以后,便向该服务器发送请求,服务器反馈一个响应结果 #3、Http协议介绍
  超文本传输协议:规定了客户端与服务端消息传输的格式
#3-1、四大特性:
  1.基于TCP/IP协议作用于应用层的协议
  2.基于请求响应
  3.无状态
  4.无连接
#3-2、数据格式之请求:
  请求首行
  请求头(一堆k,v键值对)
  
  请求体(post请求携带的数据)
请求头: GET / HTTP/1.1 Host: 127.0.0.1:8080 (主机名) Connection: keep-alive (保持链接) Cache-Control: max-age=0 (缓存不失效) Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Token: bdsjalbdjsalbdjsa 请求体(两个换行符\r\n\r\n后面的内容): bdsabdjsabjddas
#3-3、数据格式之响应:
   响应首行
   响应头(一堆k,v键值对)
  
   响应体(post请求携带的数据)

响应头: HTTP
/1.1 200 OK 响应体: 自己看到的内容 ps: http: 默认端口是80 Https: 默认的端口是443 状态码:(*****************************
   1XX:服务器已经成功接受到你的数据正在处理,你可以继续提交其他数据 2XX:
200 (ok)请求成功 服务器已经将你请求的数据发送给你了 3XX: 302 304重定向 4XX: 404(not found) 403(forbidden 禁止访问)请求资源不存在 5XX: 500 (服务端代码错误) 502 (网关错误 bad gateway) #4、字符串和字节的转换: >>> s = "hello" >>> s 'hello' >>> bytes(s,encoding='utf-8') b'hello' >>> b = bytes(s,encoding='utf-8') >>> str(b, encoding='utf-8')

   ##自定义web框架

#1、需求:想要通过输入不同的 url, 获得不一样的相应内容
#解决思路:
#step 1、创建sokect 服务端:
    该socket服务器接收浏览器客户端发来的请求头中获取uri路径,运用了split方法取值

#step 2、路由系统:
    uri 和 函数的 对应关系 :(注意自定义的原因,这里读每一个html文件都需要自己打开进行读,然后函数return进行返回)
    routes = [
        ('/xxx', f1),
    ('/ooo', f2),
        ('/hhh', f3)
    ] 
#step 3、模板引擎渲染,显示给用户
    将html代码和mysql的数据进行手动融合,然后再替换html中自定义的内容,比如案例中自定义内容@@content@@ 
(自己定制规则需要自己拼接格式 , 或者使用第三方的工具,比如jinjia2模块)   
  后端生成的数据直接传递给前端页面使用(并且前端页面可以灵活的操作改数据) >>> 模板语法
 
   模板渲染 模板语法需要依赖于第三方模块
   pip install jinja2
   
  templates:改文件夹存放就是所有的页面文件(.html)

   模板语法  jinja2支持前端直接使用类似于python的语法操作数据
   

{{ user_dic }}


   

{{ user_dic.name }}


   

{{ user_dic['password'] }}


   

{{ user_dic.get('name') }}


 
   {% for user in user_dict %} 
    
       {{ user.id }}
       {{ user.name }}
       {{ user.password }}
    
   {% endfor %}
#案例 *****自定制server.py***** import socket import time def f1(): fp = open('index.html','r',encoding='utf-8') data = fp.read() fp.close() return bytes(data,encoding='utf-8') def f2(): fp = open('article.html','r',encoding='utf-8') data = fp.read() ctime = time.time() data = data.replace('@@content@@',str(ctime)) return bytes(data, encoding='utf-8') def f3(): import pymysql conn = pymysql.connect(host='127.0.0.1',user='root',password='123',db='db1',charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = 'select id,name,depart_id from userinfo' cursor.execute(sql) res = cursor.fetchall() print(res) res_list = [] for user in res: res_str = "%s%s%s"%(user["id"],user['name'],user["depart_id"]) res_list.append(res_str) s="".join(res_list) fp = open('content.html','r',encoding='utf-8') data = fp.read() fp.close() data = data.replace("@@content@@", s) return bytes(data,encoding='utf-8') def f4(): import pymysql conn = pymysql.connect(host='127.0.0.1',user='root',password='123',db='db1',charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = 'select id,name,depart_id from userinfo' cursor.execute(sql) users = cursor.fetchall() # print(res) fp = open('content-jinjia2.html','r',encoding='utf-8') data = fp.read() fp.close() from jinja2 import Template template = Template(data) data = template.render(users = users) return bytes(data,encoding='utf-8') routers = ( ('/ooo',f1), ('/xxx',f2), ('/hhh',f3), ('/kkk',f4) ) def run(): server = socket.socket() server.bind(("127.0.0.1",1688)) server.listen(5) while True: client,addr = server.accept() buf = client.recv(1024) data = str(buf,encoding='utf-8') header_list = data.split('\r\n\r\n')[0].split('\r\n')[0] uri = header_list.split(' ')[1] #第一种方式:缺点:扩展性差 # res = None # if uri == '/xxx': # res = bytes("this is xxx",encoding='utf-8') # elif uri == '/ooo': # res = bytes("this is ooo", encoding='utf-8') # else: # res = bytes('404 not fund',encoding='utf-8') #第二种:路由方式 func_name = None for item in routers: if uri == item[0]: func_name = item[1] break if func_name: res = func_name() else: res = b'404 not fund' client.send(bytes('HTTP/1.1 200 OK\r\n\r\n',encoding='utf-8')) client.send(res) client.close() if __name__ == '__main__': run() *************index.html 静态显示********** "en"> "UTF-8"> Title

this is index

***********article.html 可以替换自定义内容动态显示时间********** "en"> "UTF-8"> Title @@content@@ *********content.html 可以替换自定义显示内容********* "en"> "UTF-8"> Title "1px"> @@content@@
ID Name department_id
*********content-jinjia2.html使用第三方工具渲染********* "en"> "UTF-8"> Title "1px"> {%for item in users%} {%endfor%}
ID Name department_id
{{item.id}} {{item.name}} {{item.depart_id}}

#2、web框架分类:
  a. sokect 服务端 b、路由系统 c、模板引擎渲染
  
 第一种维度分类:
  - a,b,c  ----> tornado
  - a(用第三方), b, c ----> django wsgiref  uwsgi
  - a(第三方),b, c(第三方) -----》 flask 

 注:
  
   web服务网关接口
         WSGI协议
         wsgiref(django自带的 可承受的并发量不是很高 通常指用于本地测试)
         uwsgi  (django项目上线之后会使用)
         werkzeug (flask使用的)
        实现WSGI协议的功能模块
        ps:
          请求来的时候处理http格式的数据
          请求走的时候讲后端发送的数据打包成符合http格式的数据再发送
 


python三大主流web框架
 Django:大而全,自带了很多功能模块,类似于航空母舰 (缺点:有点笨重)
 Flask:短小精悍,自带的功能模块特别少,大部分都是依赖于第三方模块(小而轻)
 Tornado:异步非阻塞 主要用在处理高io 多路复用的情况 可以写游戏后端
 
 第二种维度:
  
  - django
  - 其他

   Python Day 54 Django框架、web请求流程、状态码、自定义web框架_第1张图片

 

  ##Django基础

#1、安装:
    pip3 install django==1.11.10 -i https://pypi.tuna.tsinghua.edu.cn/simple 


#2、创建:
    创建django项目的方式
      方式1(命令行创建):
         创建django项目
            django-admin startproject 项目名
         创建app应用
            python3 manage.py startapp app01
         启动django项目
            python3 manage.py runserver
         ps:用命令行创建django默认不会自动创建templates文件夹
         需要你手动自己创建(注意改文件夹路径是否被添加配置文件中)
       方式2(pycharm创建)
         FILE >>> new project 选择第二个django 需要注意名字不能有中文,选择本地的解释器,勾选后台管理
         创建app
            pycharm命令行创建
               python3 manage.py startapp app01
            Tools下面run manage task功能栏
         启动点小绿色箭头
   
  
  强调:
     1.用django一定要保证只有一个在运行状态  切记切记!!!!!!!
     2.一定记得清浏览器的缓存
  
  app(应用)的概念
     一个django项目就是一所大学
     app就是大学里面的学院
  注意新创建的app需要在配置文件中注册才能生效(*******************)
    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
     'app01.apps.App01Config'  # 可以用全称
     'app01'      # 也可以简写
  ]
#3、目录介绍: 应用名
     migrations  数据库迁移记录相关数据
     admin.py    django后台管理相关
     models.py   模型表相关
     views.py    视图函数相关 mysite: mysite项目名: settings.py : 用户自定义的各种配置 urls.py : 路由与视图含书映射关系 wsgi.py : 启动socket服务端的 文件 mange.py: django入口文件、 管理文件、 python mange.py 各种命令
     templates:项目用到的所有的html文件 js, css, img : 静态 文件
#4、以后创建django完成之后: a. 配置末班文件路径: 'DIRS': [os.path.join(BASE_DIR, 'templates')] b. 配置静态资源的文件路径: STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), (逗号不能少) ) c. 注释中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
#5、写业务逻辑的话:
    
    uri和函数的对应关系:
     urlpatterns = [
      # url(r'^admin/', admin.site.urls),
      url(r'^index/', index),
     ]
    
    业务逻辑函数:
    
     def index(request):
      return render(request, "index.html")

   ##Django + 前端表单提交数据到后台

#django小白必会三板斧
#
HttpResponse:它是作用是内部传入一个字符串参数,然后发给浏览器。 # render:render方法可接收三个参数,一是request参数,二是待渲染的html模板文件,三是保存具体数据的字典参数。 它的作用就是将数据填充进模板文件,最后把结果返回给浏览器。与jinja2类似。 #redirect   重定向 又走了一次网络请求 注意:django必会三板斧返回的都是HttpReponse对象
#1、创建一个Django项目(功能:数据库验证登录、登陆失败标红从新渲染、登陆成功跳转) #1-1、完成三件事(上述有讲解 ,此处省略) #1-2、路由文件urls.py中 添加路由 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/',index), url(r'^login/',login), ] 创建相对应函数 def index(request): return render( request, 'index.html', { "username":"icon", "mylist":["icon",'is','18'], "mydict":{"name":"icon","age":"18"}, "userinfo":[ {"name":"icon1","age":"18","sex":"male"}, {"name":"icon2","age":"19","sex":"male"}, {"name":"icon3","age":"20","sex":"male"}, {"name":"icon4","age":"21","sex":"male"}, ] }, ) def login(request): if request.method == 'GET': return render(request,'login.html') else: import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='123', db='db1', charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = 'select * from user' cursor.execute(sql) # 数据库数据列表套字典 users = cursor.fetchall() #前端传过来的用户信息和密码 username = request.POST.get('username') password = request.POST.get('password') for user in users: if username == user.get('username') and password == user.get('password'): return HttpResponseRedirect("/index/") return render(request,'login.html',{'error_msg':'用户名或密码错误'}) #1-3、在templates目录创建index.html文件 "en"> "UTF-8"> Title {#1、渲染:变量替换,替换的key必须和urls.py文件中一一对应#} {{ username }}
{#2、渲染:列表替换#} {#{{ mylist.0 }}#} {#{{ mylist.1 }}#} {#{{ mylist.2 }}#}
  • {{ mylist.0 }}
  • {{ mylist.1 }}
  • {{ mylist.2 }}

{#3、渲染:列表循环替换#}
    {% for item in mylist %}
  • {{ item }}
  • {% endfor %}

{#4、渲染:字典循环替换显示给用户#} {% for key,val in mydict.items %}
  • {{ key }} --- {{ val }}
  • {% endfor %}
    {% for key in mydict.keys %}
  • {{ key }}
  • {% endfor %}
    {#5、渲染:表格#} "1px"> {% for user in userinfo %} {% endfor %}
    name age sex
    {{ user.name }} {{ user.age }} {{ user.sex }}
    #1-4、在templates目录创建login.html文件 "en"> "UTF-8"> Title {# #}
    "/index/" method="post"> 用户名:"text" name="username" >
    密码:"password" name="password"> "color: red;">{{ error_msg }}
    "submit" value="登录">
    {##} {##}

     

    转载于:https://www.cnblogs.com/liangzhenghong/p/11158131.html

    你可能感兴趣的:(Python Day 54 Django框架、web请求流程、状态码、自定义web框架)