一 瀏覽器相關知識css
http:只有依賴一回,屬於短連接,不會報錯客戶端的信息。html
瀏覽器至關於一個客戶端,客戶端的連接前端
服務端:socket服務端,起服務監聽客戶端的請求。python
import socket sk=socket.socket() sk.bind(('192.168.11.38',8888)) sk.listen(5) def index(): with open('輪播網頁.html',encoding='utf-8')as f: ret=f.read() return ret def login(): with open('login.html',encoding='utf-8')as f: ret=f.read() import pymysql conn=pymysql.connect( host='127.0.0.1', port=3306, user='root', passwd='0410', db='day46' ) cursor=conn.cursor() cursor.execute('select * from user') user_list=cursor.fetchall() cursor.close() conn.close() res='' for i in user_list: res += ''' <tr> <td>{}</td> <td>{}</td> <td>{}</td> </tr> '''.format(i[0], i[1], i[2]) tables= ret.replace('@@xx@@',res) return tables def info(): return "這是我的信息" info_index=[ ('/login/',login), ('/index/',index), ('/info/',info) ] while True: conn,addr=sk.accept() print(addr) data=conn.recv(8096) data3=str(data,encoding='utf-8') data1=data3.split('\r\n\r\n')[0] print('*'*50) print(data1) data2=data1.split('\r\n')[0].split(' ')[1] print(data2) ingo_name=None for i in info_index: if data2==i[0]: ingo_name=i[1] break if ingo_name: response=ingo_name() else: response='404' conn.send(b'HTTP/1.1 200 0k\r\nContent-Type:text/html;charset=utf-8\r\n\r\n') conn.send(response.encode('utf-8')) conn.close()
二 框架的介紹mysql
tornado:模版都是人家寫好的,咱們只管拿來使用。jquery
Django:服務端能夠本身寫,其餘的模版都是別人寫好的。web
flask:服務端和模版渲染都是本身寫的,函數的功能都是別人寫好了的。ajax
全部的web框架叫作web應用服務器。正則表達式
三 django的安裝和使用sql
安裝:pip install django。
建立項目:django-admin startproject 項目名
手動建立:
查看參數:django-admin。
開啓項目:python manage.py runserver
使用命令建立app:atsrtapp app名
配置文件的INSTALLED_APPS添加:'rbac.apps.RbacConfig',
響應格式:
{
"接收到的想要":回覆
。。。。。
}
相關文件夾:
manage.py:全部django命令,全部的django項目相關的都是基於manage這個文件實現的。
settings.py:配置文件,客戶端能夠直接訪問這裏面的一些文件
urls.py:函數功能,url內部給函數自動傳入了一個參數,就是request參數。
若是想要獲取到url裏面的內容,使用正則表達式裏面的分組,將要獲取的內容括起來,而後會被看成實參傳入到函數功能裏面去。
url配置: 注意:url:匹配的是url的路徑部分 import re re.findall("^articls/2004/$","articls/2004/asdsa") 無名分組: # url(r'^articls/(\d{4})/(\d{2})$', views.archive3,), # archive2(request,2000,11) 有名分組: # url(r'^articls/(?P<y>\d{4})/(?P<m>\d{2})$', views.archive4,), # archive2(request,y=2000,m=11)
blog分發:將一個大的urls文件進行分組,分紅多個小的urls文件,而後再在大的urls文件裏面調用這些小的urls文件。
小urls文件 from django.conf.urls import url, include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^articls/2004/$', views.archive, ), # 徹底匹配 # archive(request) url(r'^articls/(?P<y>\d{4})/(?P<m>\d{2})$', views.archive4, ), # archive2(request,y=2000,m=11) ] 大urls文件 from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^login.html/', views.login,name="laogou"), # login(request) url(r'^foo/', views.foo), # login(request) ##############路由分發#################### url(r'^app01/', include('app01.urls')) , # /app01/articls/2004 ]
wsgi.py :socketserver相關,wsgi文件和django結合使用的,django是沒有服務端的,而wsgi文件爲django提供了一個服務端。
wsgi文件是一種協議,是web網關接口,分別有兩種:wsgiref和uwsgi。
wsgiref是能夠實現基本的,大多數用來調試的。
uwsgi是用於企業的。
wsgi導入的文件是:
from django.core.wsgi import get_wsgi_application
app文件:project :主要用於業務的分類,是整個項目下的一個程序
主站,app:專門處理相關的業務,啓動app的web命令:
python manage.py startapp web
後臺管理 app:啓動app的backend命令:
python manage.py startapp backend
models文件:主要是寫web應用相關的內容。
四 使用
views視圖分爲兩大塊:一個是請求對象,另外一個是響應對象。
請求對象request:表明全部請求的內容
request.method:獲取請求,請求的方法具體是什麼
request.POST.get('***'):以什麼途徑發送的請求
request.GET.get(‘***’):從url中獲取具體的什麼數據或者內容,在後端函數裏面須要使用GET
request.POST.getlist:同時能夠獲取多個值,全部的值都是在一個列表裏面
request.encoding:請求的格式
request.path 和request.info:請求路徑的內容,沒有數據內容
request.get_full_path:請求路徑的內容,還有數據的內容
def archive(request): print(request.path) # /app01/articls/2004/ print(request.path_info) # /app01/articls/2004/ print(request.get_full_path()) # /app01/articls/2004/?a=1
request.is_ajax:判斷此次的請求是否是ajax請求
還有request.COOKICS;request.session;request.path等
GET: URL: 127.0.0.1:8000/class_list/?name=alex&age=18 request.GET.get("name") request.GET.get("age") POST: <form class="form-horizontal" action="/add_class/" method="post"> <div class="form-group"> <label for="inputclassname" class="col-sm-2 control-label">班級名稱</label> <div class="col-sm-10"> <input name="class_name" type="text" class="form-control" id="inputclassname" placeholder="班級名稱"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form>
request.body:全部的請求數據都會在這裏面。
from django.shortcuts import render,HttpResponse # Create your views here. def login(request): if request.is_ajax(): print(request.body) # b'{"user":"alex","pwd":"123"}' # b'user=alex&pwd=123&csrfmiddlewaretoken=PCLE4jNWOmLcmd5LiY1qrwTWQZLpZdSktwwwPswNKg7DhblKO6X1fBDkB05yoNMm' print(request.POST) # {'user': ['alex'], 'pwd': ['123'], 'csrfmiddlewaretoken': ['PCLE4jNWOmLcmd5LiY1qrwTWQZLpZdSktwwwPswNKg7DhblKO6X1fBDkB05yoNMm']} print(request.GET) # {} # user=request.POST.get("user") # pwd=request.POST.get("pwd") # # print(user,pwd) # print("=======") # import json # s=request.body.decode("utf8") # d=json.loads(s) # print(d.get("user")) # print(d.get("pwd")) return HttpResponse("OK") return render(request,"index.html") def reg(request): if request.is_ajax(): print(request.POST,"=======") return HttpResponse("OK") return render(request,"reg.html")
request.FILES:文件上傳的地方接收到的是一個文件對象,也就是一個文件句柄,直接.name就是文件名字。
from django.shortcuts import render,HttpResponse # Create your views here. def index(request): # #print(request.body) # print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['2Fq1vmv59yRSUxDwlkym3qmk5bNpfdHLGzbTgveW5sdjPvTvRsuXRv6IQc7yENBN'], 'user': ['yuan'], 'cFile': ['day76.txt']}> # print(request.FILES) # # file_obj=request.FILES.get("cFile") # name=file_obj.name # print(name) # day76.txt # import os # # from filePut import settings # path=os.path.join(settings.BASE_DIR,"app01","static",name) # with open(path,"wb") as f_write: # for line in file_obj: # f_write.write(line) return render(request,"index.html") def indexAjax(request): print(request.body) print(request.POST) print(request.GET) # print(request.POST) # print(request.FILES) # file_obj=request.FILES.get("cFile") # name=file_obj.name # print(name) # day76.txt # import os # # from filePut import settings # path=os.path.join(settings.BASE_DIR,"app01","static",name) # with open(path,"wb") as f_write: # for line in file_obj: # f_write.write(line) return HttpResponse("123421")
新手三件套:
導入:from django.shortcuts import
HttpResponse:http的響應,裏面只可以方字符串
render:渲染,一次請求一次響應。每請求一次就會被渲染。
render(request, 'html文件')
render(request,"html文件",{"替換的內容":值})
render(request,"html文件",locals()) :局部的變量均可以在HTML文件裏面使用
redirect:跳轉頁面,重定向這一次請求,重定向時,須要多發送一次請求。
以登陸爲例: 第一次請求: 請求url: http://127.0.0.1:8000/login.html/ GET 無請求數據 login.html/-------> views.login------>login() 響應到一個login.html頁面 第二次請求: 請求url: http://127.0.0.1:8000/login.html/ POST 有請求數據 {"user":"alex","pwd":"123"} login.html/-------> views.login------>login() 響應的return redirect("/index/")到瀏覽器,通知瀏覽器再發送請求:"/index/" 請求url: http://127.0.0.1:8000/index/ get請求 沒有數據 index/ --->url(r'^index/', views.index),---->index() 響應一個index.html
from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import render,redirect
def mysql():
import pymysql
user_dic = {}
conn=pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="0410", db="day43", charset="utf8")
cursor=conn.cursor()
cursor.execute('select name,password from user')
user_list = cursor.fetchall()
cursor.close()
conn.close()
for user in user_list:
user_dic[user[0]]=user[1]
return user_dic
def login(request):
if request.method=='GET':
return render(request,'登錄界面.html')
else:
user_dic=mysql()
for user in user_dic:
if request.POST.get('user')==user and request.POST.get('passwd')==user_dic[user] and request.POST.get('pwd')==user_dic[user]:
return redirect('http://www.xiaohuar.com/hua/')
elif request.POST.get('user')==user and request.POST.get('passwd')==user_dic[user] and request.POST.get('pwd')!=user_dic[user]:
return render(request, '登錄界面.html', {'error_msg': '密碼輸入不一致'})
else:
return render(request,'登錄界面.html',{'error_msg':'用戶名和密碼錯誤'})
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/',login)
]
http就是基於一次請求一次響應的。
模版語言:
格式1:
{% for i in **%}
{{x}}
{% endfor %}
格式2:
{{ 變量名 }}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1 { width: 100%; height: 50px; background-color:#DDDDDD; opacity: 0.3; } .c4{ width:80%; height:50px; background-color:#DDDDDD; margin-left: 10%; } .c7{ width: 100px; height: 50px; float:left; } .c8{ width: 80px; height: 50px; float:right; } .c9{ width: 120px; height: 50px; float:right; } .c10{ width: 80px; height: 50px; float:right; } .c11{ width: 80px; height: 50px; float:right; } .c12{ width: 50px; height: 50px; float:right; } .s1{ line-height:50px; text-align: center; color:#1F1E1E; } .c2{ width:100%; height: 60px; background-color: #ffffff; margin-top: 20px; } .c5{ width: 80%; height: 60px; background-color: #FFFFFF; margin-left: 10%; } .c3{ width:100%; height:auto; } .c6{ width: 80%; height: auto; margin-left: 10%; } .d1{ width: 500px; height: 400px; float: left; margin-top: 50px; } .d3{ width: 500px; height: 50px; margin-top:60px; } .s2{ font-weight:600; font-size:30px; color: #2e2e2e; line-height:50px; margin-left: 70px; } .p1{ margin-left: 120px; } .p2{ margin-left: 104px; } .i2{ margin-left: 15px; } .s3{ color:red; } .p4{ margin-left: 150px; } .s4{ color:#0000CC; } .i3{ font-size: 14px; } .p5{ margin-left: 200px; } .i5{ font-size: 10px; background-color:red; } .d2{ width: 314px; height:400px; float: right; margin-top: 50px; } .p6{ margin-left:30px; } .p7{ margin-top: 50px; } </style> </head> <body> <div class="c1"> <div class="c4"> <div class="c7"><span class="s1">*收藏網址</span></div> <div class="c8"><span class="s1">客戶服務</span></div> <div class="c9"><span class="s1">VIP會員俱樂部</span></div> <div class="c10"><span class="s1">個人訂單</span></div> <div class="c11"><span class="s1">免費註冊</span></div> <div class="c12"><span class="s1">登錄</span></div> </div> </div> <div class="c2"> <div class="c5"><img src="111.png" alt="悟空"></div> </div> <div class="c3"> <div class="c6"> <div class="d1"> <div class="d3"><span class="s2">註冊新用戶</span></div> <form action="/login/" method="post"> <p class="p1"><span class="s3">*</span>用戶名:<input type="text" name="user" class="i2"></p> <p class="p1"><span class="s3">*</span>手機號:<input type="text" name="phone" class="i2"></p> <p class="p2"><span class="s3">*</span>登錄密碼:<input type="password" name="passwd" class="i2"></p> <p class="p2"><span class="s3">*</span>確認密碼:<input type="password" name="pwd" class="i2"></p> <p class="p4"><input type="checkbox" name="ppp"><span class="i3">我已閱讀並贊成</span><span class="s4 i3">《用戶註冊協議》</span> </p> <p class="p5"><input type="submit" value="開始登陸" class="i5"></p> {{ error_msg }} </form> </div> <div class="d2"> <p class="p6 p7"><img src="222.png" alt="悟天" width='250px' height="200px"></p> </div> </div> </div> </body> </html>
empty:for循環爲空的時候須要執行的任務
{% for teacher in teacher_list %} 要作的事兒 {% empty %} 要作的事兒 {% endfor %}
if判斷語句:
{% if 條件語句 %}
執行語句
{% else %}
執行語句
{% endif %}
{% if student.class_id == class.id %} <option selected value="{{ class.id }}">{{ class.cname }}</option> {% else %} <option value="{{ class.id }}">{{ class.cname }}</option> {% endif %}
識別標籤:{{ 變量名|safe}}
{{ page_html|safe }}
{% csrf_token %}:中間件
{% url '別名' %}:調用別名,在urls文件中,name的值就是別名。
url(r'^login.html/', views.login,name="Login"), # login(request) in template: action="{% url 'Login' %}" <a href='{% url 'Login' %}'>click</a>
with模板:將深查找賦值一個變量
{% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %}
csrf_token:若是是post的請求須要處理,防跨域。
在form標籤裏面使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login.html/" method="post"> {% csrf_token %} <p>姓名:<input type="text" name="user"></p> <p>密碼:<input type="password" name="pwd"></p> <input type="submit"> </form> </body> </html>
在ajax裏面使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script> </head> <body> {% csrf_token %} <p>姓名:<input type="text" id="user"></p> <p>密碼:<input type="password" id="pwd"></p> <button>click</button><span class="error"></span> <script> $("button").on("click",function () { $.ajax({ url:"/foo/", type:"POST", data:{ user:$("#user").val(), pwd:$("#pwd").val(), csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val() }, success:function (data) { console.log(data); console.log(typeof data); console.log(JSON.parse(data)); var data=JSON.parse(data); if (data.user){ location.href="/index/" // 跳轉到首頁 } else { $(".error").html(data.error_msg).css("color","red"); setTimeout(function () { $(".error").html("") },2000) } } }) }) </script> </body> </html>
slock.super:在block模板內部使用,添加新的內容,並不會覆蓋原來的內容。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% block con1 %} <p>con11111</p> {% endblock %} {% block con_li%} <ul> <li>111</li> <li>222</li> <li>333</li> </ul> {% endblock %} </body> </html>
{% extends 'app01/base.html' %}
{% block con_li %}
{{ block.super }}
{% endblock %}
注意:若是在子文件中不使用slock.super模板,就會將父文件中的文本覆蓋。
settings文件的配置:
添加路徑:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], # 在這裏進行設置 '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', ], }, }, ]
註釋內容:
2. 中間件須要註釋一個 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', ]
靜態文件設置:
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, "ss"), # 靜態文件存放位置 )
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '#vofy$6d=w^aoa0kk#8jhtc3mno9o)eil^8-a^u=)cana=9zq^'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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',
]
ROOT_URLCONF = 'bigJob.urls'
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',
],
},
},
]
WSGI_APPLICATION = 'bigJob.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS=(os.path.join(BASE_DIR,'css'),)
IEMPLATE_DIRS=(os.path.join(BASE_DIR,'templates'),)
提交數據格式相似於:
{ 「class_name」: 」全棧7期「 } request.POST.get("「class_name」:")
select默認選中
在對應的option上加selected
檢驗數據有效性:form組件(django自帶),自動判斷輸入的是否爲空
模態框版form提交:由於模態框裏面的提交按鈕是放在form表單外面的,須要使用JS代碼去創建關聯
$("#modal-submit").on("click", function () {
$("#myModal form").submit();
});
檢驗狀態顯示顏色:has-error,若是檢驗出來就會是紅色
$('#setclassname+span').text(dataobj.status).parent().parent().addClass('has-error')
$(document).ready(function () { $('.my-menu-item').on('click', 'a', function () { $(this).toggleClass('active'); var $spanEle = $(this).find('span'); if ($spanEle.removeClass('glyphicon-menu-left')) { $spanEle.removeClass('glyphicon-menu-left').addClass('glyphicon-menu-down'); } else { $spanEle.removeClass('glyphicon-menu-down').addClass('glyphicon-menu-left'); } }); $('#modal-submit').on('click', function () { // {# $('#mymodal from').submit();#} var className = $('#inputclassname2').val(); $.ajax({ url: '/modal_add_class/', type: 'post', data: {'classname': className}, success: function (data) { if (data === 'OK') { // {# if (data.length!=0 ){#} // {# var classData=JOSN.parse(data);#} // {# var newTr=document.cueateElement('tr');#} // {# $(newTr).append('<td>'+classData['id']+'</id>');#} // {# $(newTr).append('<td>'+classData['name']+'</id>');#} // {# $('td:last').clone().appendTo($(newTr));#} // {# $(newTr).appendTo('tbody');#} location.href = '/class_list/'; } else { $('#error-msg').text(data).parent().parent().addClass('has-error') } } }) }) $('table').on('click','.set_class_list',function () { $('#set_mymodal').modal('show'); var $td=$(this).parent().parent().children(); var class_id=$($td[0]).text(); var class_name=$($td[1]).text(); $('#setclassid').val(class_id); $('#setclassname').val(class_name) }); $('#set-modal-submit').on('click',function () { var classid=$('#setclassid').val(); var classname=$('#setclassname').val(); $.ajax({ url:"/modal_set_class/", type:'post', data:{'classid':classid, 'classname':classname}, success:function(data){ var dataobj=JSON.parse(data); console.log(dataobj.status); if (dataobj.status==='OK'){ location.reload() }else{ $('#setclassname+span').text(dataobj.status).parent().parent().addClass('has-error') } } }); }) });
五 AJAX(Async JavaScript and XML)
url:發送的路由路徑
type:以什麼接口的方式
data:發送的數據
success:接收數據成功後執行
error:介紹數據結束後執行
contentType:標識的事讓服務器直到此次請求的格式。
x-www-form-urlencode:將數據拼接成字符串發送過去,這個是默認的
json:將數據轉成js字符串發送過去,告訴服務器是以一個json格式發送的。
headers:請求頭,須要引用jquery裏面的cookie.js文件
cookie("鍵"):在ajax中獲取cookie的值
serinlize:將某個表單中的value值一塊兒拼接好了一塊發送給服務器端。是一種序列化方法。
post:ajax封裝的一個API,以post接口方式發送,若是是get,就以get方式請求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script> <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script> </head> <body> <form id="myForm" action="/reg/" method="post"> {% csrf_token %} <input name="uid" type="hidden" value="1" /> <input id=user name="username" type="text" value="張三" /> <input name="password" type="text" value="123456" /> <select name="grade" id="grade"> <option value="1">一年級</option> <option value="2">二年級</option> <option value="3" selected="selected">三年級</option> <option value="4">四年級</option> <option value="5">五年級</option> <option value="6">六年級</option> </select> <input name="sex" type="radio" checked="checked" value="1" />男 <input name="sex" type="radio" value="0" />女 <input name="hobby" type="checkbox" checked="checked" value="1" />游泳 <input name="hobby" type="checkbox" checked="checked" value="2" />跑步 <input name="hobby" type="checkbox" value="3" />羽毛球 <input name="btn" id="btn" type="button" value="點擊" /> </form> <script> $("#btn").click(function () { $.ajax({ url:"/reg/", type:"POST", //data:$("#myForm").serialize(), data:$(":checkbox,:radio,#user,[name='csrfmiddlewaretoken']").serialize(), success:function (data) { console.log(data) } }) }) </script> <script> {# $(":button").click(function () {#} {##} {# $.ajax({#} {# url:"/login/",#} {# type:"POST",#} {# data:JSON.stringify({#} {# user:$("#user").val(),#} {# pwd:$("#pwd").val()#} {# //csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()#} {# })#} {# , // 'user=alex&pwd=123'#} {# //contentType:"application/x-www-form-urlencoded", // (默認)#} {# //headers:{"X-CSRFToken":$("[name='csrfmiddlewaretoken']").val()},#} {# headers:{"X-CSRFToken":$.cookie("csrftoken")},#} {# contentType:"application/json",#} {# success:function (data) {#} {# console.log(data)#} {# },#} {##} {# })#} {# })#} </script> </body> </html>
ajax能夠在不用刷新頁面的狀況下也能夠提交數據。AJAX是jquery封裝好了的。
頁面刷新:location.reload()
location.reload()
頁面跳轉:location.href='要跳轉的頁面'
location.href = '/class_list/';
模態框使用ajax提交,有返回值,在頁面能夠直接加載數據。
模態框使用ajax提交,返回值
在頁面直接添加數據
在後端:
- HttpResponse("只能放字符串")
我有一個Python的字典,要返回給前端:
要把它轉換成字符串:
json.dumps()
在前端:
- JSON.parse() --> 把字符串轉換回JS對象
- JSON.stringify() --> 把JS對象轉換成字符串
var className = {"items": [1, 2, 3, 4]}
$.ajax({
url: "/modal_add_class/",
type: "post",
data: {"classname": className},
success: function (data) {
console.log(data);
}
}
$.ajax({
url: "/modal_add_class/",
type: "post",
data: json.stringify({"classname": className}),
success: function (data) {
console.log(data);
}
}
項目目錄結構:
- 目錄結構 -mysite -mysite -urls.py 配置對應關係 URL-->函數 -settings.py 配置文件 -wsgi.py socketserver -views.py 本身寫的函數統一放到這裏 __init__.py -templates 存放模板文件的(html文件) -index.html -class_list.html -static -bootstrap -css -bootstrap.min.css -fonts -js -jQuery.3.2.1.min.js -manage.py 管理你Django項目的(有不少命令) python manage.py runserver IP:PORT
cursor.lastrowoid:pymysql下面的一種方法,操做數據庫時,返回他們的ID。
def run_list(self,sql,args=None):
self.cursor.executemany(sql, args)
self.conn.commit()
ret=self.cursor.lastrowid
return ret
AJAX發送數據:
data:{「name」: "alex", "habit": ["抽菸", "喝酒「, "燙頭"]} 這樣不行 data:{「name」: "alex", "habit": JSON.stringify(["抽菸", "喝酒「, "燙頭"])} 這樣能夠
補充:FormData:組裝數據,存放要存放的全部鍵值對
form標籤下面的enctype:修改請求的格式,
multipart/form-data:上傳文件的二進制數據格式,同時支持表單的數據上傳。
ProcessData:讓數據是否編碼成相對應的編碼格式,若是爲true,使用contentType進行編碼格式,若是爲false,就不進行contentType編碼處理。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script> </head> <body> <form action="/index/" method="post" enctype="multipart/form-data"> {% csrf_token %} <p>姓名: <input type="text" name="user"></p> <p>文件: <input type="file" name="cFile"></p> <input type="submit"> </form> <hr> {% csrf_token %} <p>姓名: <input type="text" id="user"></p> <p>文件: <input type="file" id="cFile"></p> <input type="button" value="submit"> <script> $(":button").click(function () { var $formData=new FormData() ; $formData.append("user",$("#user").val()); $formData.append("cFile",$("#cFile")[0].files[0]); $.ajax({ url:"/indexAjax/", type:"post", data:{ cf:$("#cFile")[0].files[0] }, contentType:false, processData:false, // 不對數據作預處理,不進行任何編髮 headers:{"X-CSRFToken":$('[name="csrfmiddlewaretoken"]').val()}, success:function (data) { console.log(data) } }) }) </script> </body> </html>
django的一些特殊操做:
母板的繼承:{% extends 'base.html' %}
在母板裏面定義block - 頁面佈局的block - pasge-css - page-js
引用小組件:{% include 'nav.html' %}
django詳細信息:http://www.cnblogs.com/liwenzhou/p/7931828.html
六登錄驗證
cookic定義:保存在瀏覽器的鍵值對;服務端能夠在瀏覽器上面寫cookic,響應頭裏面會有set-cookic;瀏覽器每次發送請求都會攜帶cookic。下次訪問時判斷cookie狀態
cookic的應用:使用在用戶登錄和保存用戶登錄的。
跳轉回登錄以前的哪一個頁面:在url上面加上一個跳轉url的裝飾器。
request的其餘方法:
request.get_full_path:獲取請求的url
request.COOKIC.get:獲取具體的cookic值
request.set_cookic:設置cookic的值
request.delete_cookic:刪除cookic值
sookic的一些參數:
key:鍵是什麼
value:值是多少
max_age:保存時間,以秒爲單位
expires:保存到一個具體的時間
domain:域名
secure=False:加密用的Https
httponly-False:js的代碼不可以讀取cookic,只可以瀏覽器發請求時攜帶cookic
response.set_signed_cookie("login2", "1", max_age=10, salt="PythonFullstackS7")
設置加鹽的cookic:set_signed_cookic,下面的salt後面加上本身要加的哪一個鹽
response.set_signed_cookie("login2", "1", max_age=10, salt="PythonFullstackS7")
獲取加鹽的cookic:get_signed_cookic,下面的salt後嗎加上本身要獲取的那個cookic鹽值。
request.get_signed_cookie("login2", salt="PythonFullstackS7", default=None)
七 js補充
JSON.stringify:將js對象轉成字符串類型
JSON.parse:將字符串類型轉成js對象
data:{'teacher_name':teacherName,'teacher_class_id':JSON.stringify(teacherClassID)}, var dataobj=JSON.parse(data);
八 分頁
建議:每一個頁面最多顯示11個頁碼
而django內置的分頁只有上一頁和下一頁:
1 from django.shortcuts import render 2 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 3 4 L = [] 5 for i in range(999): 6 L.append(i) 7 8 def index(request): 9 current_page = request.GET.get('p') 10 11 paginator = Paginator(L, 10) 12 # per_page: 每頁顯示條目數量 13 # count: 數據總個數 14 # num_pages:總頁數 15 # page_range:總頁數的索引範圍,如: (1,10),(1,200) 16 # page: page對象 17 try: 18 posts = paginator.page(current_page) 19 # has_next 是否有下一頁 20 # next_page_number 下一頁頁碼 21 # has_previous 是否有上一頁 22 # previous_page_number 上一頁頁碼 23 # object_list 分頁以後的數據列表 24 # number 當前頁 25 # paginator paginator對象 26 except PageNotAnInteger: 27 posts = paginator.page(1) 28 except EmptyPage: 29 posts = paginator.page(paginator.num_pages) 30 return render(request, 'index.html', {'posts': posts})
分頁的準備:
1. 封裝:將一些重用的方法封裝到一個類裏面去,隨時均可以調用
2.app程序準備
""" 分頁組件使用示例: obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info) page_user_list = USER_LIST[obj.start:obj.end] page_html = obj.page_html() return render(request,'index.html',{'users':page_user_list,'page_html':page_html}) """ class Pagination(object): def __init__(self,current_page,all_count,base_url,per_page_num=10,pager_count=11): """ 封裝分頁相關數據 :param current_page: 當前頁 :param all_count: 數據庫中的數據總條數 :param per_page_num: 每頁顯示的數據條數 :param base_url: 分頁中顯示的URL前綴 :param pager_count: 最多顯示的頁碼個數 """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page <1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num self.base_url = base_url # 總頁碼 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count self.pager_count_half = int((pager_count - 1) / 2) @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 若是總頁碼 < 11個: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 總頁碼 > 11 else: # 當前頁若是<=頁面上最多顯示11/2個頁碼 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 當前頁大於5 else: # 頁碼翻到最後 if (self.current_page + self.pager_count_half) > self.all_pager: pager_end = self.all_pager + 1 pager_start = self.all_pager - self.pager_count + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] first_page = '<li><a href="%s?page=%s">首頁</a></li>' % (self.base_url,1,) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '<li><a href="#">上一頁</a></li>' else: prev_page = '<li><a href="%s?page=%s">上一頁</a></li>' % (self.base_url,self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end): if i == self.current_page: temp = '<li class="active"><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,) else: temp = '<li><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '<li><a href="#">下一頁</a></li>' else: next_page = '<li><a href="%s?page=%s">下一頁</a></li>' % (self.base_url,self.current_page + 1,) page_html_list.append(next_page) last_page = '<li><a href="%s?page=%s">尾頁</a></li>' % (self.base_url,self.all_pager,) page_html_list.append(last_page) return ''.join(page_html_list)
3 實現分頁:數據切片獲取;顯示出實現的頁碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css"> </head> <body> <div class="container"> <h1>歡迎登錄:{{ user }} <a href="/logout/">註銷</a></h1> <table class="table table-bordered"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>操做</th> </tr> </thead> <tbody> {% for item in users %} <tr> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td><a href="/edit/{{ item.id }}/?">編輯</a></td> </tr> {% endfor %} </tbody> </table> <div style="text-align: center"> <ul class="pagination"> {{ page_html|safe }} </ul> </div> </div> </body> </html>
九 session的介紹
session的原理:輸入用戶名後回隨機返回給瀏覽器一個字符串,而後服務端本身頁保留同樣的字符串,當瀏覽器在次訪問時,服務端回拿着瀏覽器發過來的字符串和本身保存的字符串進行比較,若是不一致會提示;若是一致,找到相對應的信息,根據用戶需求是否返回相對應的內容。
session就至關於保存在服務端的鍵值對,而cookic就至關於保存在瀏覽器上面的鍵值對。而session是依賴於cookic的。
操做:
設置值:直接調用session
request.session['username']='用戶名'
內部操做:
1 設置set_cookie,返回一組字符串給瀏覽器。 2 本身報保存同樣的字符串,做爲鍵值對的鍵,而後將相關信息做爲值保存爲鍵值對的值。 sessionkey sessiondate 字符串 上傳保存的記錄
取值:獲取瀏覽器的用戶字符串
request.session.get()
內部操做:
''' uuid=request.COOKIE.get("sessionID") # 2134shdc329cbk398asdbk2 django的session表中作過濾: session_user=session.objects.filter(session-key="2134shdc329cbk398asdbk2").first() ret=session_user.session_data.get("Is_login") # {"Is_login":True,"user":"alex"} '''
刪除:刪除具體某一個值
del request.session['想要刪除的哪一個key']
刪除整條記錄:獲取瀏覽器的隨機字符串,在根據字符串去服務端比較並刪除對應的記錄。
request.session.delect()
建立和保存session的命令:主要是對數據庫的遷移
python manage.py makemigrations python manage.py migrate
建立好的session能夠存放着任何位置,默認存放在數據庫:
# ###################### session 配置信息 ########################## SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默認) # SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 存放在緩存裏面 # SESSION_CACHE_ALIAS = 'default' # 表示那臺機器? # SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 存放在文件裏面 # SESSION_FILE_PATH = None # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T # SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 數據庫加緩存 # SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 加密cookic和Session SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認) SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(默認) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時(默認) # SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存(默認) SESSION_SAVE_EVERY_REQUEST = True # 是否每次請求都保存Session,默認修改以後才保存(默認)
使用了session之後,用戶於用戶之間是不會混淆的。
db.sqlite文件:直接連接到數據庫的,將用戶的記錄能夠直接保存
session和cookic的區別是:
session執行的速度慢一些,可是安全性高
cookic執行的速度快一些,可是安全性低
Template:模板對象,實例化處理的就是一個模板對象
將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 咱們可使用 Django的 模板系統 (Template System)來實現這種模式
def current_time(req): # ================================原始的視圖函數 # import datetime # now=datetime.datetime.now() # html="<html><body>如今時刻:<h1>%s.</h1></body></html>" %now # ================================django模板修改的視圖函數 # from django.template import Template,Context # now=datetime.datetime.now() # t=Template('<html><body>如今時刻是:<h1>{{current_date}}</h1></body></html>') # #t=get_template('current_datetime.html') # c=Context({'current_date':str(now)}) # html=t.render(c) # # return HttpResponse(html) #另外一種寫法(推薦) import datetime now=datetime.datetime.now() return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})
在調用這些 屬性時用大的就是點,若是點方法,內能點沒有參數的方法
def index(request): import time c=time.time() ''' render方法的過渡應用: t=Template("<html><body>如今時刻是:<h1>{{current_date}}</h1></body></html>") c=Context({"current_date":c}) html=t.render(c) return HttpResponse(html) ''' l=[111,222,333] d = {"name": "alex"} class Person(): def __init__(self,name,age): self.name=name self.age=age def dream(self): return ("dream.....") alex=Person(name="alex",age=34) egon=Person(name="egon",age=9000) nacha=Person(name="nacha",age=3) person_list=[alex,egon,nacha] return render(request,"app01/index.html",{"l":l,"d":d,"person_list":person_list})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Current time {{ c }}</h1> <hr> <p>{{ l.2 }}</p> <p>{{ d.name}}</p> <p>{{ person_list.1.name }}</p> <p>{{ person_list.1.age }}</p> <hr> {% for person in person_list %} <p>{{ person.name }},{{ person.age }}</p> {% endfor %} <hr> {{ person_list.1.dream }} </body> </html>
Context:上下文對象,實例化出來的是一個上下文對象
十 模板過濾器
練習:datetime.datetime.now():當前時,返回的是一個時間對象,每個時間對象均可以點方法取出對應的值
def index(request): import time c=time.time() ''' render方法的過渡應用: t=Template("<html><body>如今時刻是:<h1>{{current_date}}</h1></body></html>") c=Context({"current_date":c}) html=t.render(c) return HttpResponse(html) ''' i=10 l=[111,222,333] d = {"name": "alex"} class Person(): def __init__(self,name,age): self.name=name self.age=age def dream(self): return ("dream.....") alex=Person(name="alex",age=34) egon=Person(name="egon",age=9000) nacha=Person(name="nacha",age=3) person_list=[alex,egon,nacha] import datetime t=datetime.datetime.now() l2=[] fileSize=12341234 s="hello world" content="hello world hello world hello world hello world" a="<a href=''>click</a>" #return render(request,"app01/index.html",{"l":l,"d":d,"person_list":person_list}) return render(request,"app01/index.html",locals()) def login(request): if request.method=="POST": user=request.POST.get("user") pwd=request.POST.get("pwd") if user=="alex" and pwd=="123": return redirect("/index/") return render(request,"app01/login.html") def archive(request): print(request.path) # /app01/articls/2004/ print(request.path_info) # /app01/articls/2004/ print(request.get_full_path()) # /app01/articls/2004/?a=1 # select * from Article where year=2004 return HttpResponse("2004") def archive2(request,year): return HttpResponse(year)
add:假髮過濾器,將變量的數值加上後面的數字
<p>{{ i|add:5 }}</p>
date:日期過濾器
<p>{{ t|date:"Y-m-d H:i" }}</p>
length:長度過濾器
default:提示用戶信息
<p>{{ l2|default:"沒有符合要求的內容" }}</p>
filesizeformat:文件大小過濾器
<p> 文件大小:{{ fileSize|filesizeformat }}</p>
slice:切片過濾器
<p>{{ s|slice:"2:" }}</p>
truncatechars:按照字符截斷
truncatwords:按照單詞截斷
<p>{{ content|truncatechars:9 }}</p> <p>{{ content|truncatewords:3 }}</p>