web框架

views.py 里面放的是函数 视图层

urls.py 里面放的是 路由(后缀)与视图函数对应的关系 路由层

templates文件夹 里面放的全是HTML文件 模板层

env:请求相关的所有的所有数据 将http数据全部提前处理成字典的形式 供调用者使用

response:响应相关的所有数据

return:给前端真正的数据

make_server:实时监听本机8080的端口

from wsgiref.simple_server import make_server
from urls import urls
from views import *

def run(env,response):
    """
    :param env: 请求相关的所有数据 将http数据全部提前处理成了字典的形式 供调用者使用
    :param response: 响应相关的所有数据
    :return: 给前端真正的数据
    """
    # print(env)
    response('200 OK',[('xxx','jason'),])
    current_path = env.get('PATH_INFO')
    # print(current_path)
    # if current_path == '/index':
    #     return [b'index']
    # elif current_path == '/login':
    #     return [b'login']
    # 定义一个存储函数名的标志位
    func = None
    for url in urls:  # url =  ('/login',login)  ('/index',index)
        if current_path == url[0]:  # 用户敲的后缀名 你后端有对应的处理业务
            func = url[1]  # 将匹配上的函数名赋值给func变量
            break  # 一旦用户匹配上了对应的业务接口 立刻结束匹配
    # 判断func是否被赋值
    if func:
        res = func(env)
    else:
        res = error(env)
    return [res.encode('utf-8'),]


if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run)  # 实时监听本机8080端口
    # 一旦有请求来了 会统一交给run函数处理(调用run函数并传参run(env,response))
    server.serve_forever()  # 启动服务端

后端的数据可以利用字符串替换的方式传递给html页面

将user_dic传递给html页面,页面上通过userDic就能拿到后端传递过来的值

动静态网页

  • 静态网页

    数据是写死的,如果改变了,也是认为改变的

  • 动态网页

    数据是实时获取的

    后端代码动态获取,当前的时间

    数据是从数据库查询出来的

jinja2模块语法

专门用来处理后端数据与html页面的交互

<p>{{ userDic }}</p>
		<p>{{ userDic.username }}</p>
		<p>{{ userDic['age'] }}</p>
		<p>{{ userDic.get('hobby') }}</p>
		<p>{{ userDic.get('hobby').0 }}</p>
		<p>{{ userDic.get('hobby').1 }}</p>
		<p>{{ userDic.get('hobby').2 }}</p>
		
		{% for user_dic in user_list %}
			<tr>
				<td>{{ user_dic.id }}</td>
				<td>{{ user_dic.username }}</td>
				<td>{{ user_dic.password }}</td>
			</tr>
		{% endfor %}

模板的渲染:将后端传递给html文件的数据,在后端处理好,生成一个完整的html文件的过程

注意:模板的渲染是在后端完成的 跟前端没有关系

python三大主流的web框架

django 主要特点是大而全,集成了很多的组件,全能型的框架

优点:

  • 大和全(重量级框架)
  • 自带orm,template,view
  • 需要的功能也可以去找第三方的app
  • 注重高效开发
  • 全自动化的管理后台(只需要使用起orm,做简单的定义,就能自动生成数据集结构,全功能的管理后台)
  • session功能

缺点:

  • template不怎么好用
  • 数据库用nosql不方便
  • 如果功能不多,容易臃肿

flask

主要特点小而轻,原生的组件基本为0,第三方提供的组件非常全面,属于短小精悍型框架

优点:

  • 简单,flask的路由以及路由函数由修饰器设定,开发人员需要借助其他文件匹配
  • 配置灵活,有多种方法的配置,不同环境的配置也非常方便,环境部署简单,flask运行不需要借助其他任何的软件,只需要安装python的IDE,在命令行运行即可。只需要在python中导入响应的包即可满足所有的需求
  • 入门简单,通过官方指南便可以清楚的了解flask的运行流程
  • 低耦合,flask可以兼容多种数据库、模板

缺点:

对于大型网站开发,需要设计路由映射的规则,否则导致代码混乱

Torando

主要特点是原生异步非阻塞,在IO密集型应用和多任务处理上占据绝对性的优势,属于专注型框架

优点:

  • 少而精(轻量级框架)
  • 注重性能优越,速度快
  • 解决高并发(请求处理是基于回调的非阻塞调用)
  • 异步非阻塞
  • websockets长连接
  • 内嵌了HTML服务器
  • 单线程的异步网络程序,默认启动时根据CPU数量运行多个实例;利用CPU多核的优势
  • 自定义模块

缺点:

模板和数据库部分有很多第三方的模块可以选择,这样不利于封装为一个功能模块

wsgiref是web服务器网关的接口,是web服务器软件和用python编写的web应用程序之间的标准接口

django框架的介绍

注意事项:

  • 计算机的名称不能是中文的
  • python解释器版本不要使用3.7版本,推荐使用3.4-3.6的版本
  • 一个pycharm窗口 只能运行一个项目

django版本问题

django版本以1.11.11为主,推荐的版本范围(1.11.9-1.11.13)因为他们在维护的范围内,一般不会出现问题

校验django安装成功的命令 django-admin

命令行创建项目

1、创建django项目

django-admin startproject 项目名(例如mysite)

2、启动django项目

首先切换到项目文件夹下(cd mysite)

python3 manage.py runserver

python3 manage.py runserver 127.0.0.1:8080(后面可以跟host和port)

3、创建应用(django支持创建多个app应用)

python3 manage.py startapp app01

注意

  1. 不会自动帮你创建teplates文件夹
  2. 配置文件中不会自动帮你书写templates文件路径

创建好的app需要在django配置文件中注册方可有效

INSTALLED_APPS = [
			'django.contrib.admin',
			'django.contrib.auth',
			'django.contrib.contenttypes',
			'django.contrib.sessions',
			'django.contrib.messages',
			'django.contrib.staticfiles',
			# 'app01'  # 简便写法
			'app01.apps.App01Config'  # 最完整的写法
		]

app的概念

django是一个以开发为主的web框架

app就是类似于一所大学(空的架子,本身没有任何的功能),而app就是一个个的学院

一个空的django本身没有任何的作用,只是为app提供前期的环境的配置

一个app对应一个功能模块,你可以开发多个app,每个app之间是独立的,解耦合的思想

利用pycharm创建项目

1.创建应用的时候,可以使用简便的方式

启动服务,可以点击Edit Cfig...功能按钮,可以在里面移除服务,也可以重新添加(可以修改项目的名字name,主机地址和端口)

Tools——>run manage.py task(运行管理任务),运行管理服务,输入startapp app01(可以创建应用app01)

在应用上线时,可以修改settings里面的ALLOWED_HOSTS=["*"](允许所有的主机)

创建好的app应用需要在settings中注册才能生效,注册的两种方法:方法1:'app01'(这是创建的应用的名称)方法2:‘app01.apps.App01Config’

2.一定要确保同一个端口,同一时间只能启动一个django项目

3.配置文件中针对templates文件夹的路径,如果是空的需要手动配置(如果是用命令创建的时候,'DIRS':里面可能没有内容,这个时候需要手动添加,复制粘贴)

'DIRS': [os.path.join(BASE_DIR, 'templates')]

settings里面的数据库是django自带的,后期可以替换成mysql或者其他的数据库

django功能目录

django项目名
	项目同名的文件夹
		settings.py   配置文件
		urls.py    路由与视图函数对应关系
	manage.py   django的入口的文件
	应用名文件夹
		migrations文件夹   所有数据库相关的操作记录
		admin.py     django  admin后台管理
		apps.py      注册app使用
		models.py    放所有数据库相关的模型类
		tests.py      测试文件
		views.py     处理业务逻辑的视图文件函数

django基本的配置及注意事项

django小白的三板斧

Httpresponse 返回字符串

在urls.py文件中导入from app01 import views

在urls.py文件中的urlpatterns中添加(后缀index,对应views中定义的index函数)url(r'^index/',views.index),

去views中定义函数def index(request),导入TttpResponse(返回字符串)和redirect(重定向)库

然后返回TttpResponse('返回字符串')这里面的内容必须用括号内字符串,然后启动manage.py入口文件,这里加载的页面是127.0.0.1:8000,

这时会显示(找不到页面404),下面提示的后缀有默认的admin和自定义index,点击页面输入后缀index就会显示定义的结果,输入admin会进入django管理登录页面

在urls中添加login后缀,在views中定义def login(request): 在templates中新建一个HTML文件,随便添加一个(行标签p,随便输入内容) return render(request,'login.html') 返回HTML文件,render可以给HTML传值,返回html文件。

如果想要返回其他的信息,在login下面添加一个user_dic字典,在返回的位置后面加上{'xxx':user_dic},回到login.html中的h行下面添加双花括号内是字典{{xxx.username}}通过点的方式,点出需要的信息,

它是只支持点的方式,不支持get获取值的方式。

render        返回html文件
		
					  可以给html页面传值
						def login(request):
							user_dic = {'username':'jason','password':'123'}
							return render(request,'login.html',{'xxx':user_dic})
		
		
		redirect       重定向
					
						1.直接写你本网站的路径后缀
						2.也可以全路径
		
						def home(request):
							# return redirect('/login')  # 重定向
							return redirect('https://www.baidu.com')  # 重定向

注意
django默认是自动重启的
重启机制
内有检测机制 实时检测所有文件的变化
有时候会产生 你代码还没写完 就自动重启报错的情况 不用管
每次写完代码之后 自己手动重启

1.下面这段代码的输出结果是什么,并给出你的解释
def index():
    return [lambda x : i * x for i in range(4)]
print([m(2) for m in index()]) 
结果:[6,6,6,6]
相对而言的局部变量绑定的是值,非局部变量绑定过的是空间,而不是本身,所以,for循环生成的i,相对于函数lam来说,是全局变量,所以绑定的是i所在的内存地址,但i最后变成了3,lam绑定的是3

2.有一个列表[3,4,1,2,5,6,6,5,4,3,3]请写出一个函数,找出该列表中没有重复的数的总和
#方法一
def func(l):
    dic = {}
    s = 0
    for i in l:
        if i not in dic:
            dic[i] = 1
        else:
            dic[i] += 1
    for k, v in dic.items():
        if v == 1:
            s += k
    return s

l = [3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3]
print(func(l))

#方法二
from collections import Counter
def func(l):
    dic = Counter(l)
    s = 0
    for k, v in dic.items():
        if v == 1:
            s += int(k)
    return s
l = [3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3]
print(func(l))

3.什么是函数的递归调用?书写递归函数需要注意什么?你能否利用递归函数打印出下面列表中每一个元素(只能打印数字),l = [1,[2,[3,[4,[5,[6,[7,[8,[9]]]]]]]]]
l = [1, [2, [3, [4, [5, [6, [7, [8, ]]]]]]]]

def func1(listl):
    for item in listl:
        if type(item) is not list:
            print(item)
        else:
            func1(item)
func1(l)


or 


def get(seq):
    for item in seq:
        if type(item) is list:
            get(item)
        else:
            print(item)
get(l)