WebFramework-Basis-1st
周六,多云,记录生活分享点滴
参考博客:
推荐博客:https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/
Django 1.1
web框架
框架 framework
-
特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统
-
简单地说,就是你用别人搭建好的舞台来做表演
对于所有的Web应用,本质上是一个socket服务端;用户的浏览器是一个socket客户端。
import socket ? def handle_request(client): ? buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8")) client.send("Hello, yuan
".encode("utf8")) ? def main(): ? sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost',8001)) sock.listen(5) ? while True: connection, address = sock.accept() handle_request(connection) connection.close() ? if __name__ == '__main__': ? main()
最简单的Web应用:
-
先把HTML用文件保存好,
-
用一个现成的HTTP服务器软件,接收用户请求,
-
从文件中读取HTML,返回
如果要动态生成HTML,需要把上述步骤自己来实现:
-
底层代码由专门的服务器软件实现,
-
用Python专注于生成HTML文档
-
需要统一的接口(WSGI:Web Server Gateway Interface),用Python编写Web业务
-- -- -- -- -- -- -- -- -- -- web框架制作步骤 -- -- -- -- -- -- -- -- -- --
step 1
from wsgiref.simple_server import make_server ? ? def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'Hello, web!
'] ? ? httpd = make_server('', 8080, application) ? print('Serving HTTP on port 8000...') # 开始监听HTTP请求: httpd.serve_forever()
注意:
整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写, 我们只负责在更高层次上考虑如何响应请求就可以了。 ? application()函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器,我们可以挑选一个来用。 ? Python内置了一个WSGI服务器,这个模块叫wsgiref application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数: ? //environ:一个包含所有HTTP请求信息的dict对象; //start_response:一个发送HTTP响应的函数。 ? 在application()函数中,调用: ? start_response('200 OK', [('Content-Type', 'text/html')]) ? 就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。 start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每 个Header用一个包含两个str的tuple表示。 ? 通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。 ? 然后,函数的返回值b'Hello, web!
'将作为HTTP响应的Body发送给浏览器。 ? 有了WSGI,我们关心的就是如何从environ这个dict对象拿到HTTP请求信息,然后构造HTML, 通过start_response()发送Header,最后返回Body。
step 2
print(environ['PATH_INFO']) path=environ['PATH_INFO'] start_response('200 OK', [('Content-Type', 'text/html')]) f1=open("index1.html","rb") data1=f1.read() f2=open("index2.html","rb") data2=f2.read() ? if path=="/yuan": return [data1] elif path=="/alex": return [data2] else: return ["404
".encode('utf8')]
step 3
from wsgiref.simple_server import make_server ? def f1(): f1=open("index1.html","rb") data1=f1.read() return [data1] ? def f2(): f2=open("index2.html","rb") data2=f2.read() return [data2] ? def application(environ, start_response): ? print(environ['PATH_INFO']) path=environ['PATH_INFO'] start_response('200 OK', [('Content-Type', 'text/html')]) ? ? if path=="/yuan": return f1() ? elif path=="/alex": return f2() ? else: return ["404
".encode("utf8")] ? ? httpd = make_server('', 8502, application) ? print('Serving HTTP on port 8084...') ? # 开始监听HTTP请求: httpd.serve_forever()
step 4
from wsgiref.simple_server import make_server ? ? def f1(req): print(req) print(req["QUERY_STRING"]) ? f1=open("index1.html","rb") data1=f1.read() return [data1] ? def f2(req): ? f2=open("index2.html","rb") data2=f2.read() return [data2] ? import time ? def f3(req): #模版以及数据库 ? f3=open("index3.html","rb") data3=f3.read() times=time.strftime("%Y-%m-%d %X", time.localtime()) data3=str(data3,"utf8").replace("!time!",str(times)) ? ? return [data3.encode("utf8")] ? ? def routers(): ? urlpatterns = ( ('/yuan',f1), ('/alex',f2), ("/cur_time",f3) ) return urlpatterns ? ? def application(environ, start_response): ? print(environ['PATH_INFO']) path=environ['PATH_INFO'] start_response('200 OK', [('Content-Type', 'text/html')]) ? ? urlpatterns = routers() func = None for item in urlpatterns: if item[0] == path: func = item[1] break if func: return func(environ) else: return ["404
".encode("utf8")] ? httpd = make_server('', 8518, application) ? print('Serving HTTP on port 8084...') ? # 开始监听HTTP请求: ? httpd.serve_forever()
MVC和MTV模式
MVC模式:
将web应用分为
-
模型(M):模型负责业务对象与数据库的对象(ORM)
-
控制器(C):控制器(C)接受用户的输入调用模型和视图完成用户的请求
-
视图(V):视图负责与用户的交互(页面)
三层之间以一种插件形式,松耦合的方式连接在一起。
Django的MTV模式也是各组件之间为了保持松耦合关系,在定义上有点不同
Django的MTV分别代表:
-
Model(模型):负责业务对象与数据库的对象(ORM)
-
Template(模版):负责如何把页面展示给用户
-
View(视图):负责业务逻辑,并在适当的时候调用Model和Template
补充:Django还有一个url分发器:作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template
详情参考:
# 安装:pip3 install django 添加环境变量 # 1 创建project django-admin startproject mysite ---mysite ---settings.py ---url.py ---wsgi.py ---- manage.py(启动文件) # 2 创建APP python mannage.py startapp app01 # 3 settings配置 TEMPLATES STATICFILES_DIRS=( os.path.join(BASE_DIR,"statics"), ) STATIC_URL = '/static/' # 我们只能用 STATIC_URL,但STATIC_URL会按着你的STATICFILES_DIRS去找 # 4 根据需求设计代码 url.py view.py # 5 使用模版 render(req,"index.html") # 6 启动项目 python manage.py runserver 127.0.0.1:8090 # 7 连接数据库,操作数据 model.py
django的命令行工具
-
django-admin.py 是Django的一个用于管理任务的命令行工具,
-
django-admin startproject mysite
当前目录下会生成一个 mysite的工程,目录结构如下:
-
manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。
-
settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
-
urls.py ----- 负责把URL模式映射到应用程序。
2.在mysite目录下创建app应用
python manage.py startapp blog
3.启动django项目
python manage.py runserver 8080 # ip:端口,默认本地ip
当我们访问:http://127.0.0.1:8080/ 时就可以看到:
python manage.py makemigrations
同步数据库: python manage.py migrate
python manage.py flush
django-admin.py help startapp
admin 是Django 自带的一个后台数据库管理系统。
8.
python manage.py shell
这个命令和直接运行 python 进入 shell 的区别是:你可以在这个 shell 里面调用当前项目的 models.py 中的 API,对于操作数据,还有一些小测试非常方便。
9.查看详细列表
python manage.py
实例练习1-提交数据并展示
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1>创建个人信息h1>
?
<form action="/userInfor/" method="post">
?
<p>姓名<input type="text" name="username">p>
<p>性别<input type="text" name="sex">p>
<p>邮箱<input type="text" name="email">p>
<p><input type="submit" value="submit">p>
?
form>
?
<hr>
?
<h1>信息展示h1>
?
<table border="1">
?
<tr>
<td>姓名td>
<td>性别td>
<td>邮箱td>
tr>
{% for i in info_list %}
?
<tr>
<td>{{ i.username }}td>
<td>{{ i.sex }}td>
<td>{{ i.email }}td>
tr>
?
{% endfor %}
?
table>
?
body>
html>
?
?
-----------------------url.py---------------------------------------
url(r'^userInfor/', views.userInfor)
?
-----------------------views.py--------------------------------------
?
info_list=[]
?
def userInfor(req):
?
if req.method=="POST":
username=req.POST.get("username",None)
sex=req.POST.get("sex",None)
email=req.POST.get("email",None)
?
info={"username":username,"sex":sex,"email":email}
info_list.append(info)
?
return render(req,"userInfor.html",{"info_list":info_list})
实例练习2-提交数据并展示(数据库)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1>创建个人信息h1>
?
<form action="/userInfor/" method="post">
?
<p>姓名<input type="text" name="username">p>
<p>性别<input type="text" name="sex">p>
<p>邮箱<input type="text" name="email">p>
<p><input type="submit" value="submit">p>
?
form>
?
<hr>
?
<h1>信息展示h1>
?
<table border="1">
?
<tr>
<td>姓名td>
<td>性别td>
<td>邮箱td>
tr>
{% for i in info_list %}
?
<tr>
<td>{{ i.username }}td>
<td>{{ i.sex }}td>
<td>{{ i.email }}td>
tr>
?
{% endfor %}
?
table>
?
body>
html>
?
?
----------------------------------------------models.py
from django.db import models
?
# Create your models here.
?
?
class UserInfor(models.Model):
?
username=models.CharField(max_length=64)
sex=models.CharField(max_length=64)
email=models.CharField(max_length=64)
?
----------------------------------------------views.py
?
from django.shortcuts import render
?
from app01 import models
# Create your views here.
?
?
def userInfor(req):
?
if req.method=="POST":
u=req.POST.get("username",None)
s=req.POST.get("sex",None)
e=req.POST.get("email",None)
?
?
#---------表中插入数据方式一
# info={"username":u,"sex":e,"email":e}
# models.UserInfor.objects.create(**info)
?
#---------表中插入数据方式二
models.UserInfor.objects.create(
username=u,
sex=s,
email=e
)
?
info_list=models.UserInfor.objects.all()
?
return render(req,"userInfor.html",{"info_list":info_list})
?
return render(req,"userInfor.html")
Setting文件配置
参考博客:
方法一
静态文件在单独的app下:如 /app01/static/app01/JS/jquery-2.1.4.min.js
(其中蓝色app01目录为必须,但可改其他名字,static文件夹也可改其他名字)
# index.html
{% load static %}
setting文件设置: (其中app01为项目名字,static为保存静态文件的文件夹。)
STATIC_URL = '/whattttt/' # 前端使用前缀 STATICFILES_DIRS = ( os.path.join(BASE_DIR,'app01','static'), )
方法二(同上述setting配置)
# index.html
方法三(使用别名的形式)
# index.html
{% load static %}
setting文件设置
STATIC_URL = '/whattttt/' STATICFILES_DIRS = ( ('biemin',os.path.join(BASE_DIR,'app01','static','app01')), )
补充:
如果不想每次在模版中加载静态文件都使用 {% load static%}
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , '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', ], #添加在这个位置 'builtins' : [ 'django.templatetags.static' ], }, }, ]
补充:pycharm创建django项目
主要总结一下在pycharm中进行django的创建遇到的问题
对于django的安装和pipenv虚拟环境的设置可参考:https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/59/
1.如果选择pipenv虚拟环境下创建django项目时,情况如下图
2.然后进行创建中
3.当在运行过程中如果出现这下图类似的错误
4.可以尝试以下建议(https://pypi.tuna.tsinghua.edu.cn/simple)
5.修改完成后
6.再次重新创建django,现在无法打开,静静等待最下面的蓝色字母运行完成(我的电脑需要运行一两分钟,有的是秒建,不知道什么原因)
7.然后就可以正常运行django了
8.总结
需要修改文件夹下Pipfile文件中sours下的url,修改为 https://pypi.tuna.tsinghua.edu.cn/simple
在此非常感谢群里的小伙伴提供的帮助,折腾了很久,终于可以继续学习了