Django框架基礎知識彙總(有專案版)
阿新 • • 發佈:2019-02-02
Web框架本質
web系統概念
1. Http,無狀態,短連線
2. 瀏覽器(socket客戶端)、網站(socket服務端)
web框架本質
import socket
def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 OK\r\n\r\n")
client.send("Hello, Seven")
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost' ,8000))
sock.listen(5)
while True:
connection, address = sock.accept()
handle_request(connection)
connection.close()
if __name__ == '__main__':
main()
自定義Web框架
a. socket服務端
b. 根據URL不同返回不同的內容
路由系統:
URL -> 函式
c. 字串返回給使用者
模板引擎渲染:
HTML充當模板(特殊字元)
自己創造任意資料
字串
- 靜態網站處理方式:
import socket
def f1(request):
"""
處理使用者請求,並返回相應的內容
:param request: 使用者請求的所有資訊
:return:
"""
f = open('index.fsw','rb')
data = f.read()
f.close()
return data
def f2(request):
f = open('aricle.tpl','rb')
data = f.read()
f.close()
return data
routers = [
('/xxx', f1),
('/ooo', f2),
]
def run():
sock = socket.socket()
sock.bind(('127.0.0.1',8080))
sock.listen(5)
while True:
conn,addr = sock.accept() # hang住
# 有人來連線了
# 獲取使用者傳送的資料
data = conn.recv(8096)
data = str(data,encoding='utf-8')
headers,bodys = data.split('\r\n\r\n')
temp_list = headers.split('\r\n')
method,url,protocal = temp_list[0].split(' ')
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
func_name = None
for item in routers:
if item[0] == url:
func_name = item[1]
break
if func_name:
response = func_name(data)
else:
response = b"404"
conn.send(response)
conn.close()
if __name__ == '__main__':
run()
- 動態網站處理方式一(手動進行替換的模版引擎):
import socket
def f3(request):
import pymysql
# 建立連線,獲得資料
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123',db='db666')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('select id,username,password from userinfo')
user_list = cursor.fetchall()
cursor.close()
conn.close()
# 組裝資料模型
content_list=[]
for row in user_list:
tp = '<tr><td>%s</td><td>%s</td><td>%s</td></tr>'%(row['id'],row['username'],row['password'])
content_list.append(tp)
content = "".join(content_list) # 將列表中的資料拼接成字串
# 模板渲染(模板+資料)
f = open('userlist.html','r',encoding='utf-8')
template = f.read()
f.close()
data = template.replace('@@[email protected]@', content)
return bytes(data, encoding='utf-8')
# 路由系統
routers = [
('/userlist.htm', f3),
]
def run():
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1',8080))
sock.listen(5)
while True:
conn,addr = sock.accept() # hang住
# 有人來連線了
# 獲取使用者傳送的資料
data = conn.recv(8096)
data = str(data,encoding='utf-8')
headers,bodys = data.split('\r\n\r\n')
temp_list = headers.split('\r\n')
method,url,protocal = temp_list[0].split(' ')
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
func_name = None
for item in routers:
if item[0] == url:
func_name = item[1]
break
if func_name:
response = func_name(data)
else:
response = b"404"
conn.send(response)
conn.close()
if __name__ == '__main__':
run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>使用者名稱</th>
<th>郵箱</th>
</tr>
</thead>
<tbody>
@@[email protected]@
</tbody>
</table>
</body>
</html>
動態網站二(使用jinjia2模板引擎進行替換)
import socket
def f4(request):
import pymysql
# 建立連線
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='db666')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select id,username,password from userinfo")
user_list = cursor.fetchall()
cursor.close()
conn.close()
f = open('hostlist.html','r',encoding='utf-8')
data = f.read()
f.close()
# 基於第三方工具實現的模板渲染
from jinja2 import Template
template = Template(data)
data = template.render(xxxxx=user_list, user='dsafsdfsdf')
return data.encode('utf-8')
# 路由系統
routers = [
('/host.html', f4),
]
def run():
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1',8080))
sock.listen(5)
while True:
conn,addr = sock.accept() # hang住
# 有人來連線了
# 獲取使用者傳送的資料
data = conn.recv(8096)
data = str(data,encoding='utf-8')
headers,bodys = data.split('\r\n\r\n')
temp_list = headers.split('\r\n')
method,url,protocal = temp_list[0].split(' ')
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
func_name = None
for item in routers:
if item[0] == url:
func_name = item[1]
break
if func_name:
response = func_name(data)
else:
response = b"404"
conn.send(response)
conn.close()
if __name__ == '__main__':
run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>使用者名稱</th>
<th>郵箱</th>
</tr>
</thead>
<tbody>
{% for row in xxxxx %}
<tr>
<td>{{row.id}}</td>
<td>{{row.username}}</td>
<td>{{row.password}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{user}}
</body>
</html>
Django框架基礎內容
框架種類
- a,b,c --> Tornado
- [第三方a],b,c --> wsgiref -> Django
- [第三方a],b,[第三方c] --> flask,
Django專案前期配置
pip3 install django
# 建立Django程式
django-admin startproject mysite
# 進入程式目錄
cd mysite
# 啟動socket服務端,等待使用者傳送請求
python manage.py runserver 127.0.0.1:8080
Django配置檔案:settings.py
……
DIRS': [os.path.join(BASE_DIR, 'template')],
……
Mysql資料庫:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname',
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': '',
'PORT': '',
}
}
#備註:
# 由於Django內部連線MySQL時使用的是MySQLdb模組,而python3中還無此模組,所以需要使用pymysql來代替
# 如下設定放置的與project同名的配置的 __init__.py檔案中
import pymysql
pymysql.install_as_MySQLdb()
靜態檔案路徑:
static目錄
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
額外配置(跨站請求偽裝crsf):
MIDDLEWARE = [
……
#'django.middleware.csrf.CsrfViewMiddleware',
……
]
專案案例
- 網站請求
# urls.py
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^index/',index),
]
def index(request):
# return HttpResponse('Index')
return render(request, 'index.html',{
'name': 'tom',
'users':['李志','李傑'],
'user_dict':{'k1':'v1', 'k2':'v2'},
'user_list_dict':[
{'id':1,'name':'tom','email':'[email protected]'},
{'id':1,'name':'tom','email':'[email protected]'},
{'id':1,'name':'tom','email':'[email protected]'},
{'id':1,'name':'tom','email':'[email protected]'},
]
})
# template/index
<p>{{ name }}</p>
<p>{{ users.0 }}</p>
<p>{{ users.1 }}</p>
<p>{{ user_dict.k1 }}</p>
<p>{{ user_dict.k2 }}</p>
<h3>迴圈</h3>
<ul>
{% for item in users %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<h3>迴圈</h3>
<table border="1">
{% for row in user_list_dict %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.email }}</td>
<td>
<a>編輯</a> | <a href="/del/?nid={{ row.id }}">刪除</a>
</td>
</tr>
{% endfor %}
</table>
- 網站登陸
# urls
from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse,render,redirect
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^login/',login),
]
def login(request):
"""
處理使用者請求,並返回內容
:param request: 使用者請求相關的所有資訊(物件)
:return:
"""
# 字串
# return HttpResponse('<input type="text" />')
# return HttpResponse('login.html')
# 自動找到模板路徑下的login.html檔案,讀取內容並返回給使用者
# 模板路徑的配置
print(request.GET) # 結果為字典格式,值為列表型別
if request.method == "GET":
return render(request,'login.html')
else:
# 使用者POST提交的資料(請求體)
u = request.POST.get('user')
p = request.POST.get('pwd')
if u == 'root' and p == '123':
# 登入成功
# return redirect('http://www.oldboyedu.com')
return redirect('/index/') # 重定向
else:
# 登入失敗
return render(request,'login.html',{'msg': '使用者名稱或密碼錯誤'})
# template
<form method="POST" action="/login/">
<input type="text" name="user" />
<input type="password" name="pwd" />
<input type="submit" value="登入" />
{{ msg }}
</form>
django學員管理系統
資料庫設計結構
表結構:班級\學生\老師
(班級表):
id title
1 全4期
2 全5期
(學生表):
id name 班級ID(FK)
1 張傑 1
(老師表):
id name
1 林峰
2 林狗
3 苑天
(老師班級關係表):
id 老師ID 班級ID
1 1 1
2 1 2
3 2 2
班級管理模組
- 查(母版繼承)
# urls
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'classes/', views.classes),
]
# view
from django.shortcuts import render,redirect
import pymysql
def classes(request):
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='123', db='s4db65', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 設定查詢結果為字典格式
cursor.execute("select id, title from class")
class_list = cursor.fetchall() # 結果為字典
cursor.close()
conn.close()
print(class_list)
return render(request, 'classes.html',{'class_list':class_list})
# html
{% extends ‘manage.html’% } # 繼承母版
{%block content%} # 母版塊中填充內容
<h1>班級列表</h1>
<div>
<a href="/add_class/">新增</a>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>班級名稱</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in class_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.title }}</td>
<td>
<a href="">編輯</a>
|
<a href="">刪除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endbloc %}
- 增
# urls
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^add_class/', views.add_class),
]
# view
def add_class(request):
if request.method == 'GET':
return render(request,'add_class.html')
else:
print(request.POST)
v = request.POST.get('title')
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123',db='s4db65',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('insert into class(title) value(%s)', [v,])
conn.commit() # 提交事務
cursor.close()
conn.close()
return redirect('/classes/')
# html
<h1>新增班級</h1>
<form method="post" action="/add_class/">
<p>班級名稱:<input type="text" name="title" /></p>
<input type="submit" value="提交">
</form>
- 刪
# urls
urlpatterns = [
url(r'^del_class/', views.del_class),
]
# view
def del_class(request):
nid = request.GET.get('nid')
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='s4db65', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('delete from class where id=%s',[nid,])
conn.commit()
cursor.close()
conn.close()
return redirect('/classes/')
- 改
# urls
urlpatterns = [
url(r'^edit_class/', views.edit_class),
]
# view
def edit_class(request):
if request.method == 'GET': # 獲取資料
nid = request.GET.get('nid')
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd = '123', db='s4db65',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('select id, title from class where id=%s', [nid,])
result = cursor.fetchone()
cursor.close()
conn.close()
print(result)
return render(request,'edit_class.html',{'result':result})
else:
nid = request.GET.get('nid')
title = request.POST.get('title')
print(nid, title)
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123',db='s4db65', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('update class set title=%s where id=%s',[title,nid,])
conn.commit()
cursor.close()
conn.close()
return redirect('/classes/')
- 模態對話方塊實現增加班級功能
# html
<a onclick="showModal()">對話方塊新增</a>
<div id="shadow" class="shadow hide"></div>
<div id="modal" class="model hide">
<p>
<input type="text" id="title">
</p>
<input type="button" value="提交" onclick="AjaxSend()"/><span id=""></span>
<input type="button" value="取消" onclick="cancleModal()">
</div>
# css
.hide {
display: none;
}
.shadow {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: black;
opacity: 0.5;
z-index: 999;
}
.model {
z-index: 1000;
position: fixed;
height: 300px;
width: 400px;
background: white;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -150px;
}
# js
function showModal() {
document.getElementById('shadow').classList.remove('hide')
document.getElementById('modal').classList.remove('hide')
}
function cancleModal() {
document.getElementById('shadow').classList.add('hide');
document.getElementById('modal').classList.add('hide');
}
function AjaxSend() {
$.ajax({
url: '/modal_add_class/',
type: 'POST',
data: {'title': $('#title').val()},
success: function (data) {
console.log(data);
if (data == 'ok') {
location.href = '/classes';
} else {
$('errormsg').text(data);
}
}
})
}
# urls
urlpatterns = [url(r'^modal_add_class/', views.modal_add_class]
# views
sqlheper工具類(將增刪改查進行封裝):
def modify(sql,args):
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='s4db65', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute(sql,args)
conn.commit()
cursor.close()
conn.close()
----------
def modal_add_class(request):
title = request.POST.get('title')
if len(title) > 0:
sqlheper.modify('insert into class (title) value(%s)',[title,])
return HttpResponse('ok')
else:
return HttpResponse('班級標題不能為空')
學生管理模組
- 查
# urls
url(r'^students/',views.students),
# views
def students(request):
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123',db='s4db65',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('select student.id,student.name,class.title from student left JOIN class on student.class_id = class.id')
student_list = cursor.fetchall()
cursor.close()
conn.close()
print('結果:',student_list)
return render(request,'students.html',{'student_list':student_list})
# html
<h1>學生列表</h1>
<div><a href="/add_student/">新增</a></div>
<table>
<thead>
<tr>
<th>ID</th>
<th>學生姓名</th>
<th>所屬班級</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in student_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.title }}</td>
<td>
<a href=" ">編輯</a>
<a>刪除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
- 增
# urls
url(r'^add_student/',views.add_student)
# views
def add_student(request):
if request.method == 'GET': #只負責跳轉頁面
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123',db='s4db65',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('select id,title from class')
class_list = cursor.fetchall()
cursor.close()
conn.close()
return render(request,'add_student.html',{'class_list':class_list})
else:
name = request.POST.get('name') #負責提交資料的跳轉頁面
class_id = request.POST.get('class_id')
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123',db='s4db65',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('insert into student(name,class_id)values(%s,%s)',[name,class_id,])
conn.commit()
cursor.close()
conn.close()
return redirect('/students/')
# html
<h1>新增學生</h1>
<form method="post" action="/add_student/">
<p>學生姓名<input type="text" name="name"> </p>
<p>
所屬班級
<select name='class_id'>
{% for row in class_list %}
<option value="{{ row.id }}">{{ row.title }}</option>
{% endfor %}
</select>
</p>
<input type="submit" value="提交" />
</form>
- 改
# urls
url(r'^edit_student/',views.edit_student),
# views
from utils import sqlheper
def edit_student(request):
if request.method == "GET":
nid = request.GET.get('nid')
class_list = sqlheper.get_list("select id,title from class",[])
current_student_info = sqlheper.get_one('select id,name,class_id from student where id=%s',[nid,])
print('結果:',class_list,current_student_info,nid)
return render(request,'edit_student.html',{'class_list': class_list,'current_student_info':current_student_info})
else:
nid = request.GET.get('nid')
name = request.POST.get('name')
class_id = request.POST.get('class_id')
sqlheper.modify('update student set name=%s,class_id=%s where id=%s',[name,class_id,nid,])
return redirect('/students/')