web網站:css
HTTP: 無狀態、短連接(創建在TCP之上) TCP: 不斷開(能夠) WEB應用(網站): http協議: 發送 遵循請求頭和請求體規則 GET發送方式 請求體在第一行/後面 GET /index/?p=3 HTTP/1.1
POST發送方式 請求體在請求頭後結束空兩行 POST /index/?p=3 HTTP/1.1
GET請求時----》 只有reqeuest.GET有值
POST請求 ----》 reqeuest.GET和reqeuest.POST均可能有值
響應 響應頭 響應體 用戶在頁面看到的內容「字符串」(看到的效果,是瀏覽器解析的) WEB使用HTTP協議做應用層協議,以封裝HTTP 文本信息,而後使用TCP/IP作傳輸層協議將它發到網絡上。 瀏覽器(socket客戶端) 2.www.cnblogs.com (DNS解析域名,拿到ip,42.121.252.58,80) 5.接收 6.連接斷開 博客園(socket服務端) 1.監聽ip和端口 3.收到 4.響應 7.收到用戶斷開連接
web框架:html
1. Http,無狀態,短鏈接 2. 瀏覽器(socket客戶端) 網站(socket服務端) 3. 本身寫網站 a. socket服務端 b. 根據URL不一樣返回不一樣的內容 路由系統: URL -> 函數 c. 字符串返回給用戶 模板引擎渲染: HTML充當模板(特殊字符) 本身創造任意數據 字符串 4. Web框架: 框架種類: - a,b,c --> Tornado - [第三方a],b,c --> wsgiref(做爲服務端)-> Django - [第三方a],b,[第三方c] --> flask,jinja2
靜態網站前端
import socket def f1(request): ''' 處理用戶的請求,並返回相應的內容 request:用戶請求的全部信息 ''' f = open('index.html','rb') data = f.read() f.close() return data def f2(request): f = open('article.html', '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() #等待連接 data =conn.recv(8096) data = str(data,encoding='utf-8') print(data) headers,bodys=data.split('\r\n\r\n') temp_list=headers.split('\r\n') method,url,protecal = temp_list[0].split(' ') conn.send(b"HTTP/1.1 200 OK\r\n\r\n") # 響應頭 fun_name = None for item in routers: if item[0]==url: fun_name = item[1] break if fun_name: response = fun_name(data) else: response = b"404" conn.send(response) # if url == "/xxxx": # conn.send(b'123123') # else: # conn.send(b'404 not find') conn.close() if __name__ == '__main__': run()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>用戶登陸</h1> <form action=""> <p><input type="text" placeholder="用戶名"></p> <p><input type="password" placeholder="密碼"></p> </form> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1"> <thead> <tr> <th>1</th> <th>root</th> <th>root@qq.com</th> </tr> </thead> </table> </body> </html>
動態網站(從數據庫取數據)python
import socket def f1(request):#靜態網站 ''' 處理用戶的請求,並返回相應的內容 request:用戶請求的全部信息 ''' f = open('index.html','rb',) data = f.read() f.close() return data def f2(request):#動態網站 f = open('article.html', 'r',encoding='utf-8') data = f.read() f.close() import time ctime = time.time() data = data.replace("@@sw@@",str(ctime)) return bytes(data,encoding='utf-8') def f3(request): #去數據庫取數據 import pymysql # 建立鏈接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', 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('@@sdfsdffd@@',content) return bytes(data,encoding='utf-8') def f4(request): # 基於第三方工具實現的模板渲染jinja2 import pymysql # 建立鏈接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', 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() # 基於第三方工具實現的模板渲染jinja2 #data就是模板 from jinja2 import Template template = Template(data) data = template.render(xxxxx=user_list,user='sdfsdfsdf') return data.encode('utf-8') routers = [ ('/xxx',f1), ('/aaa',f2), ('/userlist.htm', f3), ('/host.html', f4), ] def run(): sock = socket.socket() sock.bind(('127.0.0.1',8080)) sock.listen(5) while True: conn,addr = sock.accept() #等待連接 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,protecal = temp_list[0].split(' ') conn.send(b"HTTP/1.1 200 OK\r\n\r\n") # 響應頭 fun_name = None for item in routers: if item[0]==url: fun_name = item[1] break if fun_name: response = fun_name(data) else: response = b"404" conn.send(response) # if url == "/xxxx": # conn.send(b'123123') # else: # conn.send(b'404 not find') conn.close() if __name__ == '__main__': run()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>用戶登陸</h1> <form action=""> <p><input type="text" placeholder="用戶名"></p> <p><input type="password" placeholder="密碼"></p> </form> </body> </html>
<!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>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1"> <thead> <tr> <th>id</th> <th>用戶</th> <th>郵箱</th> </tr> </thead> <tbody> <tr> <th>1</th> <th>@@sw@@</th> <th>root@qq.com</th> </tr> </tbody> </table> </body> </html>
<!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> @@sdfsdffd@@ </tbody> </table> </body> </html>
Django框架:mysql
pip3 install django 在終端安裝程序後,將django-admin.py文件的上一級路徑加環境變量裏面 命令: # 建立Django程序 django-admin startproject mysite # 進入程序目錄 cd mysite # 啓動socket服務端,等待用戶發送請求 python manage.py runserver 127.0.0.1:8080 啓動服務端,監聽端口,等待連接 默認端口是8000 pycharm: ... Django程序目錄: mysite mysite - settings.py # Django配置文件 - url.py # 路由系統:url和函數的對應關係 - wsgi.py # 用於定義Django用socket, 默認用的wsgiref,用於本地測試,工做時用uwsgi manage.py # 對當前Django程序全部操做能夠基於 python manage.py runserver ,還能夠加其餘參數
1. Web框架本質 瀏覽器(socket客戶端) 2. 發送IP和端口 http://www.baidu.com:80/index/ GET: 請求頭 http1.1 /index?p=123 ... 請求體(無內容) POST: 請求頭 http1.1 /index?p=123 ... 請求體 ... 4. 接收響應 普通響應:頁面直接顯示 重定向響應:再一塊兒一次Http請求(服務端傳回客戶端,再向服務端發起一次Http請求) 服務器(socket服務端) 1. 啓動並監聽ip和端口,等待用戶鏈接 3. 接收請求進行處理,並返回 普通返回: 響應頭: Access-Control-Allow-Origin:* Cache-Control:max-age=600 Date:Mon, 19 Jun 2017 00:57:43 GMT Expires:Mon, 19 Jun 2017 01:07:43 GMT Last-Modified:Wed, 24 May 2017 01:51:55 GMT Server:GitHub.com X-GitHub-Request-Id:C495:5EBC:8739EF:B817EE:59472187 響應體: <html> .... </html> 重定向返回: 響應頭: LOCATION: 'http://www.baidu.com' Access-Control-Allow-Origin:* Cache-Control:max-age=600 Date:Mon, 19 Jun 2017 00:57:43 GMT Expires:Mon, 19 Jun 2017 01:07:43 GMT Last-Modified:Wed, 24 May 2017 01:51:55 GMT Server:GitHub.com X-GitHub-Request-Id:C495:5EBC:8739EF:B817EE:59472187 2. DjangoWeb框架 a. 建立Project django-admin startproject mysite b. 配置 模板 靜態文件 csrf c. 路由關係 url -> 函數 url -> 函數 url -> 函數 url -> 函數 d. 視圖函數 def index(request): request.method request.GET.get('name') request.POST.get('nage') li = request.POST.getlist('多選下拉框name') return HttpResponse('字符串') return redirect('URL') return render(request,'模板路徑',{}) # 1. 獲取模板+數據,渲染 # 2. HttpReponse(...) c. 模板渲染 {{k1}} {{k2.0}} {% for i in result %} {{i}} {%endfor %} {%if 1>2%} {%endif%} 3. Ajax(jQuery) $.ajax({ url: '', type: 'GET', data: {k1:'v1'}, success:function(arg){ } })
配置:jquery
- 模板路徑 template目錄 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, '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', ], }, }, ] - 靜態文件路徑 static目錄 STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR,'static'), )#靜態文件路徑設置
額外配置:web
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
urls.pyajax
from django.conf.urls import url from django.contrib import admin from django.shortcuts import HttpResponse,render,redirect def login(request): """ 處理用戶請求,並返回內容 :param request: 用戶請求相關的全部信息(對象) :return: """ # HttpResponse只處理字符串 # return HttpResponse('<input type="text" />') # return HttpResponse('login.html') # render自動找到模板路徑下的login.html文件,讀取內容並返回給用戶 # 模板路徑的配置(settings.py內'DIRS') print(request.GET) if request.method == "GET": return render(request,'login.html') else: # request.POST用戶POST提交的數據(請求體) u = request.POST.get('user') #get方式取值,若是沒有不會報錯,會賦值None p = request.POST.get('pwd') if u == 'root' and p == '123123': # 登陸成功 # return redirect('http://www.oldboyedu.com') 跳轉網頁 return redirect('/index/') #跳轉 else: # 登陸失敗 return render(request,'login.html',{'msg': '用戶名或密碼錯誤'}) #msg模板引擎的特殊標記 def index(request): # return HttpResponse('Index') return render( request, 'index.html', { 'name': 'alex', 'users':['李志','李傑'], 'user_dict':{'k1': 'v1','k2':'v2'}, 'user_list_dict': [ {'id':1, 'name': 'alex', 'email': 'alex3714@163.com'}, {'id':2, 'name': 'alex2', 'email': 'alex3714@1632.com'}, {'id':3, 'name': 'alex3', 'email': 'alex3713@1632.com'}, ] } ) urlpatterns = [ # url(r'^admin/', admin.site.urls),#目前用不着 url(r'^login/', login), url(r'^index/', index), ]
static-----靜態文件,放置插件、css、js文件等sql
h1{
color: red;
}
templates---模板數據庫
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>模板標記學習</h1> <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> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/commons.css" /> </head> <body> <h1>用戶登陸</h1> <form method="POST" action="/login/"> {# action是提交路徑#} <input type="text" name="user" /> <input type="password" name="pwd" /> <input type="submit" value="登陸" /> {{ msg }} {# render傳值才顯示#} </form> </body> </html>
- 模板渲染 def index(request): return render(request,'模板路徑', { 'k1': 'v1', 'k2': [1,2,32,34], 'k3': {'x'...}, } ) index.html <h1>{{k1}}</h1> <h1>{{k2.2}}</h1> {% for item in k2%} <h1>{{item}}</h1> {% endfor %}
1. 模態對話框 - 添加 Form表單提交,頁面會刷新 2. Ajax(不要以Form表單提交,完成模態對話框提交失敗,返回信息還在模態對話框,不刷新網頁) jQuery $.ajax({ url: '要提交的地址', type: 'POST', // GET或POST,提交方式 data: {'k1': 'v1','k2':'v2'}, // 提交的數據 dataType:"JSON",//默認將服務端傳回的字符串轉化爲對象
success:function(data){ // 當前服務端處理完畢後,自動執行的回調函數 // data返回的數據 //data字符串類型
//JSON.parse(字符串)==》對象
//JSON.stringify(對象)==》字符串
//arg = JSON.parse(data);
if(data.status){
//location.href='/class/' //從定向
location.reload()//刷新當前頁面
}
else{
$("#errormsg").text(data.message)
}
} }) 其餘: 1. 模板語言if條件語句和循環語句
{% for row in class_list %}
{% if row.id == student_info.id %}
<option selected value="{{ row.id }}">{{ row.title }}</option>
{% else %}
<option value="{{ row.id }}">{{ row.title }}</option>
{% endif %}
{% endfor %}
索引[11,22,33].indexOf(22222) 正確的話返回索引位置,不正確的話返回-1
{{}}
2. Form表單提交,頁面會刷新 3. Ajax提交頁面不刷新 4. js實現頁面跳轉: location.href = "要跳轉的地址" 5. 模態對話框(Ajax) - 少許輸入框 - 數據少 登陸 新URL方式 - 操做多 - 對於大量的數據以及操做
6.多對多時(例如老師授課班級關係表編輯時,更新老師和班級關係表時,解決方法):
1、刪除原先老師授課班級的關係表,而後再插入授課班級關係表
2、print list(set(b).difference(set(a))) 判斷修改的授課關係表是否在數據庫中,不在再插入
1. Http請求生命週期 請求頭 -> 提取URL -> 路由關係匹配 -> 函數 (模板+數據渲染) -> 返回用戶(響應頭+響應體) 2. def index(request): request.POST.getlist 獲取列表數據
request.GET.get request.method 判斷數據的傳輸方法
return render() 模板渲染(結合html文件)
return HttpResponse() 傳輸字符串
return redirect() 向客戶端發送響應體,再讓客戶端發起一次http請求
補充:模板渲染是在後臺執行
先執行函數,再跳轉網頁:
<a href="www.baidu.com" onclick="btn">點擊</a> <script> function btn() { alert(123) } </script>
事件執行後,再也不跳轉(js):
<a href="www.baidu.com" onclick="return btn">點擊</a> <script> function btn() { alert(123); return false } </script>
事件執行後,再也不跳轉(Jquery):
<a href="www.baidu.com" id="'#addModal'">點擊</a>
$('#addModal').click(function(){ alert(123); return false; })
服務端:
def edi_class(request): ret = {"status":True,"message":None} try: nid = request.POST.get("nid") print(nid) title=request.POST.get("title") print(title) conn = pymysql.connect(host="localhost", user="root", password="", database="class_student",
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() except Exception as e: ret["status"]=False ret["message"]=e; return HttpResponse(json.dumps(ret))
客戶端:
csrftoken的取值用插件的形式取
<script src="/static/jquery.cookie.js"></script>
function AjaxSend_edi(){ var token = $.cookie('csrftoken');
$.ajax({ url: '/edi_class/', type: 'POST', headers: {'X-CSRFToken': token},
data: {'nid': $('.modal_edi_Y').attr("nid"),'title':$('.modal_edi_title').val()}, dataType:"JSON", success:function (arg) { //arg字符串類型 //JSON.parse(字符串)==》對象 //JSON.stringify(對象)==》字符串 //arg = JSON.parse(arg); if(arg.status){ //location.href='/class/' location.reload() } else{ $("#errormsg").text(arg.message) } } }) }
或者(csrftoken的取值方式不一樣)
function AjaxSend_edi(){
$.ajax({ url: '/report.html', type: "POST", data: {'csrfmiddlewaretoken': '{{ csrf_token }}'}, dataType: 'JSON', success: function (arg) { console.log(arg); }, }); }
$.getJSON( "{% url 'get_task_result' %}", {'task_id':task_id}, function(callback){} ) $.post( "{% url 'multitask' %}", {'csrfmiddlewaretoken': "{{ csrf_token }}",'task_data': JSON.stringify(task_data)}, function(callback){} )
url方式接收時select的多個選項時:
class_id=request.POST.getlist("class_id")
Ajax方式時有兩種解決方法:
function bindAddSubmit(){ $('#addSubmit').click(function(){ var name = $('#addName').val(); var class_id_list = $('#classIds').val(); console.log(name,class_id_list); $.ajax({ url:'/modal_add_teacher/', type: 'POST', data: {'name':name, 'class_id_list': class_id_list,'csrfmiddlewaretoken': '{{ csrf_token }}'}, dataType:'JSON', traditional: true,// 若是提交的數據的值有列表,則須要添加此屬性 //不加這個屬性時,jQuery1.4以後可序化,數組參數名自動添加[] success: function (arg) { if(arg.status){ location.reload(); }else{ alert(arg.message); } } }) }); }
1、在html中添加
traditional: true
2、在服務端接收時:
class_id=request.POST.getlist("class_id_list[]")
1、bootstrap
引入:
bootstrap.css測試時用
bootstrap.min.css生產時用
2、ontawesome
引入:
font-awesome.css
import pymysql def get_list(sql,args): conn = pymysql.connect(host="localhost",user="root",password="",charset="utf8",database="class_student") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql,args) result = cursor.fetchall() cursor.close() conn.close() return result def get_one(sql,args): conn = pymysql.connect(host="localhost",user='root',password='',charset='utf8',database='class_student') cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql,args) result=cursor.fetchone() cursor.close() conn.close() return result def modify(sql,args): conn = pymysql.connect(host="localhost", user='root', password='', charset='utf8', database='class_student') cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql,args) conn.commit() cursor.close() conn.close() def create(sql,args): conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='class_student', charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql,args) conn.commit() last_row_id = cursor.lastrowid cursor.close() conn.close() return last_row_id
import pymysql class SqlHelper(object): def __init__(self): # 讀取配置文件 self.connect() def connect(self): self.conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='class_student', charset='utf8') self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) def get_list(self,sql,args): self.cursor.execute(sql,args) result = self.cursor.fetchall() return result def get_one(self,sql,args): self.cursor.execute(sql,args) result = self.cursor.fetchone() return result def modify(self,sql,args): self.cursor.execute(sql,args) self.conn.commit() def multiple_modify(self,sql,args): # self.cursor.executemany('insert into bd(id,name)values(%s,%s)',[(1,'alex'),(2,'eric')]) self.cursor.executemany(sql,args) self.conn.commit() def create(self,sql,args): self.cursor.execute(sql,args) self.conn.commit() return self.cursor.lastrowid def close(self): self.cursor.close() self.conn.close()