您的位置:首页 > 编程语言 > Python开发

python之路_初识django框架

2020-01-14 04:50 381 查看

一、WEB框架介绍

  互联网刚兴起的那段时间大家都热衷于CS架构,也就是Client/Server模式。每个用户的电脑上安装一个Client,就像QQ这种终端软件。随着互联网的发展,开发客户端显得越来越‘重’,BS架构(Browser/Server模式)越来越流行,也就是用户只需要一个浏览器就足够了。

1、页面显示的过程

2、HTTP协议

  所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。用户的浏览器一输入网址,会给服务端发送数据,那浏览器会发送什么数据?怎么发?这个谁来定?HTTP协议。HTTP协议就是解决这个问题,它规定了发送消息和接收消息的格式

  每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。HTTP响应的Header中有一个

Content-Type
表明响应的内容格式。如
text/html
表示HTML网页。
(1)HTTP请求

  HTTP GET请求的格式:

  HTTP POST请求格式:

(2)HTTP响应

  HTTP响应的格式:

3、自定义WEB框架

  WEB应用本质就是一个sockect服务端,只要让我们的Web框架在给客户端回复响应的时候按照HTTP协议的规则加上响应头,这样我们就实现了一个正经的Web框架。如下简单实例:开启服务端后,在浏览器上输入网址:127.0.0.1:8090/index/后就会向浏览器返回:这是主页内容

from socket import socket
server=socket()
server.bind(("127.0.0.1",8090))
server.listen(5)
while True:
conn,addr=server.accept()
data = conn.recv(1024).decode()                                                      #data为请求的HTTP格式
print(data)
header=data.split("\r\n\r\n")[0]                                                     #获得请求header部分
temp=header.split("\r\n")[0]                                                         #获得header中包含请求路径的第一行
url=temp.split(" ")[1]                                                               #获得请求路径
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n')       #返回HTTP响应格式内容
#根据路径不同返回不同的内容
if url=="/index/":
response="这是主页"
else:
response="404"
conn.send(bytes(response,encoding="utf-8"))
 

如下为上述实例接收到HTTP请求的data内容:

GET /index/ HTTP/1.1                                              #header部分
Host: 127.0.0.1:8090
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

GET /favicon.ico HTTP/1.1                                         #body部分
Host: 127.0.0.1:8090
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8090/index/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

  上述实例我们可以从请求头里面拿到请求的URL,然后做一个判断,我们的Web服务根据用户请求的URL不同而返回不同的内容。但是问题又来了,如果有很多很多页面怎么办?难道要挨个判断?当然不用,我们有更聪明的办法。

from socket import socket
server=socket()
server.bind(("127.0.0.1",8090))
server.listen(5)
def index():
return "这是主页"
def info():
return "这是个人信息页"
func_list=[
("/index/",index),
("/info/",info)
  ]
while True:
conn,addr=server.accept()
data = conn.recv(1024).decode()
header=data.split("\r\n\r\n")[0]
temp=header.split("\r\n")[0]
url=temp.split(" ")[1]
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n')
func_name=None
for i in func_list:
if url==i[0]:
func_name=i[1]
break

if func_name:
response=func_name()
else:
response="404"
conn.send(bytes(response,encoding="utf-8"))

  完美解决了不同URL返回不同内容的问题。但是我不想仅仅返回几个字符串,我想给浏览器返回完整的HTML内容,这又该怎么办呢?没问题,不管是什么内容,最后都是转换成字节数据发送出去的。我可以打开HTML文件,读取出它内部的二进制数据,然后发送给浏览器。

from socket import socket
server=socket()
server.bind(("127.0.0.1",8090))
server.listen(5)
def index():
with open("index.html",encoding="utf-8") as f:
data_html=f.read()                                         #读取html程序,本质是字符串
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='', database='day65', charset='utf8')
cur = conn.cursor(cursor=pymysql.cursors.DictCursor)           # 设置查询结果以字典形式显示
sql = "select id,name,balance from user"
cur.execute(sql)
use_list = cur.fetchall()
print(use_list)#[{'id': 1, 'name': 'egon', 'balance': 10000}, {'id': 2, 'name': 'alex', 'balance': 2000}, {'id': 3, 'name': 'wsb', 'balance': 20000}]
ret=""
for i in use_list:
ret+="""
<tr>
<td>{0}</td>
<td>{1}</td>
<td>{2}</td>
</tr>
""".format(i["id"],i["name"],i["balance"])
cur.close()
conn.close()
data_new=data_html.replace("@@xx@@",ret)                        #将html中的占位内容用数据库中查询的结果组成的字符替换
return data_new                                                 #返回替换数据的html字符串

index()
def info():
return "这是个人信息页"
func_list=[
("/index/",index),
("/info/",info)
]
while True:
conn,addr=server.accept()
data = conn.recv(1024).decode()
header=data.split("\r\n\r\n")[0]
temp=header.split("\r\n")[0]
url=temp.split(" ")[1]
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n')
func_name=None
for i in func_list:
if url==i[0]:
func_name=i[1]
break
if func_name:
response=func_name()
else:
response="404"
conn.send(bytes(response,encoding="utf-8"))

  上述代码模拟了一个web服务的本质,而对于真实开发中的Python Web程序来说,一般分为两部分:服务器程序和应用程序。服务器程序负责对

Socket
服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架。

  不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。一旦标准确定,双方根据约定的标准各自进行开发即可。WSGI(Web Server Gateway Interface)就是这样一种规范,它定义了使用Python编写的Web APP与Web Server之间接口格式,实现Web APP与Web Server间的解耦。

二、django框架

1、框架介绍

  根据第一部分内容介绍,我们可以总结出一个web框架应该包含如下三部分:a.sockect服务、b.根据不同的url调用不同函数(包含逻辑)、c.返回内容(模板渲染)。常见的python WEB框架有tornado(包含如上3部分, Django(上述a部分为第三方的),flask(上述a和c为第三方的)。

2、Django安装

  Django框架安装:

  命令行创建django项目(首先将cd到django项目欲放置的位置):

  命令行开启django服务端(首先将cd到django项目文件夹的位置):

python manage.py runserver

  上述开启的服务的默认端口为:127.0.0.1:8000,如果需要指定端口,则在上述命令后空格直接跟指定的ip和端口

 3、目录介绍

4、配置文件

  模板文件配置:在python中创建一个django项目后,在项目文件夹下会多一个templates文件夹,主要用于存放html模板文件,若要准确找到引用的html文件,需要在setting文件中对此文件夹路径进行配置。如下:

  静态文件配置:在使用html模板文件时,其通常会有使用js或css等文件,这些文件称为静态文件,为了使其正常生效,我们也需要在setting文件进行相关配置,如下:

  html文件中引用静态文件的方式如下:

5、入门三件套

  (1)HttpResponse:用于向服务端返回字符串,如启动服务后,在浏览器请求:127.0.0.1:8000/index/后,浏览器显示hello world字符内容

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse
def index(request):
return HttpResponse("hello world")

urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^index/', index),
]

  (2)render:用于渲染html文件,如启动服务后,在浏览器请求:127.0.0.1:8000/login/后,浏览器会显示login.html文件应被渲染出的结果

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import render                   #render用于渲染html文件
def login(request):                                   #request就代表了请求的所有内容
return render(request,"login.html")

urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^login/', login),
]

   (3)redirect:用于跳转到指定的连接,实例如下:当启动服务端后,在浏览器请求:127.0.0.1:8000/login/后,会显示login.html被渲染的登录界面,提交后若判断登录成功,则会跳转到指定的网页。

login.html文件主要代码:

<body>
<h1>欢迎登录</h1>
<form action="/login/" method="post">                           //action为提交路径,action为请求方式
<p><input type="text" name="username"></p>
<p><input type="password" name="userpswd"></p>
<p><input type="submit" value="提交"></p>
{{ error_msg }}                                             //模板语言,不传值不会显示
</form>
</body>

项目中url逻辑代码:

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse,render,redirect
def login(request):
if request.method=="GET":                 #request.method表示请求类型
return render(request,"login.html")
else:#当点击提交按钮执行
print(request.method)                 #结果:POST
print(request.POST)                   #结果为登录输入的用户名及密码<QueryDict: {'uesername': ['zhangli'], 'userpswd': ['123']}>
if request.POST.get("username")=="zhangli" and request.POST.get("userpswd")=="123":
return redirect("http://www.baidu.com") #如果登录成功,则跳转其他页面
else:
return render(request, "login.html", {"error_msg": "用户名或密码错误"})       #有html有模板语言(占位用)时render用法
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^login/', login),
]

6、模板语言

  主要用于html文件中,暂时主要介绍两种:用于实现循环和占位,占位已在上一节展示,此处不再演示,主要介绍循环模板,如下例:

index.html文件主要代码:

<body>

<table border="1">
<thead>
<tr>
<th>#</th>
<th>姓名</th>
<th>工资</th>
</tr>
</thead>
<tbody>
{% for i in user_list %}
<tr>
<td>{{ i.id }}</td>
<td>{{ i.name }}</td>
<td>{{ i.balance }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>

项目中url代码:

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse,render,redirect
def index(request):
import pymysql
conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="", db="day65", charset="utf8")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select id, name, balance from user")
user_list = cursor.fetchall()
cursor.close()
conn.close()
print(user_list)#查询结果为:[{'id': 1, 'name': 'egon', 'balance': 10000}, {'id': 2, 'name': 'alex', 'balance': 2000}, {'id': 3, 'name': 'wsb', 'balance': 20000}]
return render(request, "index.html", {"user_list": user_list})

urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^login/', login),
url(r'^index/', index),
]

转载于:https://www.cnblogs.com/Ebola-/p/8734099.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
deyun201442 发布了0 篇原创文章 · 获赞 0 · 访问量 112 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: