一 浏览器相关知识

 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-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文件:直接链接到数据库的,将用户的记录可以直接保存

 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>

   

   

Django的开始的更多相关文章

  1. 异步任务队列Celery在Django中的使用

    前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...

  2. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  3. django server之间通过remote user 相互调用

    首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...

  4. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  5. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  6. 《Django By Example》第三章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第三章滚烫出炉,大家请不要吐槽文中 ...

  7. 《Django By Example》第二章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:翻译完第一章后,发现翻译第二章的速 ...

  8. 《Django By Example》第一章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:本人目前在杭州某家互联网公司工作, ...

  9. Django

    一.Django 简介 Django 是一个由 Python 写成的开放源代码的 Web 应用框架.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统) ...

  10. Django admin定制化,User字段扩展[原创]

    前言 参考上篇博文,我们利用了OneToOneField的方式使用了django自带的user,http://www.cnblogs.com/caseast/p/5909248.html , 但这么用 ...

随机推荐

  1. HDU-1074.DoingHomework(撞鸭dp二进制压缩版)

    之前做过一道二进制压缩的题目,感觉也不是很难吧,但是由于见少识窄,这道题一看就知道是撞鸭dp,却总是无从下手....最后看了一眼博客,才顿悟,本次做这道题的作用知识让自己更多的认识二进制压缩,并无其它 ...

  2. java 对一个字符串去重,即去掉字符串内重复元素

    String str ="abc|efa|abc|efa|abc"; String str1 = str.replaceAll("(?s)(.)(?=.*\\1)&quo ...

  3. linux下面redis安装

    安装方法1redis1.下载安装包2.解压程序包tar -zxvf  redis-3.2.6.tar.gz3.编译源程序make(编译失败,查看是否安装gcc   如果没有yum install gc ...

  4. spring-mvc.xml 和 application-context.xml的区别

    转自:https://www.cnblogs.com/binlin1987/p/7053016.html application-context.xml是全局的,应用于多个serverlet,配合li ...

  5. Python开发【第二篇】:Python基本数据类型

    运算符 设定:a=10,b=20 . 算数运算 2.比较运算 3.赋值运算 4.逻辑运算 5.成员运算 基本数据类型 1.数字 int(整型)     在32位机器上,整数的位数为32位,取值范围为- ...

  6. 【laravel VS lumen】

    读取项目的配置信息 读取config文件database.php中的default属性信息 laravel:config('database.default'); lumen:app()->co ...

  7. Linux 线程】线程同步《四》

    1.信号量 (1)概念 信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区. 不多做解释,要使用信号量同步,需要包含头文件semaphore.h. ...

  8. 纯java+maven+sqlserver使用mybatis

    第一部分:基本实现 @参考文章,在此基础上略作修改 1,新建maven项目JavaMybatis导入依赖 <dependencies> <dependency> <gro ...

  9. Topological Sorting拓扑排序

    定义: Topological Sorting is a method of arranging the vertices in a directed acyclic graph (DAG有向无环图) ...

  10. [leetcode]103. Binary Tree Zigzag Level Order Traversal二叉树来回遍历

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...