一 浏览器相关知识

 http:只有依赖一回,属于短链接,不会报错客户端的信息。

 浏览器相当于一个客户端,客户端的链接

 服务端:socket服务端,起服务监听客户端的请求。

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()

二 框架的介绍

 tornado:模版都是人家写好的,我们只管拿来使用。

 Django:服务端可以自己写,其他的模版都是别人写好的。

 flask:服务端和模版渲染都是自己写的,函数的功能都是别人写好了的。

 所有的web框架叫做web应用服务器。

三 django的安装和使用

 安装:pip install django。

 创建项目:django-admin startproject 项目名

 手动创建:

Django的开始-LMLPHPDjango的开始-LMLPHP

 查看参数: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("")

 新手三件套:

  导入: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内置的分页只有上一页和下一页:

 from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger L = []
for i in range(999):
L.append(i) def index(request):
current_page = request.GET.get('p') paginator = Paginator(L, 10)
# per_page: 每页显示条目数量
# count: 数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page: page对象
try:
posts = paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
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文件:直接链接到数据库的,将用户的记录可以直接保存

Django的开始-LMLPHP

 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=="":
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("") 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>

   

   

05-11 15:39