Django 0.1
一、今日面試題(python全棧課前練習題)
------------------------------------------------
s = "Alex SB 哈哈\r\nx:1\r\ny:2\r\nz:3\r\n\r\n自行車"
# 問題1:如何取到["Alex SB 哈哈\r\nx:1\r\ny:2\r\nz:3", "自行車"]?
ret1 = s.split("\r\n\r\n")
print(ret1)
# 問題2:如何在上面結果基礎上拿到["Alex", "SB", "哈哈"]?
ret2 = ret1[0].split("\r\n")[0].split(" ")
print(ret2)
# 問題3:如何在上面結果基礎上拿到"SB"?
ret3 = ret2[1]
print(ret3)
----------------------------------------------
有一個列表,他的內部是一些元祖,元祖的第一個元素是姓名,第二個元素是愛好。現在我給你一個姓名,如"Egon",如果有這個姓名,就打印出他的愛好,沒有就打印查無此人。
list1 = [
("Alex", "燙頭"),
("Egon", "街舞"),
("Yuan", "喝茶")
]
for i in list1:
if "Egon" == i[0]:
print(i[1])
break
else:
print("查無此人")
-----------------------------------------
有一個HTML文件"login.html"
# 問題1:我如何讀取它的文本內容保存到變量html_s?
with open("login.html", "r", encoding="utf8") as f:
html_s = f.read()
print(html_s)
# 問題2:我如何讀取它的二進制內容保存到變量html_b?
with open("login.html", "rb") as f:
html_b = f.read()
print(html_b)
---------------------------------------------
s2 = "Alex 花了一百萬買了輛電動車,真@@xx@@。"
# 問題1:如何把上面的s2轉變成"Alex 花了一百萬買了輛電動車,真SB。"
ret4 = s2.replace("@@xx@@", "SB")
print(ret4)
---------------------------------------------
字節和字符串的相互轉換
s = "o98k"
ret = bytes(s, encoding="utf8")
print(ret)
b = b‘hello world!‘
ret2 = str(b, encoding="utf8")
print(ret2)
---------------------------------------------
HTTP協議:規定了瀏覽器和服務器之前發送信息的格式
請求(request):瀏覽器往服務端發送的消息
響應(response):服務端回復給瀏覽器的消息
二、今日內容
1、web框架本質
網址->IP地址和端口->找到網站服務器->把HTML文件發回給瀏覽器->按照HTML格式渲染成最終網頁
https://www.cnblogs.com/liwenzhou/p/8258992.html
半成品自定義web框架->加上http協議規則的web框架-> 根據不同的路徑返回不同的內容(若幹if判斷)->根據不同的路徑返回不同的內容(函數版,定義一個url和實際要執行的函數的對應關系)->返回具體的HTML文件->返回動態的HTML文件
返回動態的HTML文件
"""
根據瀏覽器訪問的路徑的不同,返回不同的內容
將不同頁面的處理代碼封裝到函數中
優化頻繁的if判斷
返回具體的HTML文件
實現不同的用戶得到不同的HTML頁面
"""
import socket
import time
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((‘127.0.0.1‘, 8888))
server.listen()
def home(url):
s = "this is {} page!".format(url)
return bytes(s, encoding="utf8")
def index(url):
return b‘<h1>index page</h1>‘. # 瀏覽器根據html標簽,自動渲染
def user(url):
# 不同的用戶得到的頁面上顯示不同的時間
c_time = str(time.time())
with open("user.html", "r") as f:
data_s = f.read()
data_s = data_s.replace("@@xx@@", c_time) # 替換後的字符串數據
return bytes(data_s, encoding="utf8")
def login(url):
with open("login.html", "rb") as f:
return f.read()
# url和將要執行的函數的對應關系
url2func = [
("/index", index),
("/home", home),
("/user", user),
("/login", login),
]
while 1:
conn, addr = server.accept()
data = conn.recv(8096) # 收消息
# print(data)
# 從瀏覽器發送消息中,拿到用戶訪問的路徑
data_str = str(data, encoding="utf8")
# print(data_str)
url = data_str.split("\r\n")[0].split(" ")[1]
print(url)
func = None
for i in url2func:
if url == i[0]:
func = i[1] # 拿到將要執行的函數
break
else:
func = None
if func:
msg = func(url) # 執行對應的函數
else:
msg = b‘<h1>404</h1>‘ # 找不到要執行的函數就返回404
# 按照HTTP協議的格式要求 回復消息
conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘) # 發送狀態行
conn.send(msg) # 發送響應體
conn.close()
2、服務器程序和應用程序
A.收發信息相關(socket)
B.根據不同的URL返回不同的內容(業務邏輯)
C.字符串替換(動態的網頁)
自己處理ABC –>Tornado(爬蟲常使用)
自己處理BC,第三方處理A ->Django(運維開發常使用)
自己處理B,第三方處理A,C->Flask(Web開發常使用)
另一個維度分類:
- Django(大而全)
- 其他
對於真實開發中的python web程序來說,一般會分為兩部分:服務器程序和應用程序。
服務器程序負責對socket服務器進行封裝,並在請求到來時,對請求的各種數據進行整理。
應用程序則負責具體的邏輯處理。為了方便應用程序的開發,就出現了眾多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的開發方式,但是無論如何,開發出的應用程序都要和服務器程序配合,才能為用戶提供服務。
WSGI(Web Server Gateway Interface)就是一種規範,它定義了使用Python編寫的web應用程序與web服務器程序之間的接口格式,實現web應用程序與web服務器程序間的解耦。
常用的WSGI服務器有uwsgi、Gunicorn。而Python標準庫提供的獨立WSGI服務器叫wsgiref,Django開發環境用的就是這個模塊來做服務器。
3、wsgiref
利用wsgiref模塊來替換我們自己寫的web框架的socket server部分
"""
根據瀏覽器訪問的路徑的不同,返回不同的內容
將不同頁面的處理代碼封裝到函數中
優化頻繁的if判斷
返回具體的HTML文件
實現不同的用戶得到不同的HTML頁面
"""
import time
from wsgiref.simple_server import make_server
def home(url):
s = "this is {} page!".format(url)
return bytes(s, encoding="utf8")
def index(url):
return b‘<h1>index page</h1>‘
def user(url):
# 不同的用戶得到的頁面上顯示不同的時間
c_time = str(time.time())
with open("user.html", "r") as f:
data_s = f.read()
data_s = data_s.replace("@@xx@@", c_time) # 替換後的字符串數據
return bytes(data_s, encoding="utf8")
def login(url):
with open("login.html", "rb") as f:
return f.read()
# url和將要執行的函數的對應關系
url2func = [
("/index", index),
("/home", home),
("/user", user),
("/login", login),
]
# 按照wsgiref的要求定義一個run_server函數
def run_server(environ, start_response):
"""
:param environ: 跟請求相關的參數
:param start_response:
:return:
"""
# 設置HTTP響應的狀態碼和頭信息
start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html;charset=utf8‘), ])
url = environ[‘PATH_INFO‘] # 取到用戶輸入的url
func = None
for i in url2func:
if url == i[0]:
func = i[1] # 拿到將要執行的函數
break
else:
func = None
if func:
msg = func(url) # 執行對應的函數
else:
msg = b‘<h1>404</h1>‘ # 找不到要執行的函數就返回404
return [msg, ]
if __name__ == ‘__main__‘:
httpd = make_server(‘127.0.0.1‘, 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()
4、jinja2
HTML內容中利用一些特殊的符號來替換要展示的數據。 用的特殊符號是自己定義的,其實模板渲染有個現成的工具:jinja2
模板的原理就是字符串替換,我們只要在HTML頁面中遵循jinja2的語法規則寫上,其內部就會按照指定的語法進行相應的替換,從而達到動態的返回內容。
pip install jinja2
"""
根據瀏覽器訪問的路徑的不同,返回不同的內容
將不同頁面的處理代碼封裝到函數中
優化頻繁的if判斷
返回具體的HTML文件
實現不同的用戶得到不同的HTML頁面
"""
import time
from wsgiref.simple_server import make_server
from jinja2 import Template
import pymysql
def home(url):
s = "this is {} page!".format(url)
return bytes(s, encoding="utf8")
def index(url):
return b‘<h1>index page</h1>‘
def user(url):
# 從數據庫裏面去到所有的用戶信息,
conn = pymysql.connect(
host=‘127.0.0.1‘,
port=3306,
user=‘root‘,
password=‘123‘,
database=‘db1‘,
charset=‘utf8‘
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute(‘select * from user‘)
ret = cursor.fetchall()
print(ret)
# 在頁面上顯示出來
with open("user.html", "r", encoding="utf8") as f:
data_s = f.read()
template = Template(data_s) # 生成一個模板文件實例
msg = template.render({"user_list": ret}) # 把數據填充到模板裏面
return bytes(msg, encoding="utf8")
def login(url):
with open("login.html", "rb") as f:
return f.read()
# url和將要執行的函數的對應關系
url2func = [
("/index", index),
("/home", home),
("/user", user),
("/login", login),
]
# 按照wsgiref的要求定義一個run_server函數
def run_server(environ, start_response):
"""
:param environ: 跟請求相關的參數
:param start_response:
:return:
"""
# 設置HTTP響應的狀態碼和頭信息
start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html;charset=utf8‘), ])
url = environ[‘PATH_INFO‘] # 取到用戶輸入的url
func = None
for i in url2func:
if url == i[0]:
func = i[1] # 拿到將要執行的函數
break
else:
func = None
if func:
msg = func(url) # 執行對應的函數
else:
msg = b‘<h1>404</h1>‘ # 找不到要執行的函數就返回404
return [msg, ]
if __name__ == ‘__main__‘:
httpd = make_server(‘127.0.0.1‘, 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()
user.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>hello</h1>
<table border="1">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>愛好</th>
</tr>
</thead>
<tbody>
{% for user in user_list %}
<tr>
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.hobby}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
5、Django
https://www.djangoproject.com/download/
A、安裝(最新LTS版)
pip3 install django==1.11.11
或
B、創建一個django項目
C、運行一個Django項目
python manage.py runserver 127.0.0.1:8000
or
D、模版文件和靜態文件配置
Template放html
Static(自己命名)放css,js
在settings.py中配置
STATIC_URL = ‘/static/‘ # 別名;HTML中使用的靜態文件夾前綴
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "css"), # 靜態文件存放位置
os.path.join(BASE_DIR, "js")
]
E、Django基礎必備三件套
from django.shortcuts import HttpResponse, render, redirect
HttpResponse:內部傳入一個字符串參數,返回給瀏覽器。
例如:
def index(request):
# 業務邏輯代碼
return HttpResponse("OK")
render:除request參數外還接受一個待渲染的模板文件和一個保存具體數據的字典參數。將數據填充進模板文件,最後把結果返回給瀏覽器。(類似於我們上面用到的jinja2)
例如:
def index(request):
# 業務邏輯代碼
return render(request, "index.html", {"name": "alex", "hobby": ["燙頭", "泡吧"]})
redirect:接受一個URL參數,表示跳轉到指定的URL。
例如:
def index(request):
# 業務邏輯代碼
return redirect("/home/")
F、常規步驟
1、創建一個django項目
2、在settings.py中對靜態文件進行配置
STATIC_URL = ‘/static/‘
STATICFILES_DIRS = [
os.path.join(BASE_DIR,‘css‘),
os.path.join(BASE_DIR,‘js‘)
]
3、將要執行的html文件放入templates文件夾
4、將需要的靜態文件放入相應文件夾(js文件放入js文件夾,css文件放入css文件夾)
5、在html文件中導入上述js,css文件時,要註意導入路徑
<script src="/static/jquery-3.3.1.min.js"></script>
6、將要執行的html文件封裝成函數,添加到urls.py中
from django.shortcuts import HttpResponse, render, redirect
def login(request):
return render(request,"批量修改.html")
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
url(r‘login/‘,login)
]
Django 0.1