一、web框架
socket可以实现服务端和客户端基于网络的通信,它们之间遵循定义好的规则。
现实生活中,客户端许多都是浏览器,这就需要服务端能和浏览器进行通信,它们之间也要遵循一定的规则,这就是http协议。
HTTP协议:超文本传输协议(英文:HyperText Transfer Protocol)是一种用于分布式、协作式和超媒体信息系统的应用层协。HTTP是万维网的数据通信的基础。
1、实现不同的网址返回不同的内容,包括HTML网页和动态的网页
import socket
import time
sk = socket.socket()
sk.bind(("127.0.0.1", 8080))
sk.listen(5)
def home(url):
with open("home.html", "r") as f:
html_msg = f.read()
now = time.time()
msg = html_msg.replace("@@xx@@", str(now)) #动态内容需要用真实内容替换网页的占位字符串
return bytes(msg, encoding="utf8") # 转成bytes类型返回,返回的是home.html网页文件
def index(url):
return b"index page!"
def user(url):
return b"user page!"
# 定义一个URL和函数的对应关系
url_func = [
("/index/", index),
("/home/", home),
("/user/", user),
]
while 1:
# 建立连接
conn, addr = sk.accept()
# 收消息
data = conn.recv(8096)
data_str = str(data, encoding="utf8")
# 拿到用户访问的具体URL
url = data_str.split("\r\n")[0].split()[1]
func = None
for i in url_func:
if i[0] == url:
func = i[1]
break
if func:
msg = func(url)
else:
msg = b"404!"
# 回复消息
conn.send(b"HTTP/1.1 200 OK\r\n\r\n") # 响应行,后面第一个\r\n表示换行,第二个\r\n表示空行
conn.send(msg) # 发送响应体
conn.close()
home.html网页内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>home</title>
</head>
<body>
<h1>This is home page!</h1>
<img width="600" src="http://img1.xiazaizhijia.com/walls/20160421/1440x900_a03dc8525ec35b5.jpg" alt="">
<p>@@xx@@</p>
</body>
</html>
二、服务器程序和应用程序
对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。
服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。
应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。
1、常用的Python Web框架
Tornado框架:自己可以接收浏览器发送的消息,根据不同的路径返回不同的内容,通过字符串替换 实现 动态网页
Django框架:自己可以根据不同的路径返回不同的内容,通过字符串替换 实现 动态网页,需要使用第三方服务接收浏览器发送的消息
Flask框架:自己可以根据不同的路径返回不同的内容,需要使用第三方服务实现通过字符串替换 实现 动态网页和接收浏览器发送的消息
WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。
常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。
2、wsgiref实现上面的web框架
import time
from wsgiref.simple_server import make_server
# 将返回不同的内容部分封装成函数
def index(url):
with open("index.html", "r", encoding="utf8") as f:
s = f.read()
now = str(time.time())
s = s.replace("@@oo@@", now)
return bytes(s, encoding="utf8")
def home(url):
with open("home.html", "r", encoding="utf8") as f:
s = f.read()
return bytes(s, encoding="utf8")
# 定义一个url和实际要执行的函数的对应关系
list1 = [
("/index/", index),
("/home/", home),
]
def run_server(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息
url = environ['PATH_INFO'] # 取到用户输入的url
func = None
for i in list1:
if i[0] == url:
func = i[1]
break
if func:
response = func(url)
else:
response = b"404 not found!"
return [response, ]
if __name__ == '__main__':
httpd = make_server('127.0.0.1', 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()
三、Django环境搭建
1、基础环境
官网下载:
https://www.djangoproject.com/download/
安装:
pip3 install django==1.11.9 #pip3是我们定义的第三版本的pip
2、创建Django项目
(1)使用命令创建名称为mysite的项目:
django-admin startproject mysite
(2)使用PyCharm创建项目
点击文件--->新项目--->在弹出框里填写其他信息
如图:
3、配置修改
setting.py文件修改:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "template")], #'DIRS'后面的中括号填写template文件夹位置
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware', #刚开始学习时可在配置文件中暂时禁用csrf中间件,方便表单提交测试。
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 在文件最后指定静态文件存放位置
STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"), # 静态文件存放位置,对应的在项目的同级目录建一个static目录
]
4、目录介绍:(mysite,static,template在同一级目录)
mysite:
manage.py # 管理文件
mysite # 项目目录
__init__.py
settings.py # 配置
urls.py # 路由 --> URL和函数的对应关系
wsgi.py # runserver命令就使用wsgiref模块做简单的web server
static:
bootstrap
jquery-3.3.1.min.js
template: #存放html页面
home.html
login.html
5、运行Django项目:
python manage.py runserver 127.0.0.1:8000
6、关于mysql数据库
在__init__.py文件中使用pymysql的功能:
import pymysql
pymysql.install_as_MySQLdb()
setting.py文件中配置连接mysql数据库:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 告诉Django连接数据库的类型
'NAME': 'book', #数据库的库,需要手动在mysql中先建好
'HOST': "127.0.0.1",
'PORT': 3306, # 不要加引号
'USER': "root",
"PASSWORD": "123456", # 要加引号
}
}
四、Django基础必备三件套
from django.shortcuts import HttpResponse, render, redirect
def index(request):
# 业务逻辑代码
return HttpResponse("OK") #返回给客户端“ok”
def index(request):
# 业务逻辑代码
return render(request, "index.html", {字典格式的参数}) #返回给客户端定义的index.html页面
def index(request):
# 业务逻辑代码
return redirect("/home/") #重定向,返回url为home的定义的内容,还可以返回网站url,如"http://www.baidu.com"
五、写一个返回html页面的Django项目
urls.py文件:
from django.conf.urls import url
from django.contrib import admin
from mysite import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^home/', views.home),
url(r'^index/', views.index),
url(r'^login/', views.login)
]
views.py文件:
from django.shortcuts import render
# Create your views here.
from django.shortcuts import HttpResponse, render, redirect
from mysite import models
def index(request):
# 所有和请求相关的数据都封装到了这个request参数中
# return HttpResponse("This is index page!")
return redirect("http://www.baidu.com") #返回百度站点的页面
def home(request):
return render(request, "home.html")
def login(request):
error_msg = ""
# 如果是POST请求,表示要提交数据了
if request.method == "POST":
# 从提交的数据中 取到email和pwd
email = request.POST.get("email2")
pwd = request.POST.get("pwd")
if email == "alex@1.com" and pwd == "alexdsb":
# 登录成功,跳转到网站首页
return redirect("
else:
error_msg = "邮箱或密码错误!"
return render(request, "login.html", {"error": error_msg})
login.html页面内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<title>登录注册示例</title>
<style>
body {
background-color: #eee;
}
</style>
</head>
<body>
<div>
<div>
<div class="col-md-4 col-md-offset-4" style="margin-top: 100px">
<h1>请登录</h1>
<form action="/login/" method="post" novalidate>
<div>
<label for="inputEmail3" class="col-sm-2 control-label">邮箱</label>
<div>
<input type="email" name="email2" id="inputEmail3" placeholder="Email">
</div>
</div>
<div>
<label for="inputPassword3" class="col-sm-2 control-label">密码</label>
<div>
<input type="password" name="pwd" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-8">
<p style="color: red">{{ error }}</p>
</div>
</div>
<div>
<div class="col-sm-offset-2 col-sm-10">
<div>
<label>
<input type="checkbox">记住我
</label>
</div>
</div>
</div>
<div>
<div class="col-sm-offset-2 col-sm-8">
<input type="submit" class="btn btn-primary btn-block" value="登录">
</div>
</div>
</form>
</div>
</div>
</div>
<script src="/static/jquery-3.3.1.min.js"></script>
</body>
</html>
启动项目后在浏览器访问:
127.0.0.1:8000/index/
127.0.0.1:8000/home/
127.0.0.1:8000/login/
转载于:https://blog.51cto.com/qidian510/2093643