Django后端笔记
视图
视图的功能
接收请求,进行处理,与M和T进行交互,返回应答。
返回html内容 HttpResponse,也可能重定向 redirect,还可以返回json数据。
视图函数使用
使用
-
定义视图函数
request参数必须有。是一个HttpRequest类型的对象。参数名可以变化,但不要更改。 -
配置url
建立url和视图函数之间的对应关系。
url配置的过程
-
在项目的urls文件中包含具体应用的urls文件,在具体应用的urls文件中包含具体url和视图的对应关系。
-
url配置项是定义在一个名叫urlpatterns 的列表中,其中的每一个元素就是一个配置项,每一个配置项都调用url函数。
url匹配的过程
url:http://127.0.0.1:8000/aindex?a=1
- 去除域名和后面的参数,剩下==/aindex==,再把前面的/去掉,剩下aindex
- 拿aindex先到项目的url.py文件中进行从上到下的匹配,匹配成功之后执行后面对应的处理动作,就是把匹配成功的部分a字符去除,然后拿剩下的部分index到应用的urls.py文件中再进行从上到下的匹配。
- 如果匹配成功则调用相应的视图产生内容返回给客户端。如果匹配失败则产生404错误。
错误视图
404:找不到页面,关闭调试模式之后,默认会显示一个标准的错误页面,如果要显示自定义的页面,则需要的templates目录下面自定义一个404.html文件。
- url没有配置
- url配置错误
500: 服务器端的错误。
- 视图出错
网站开发完成需要关闭调试模式,在settings.py文件中:
DEBUG=False
ALLOWED_HOST=[ ‘*’]
捕获url参数
进行url匹配时,把所需要的捕获的部分设置成一个正则表达式组,这样django框架就会自动把匹配成功后相应组的内容作为参数传递给视图函数。
- 位置参数
位置参数,参数名可以随意指定 - 关键字参数:在位置参数的基础上给正则表达式组命名即可。
?P<组名>
关键字参数,视图中参数名必须和正则表达式组名一致.
urls.py
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^index$', views.index), # 首页
# url(r'^showarg(\d+)$', views.show_arg), # 捕获url参数:位置参数
url(r'^showarg(?P<num>\d+)$', views.show_arg),# 捕获url参数:关键字参数
普通登录案例
- 显示出登录页面
- a) 设计url,通过浏览器访问 http://127.0.0.1:8000/login 时显示登录页面。
- b) 设计url对应的视图函数login。
- c) 编写模板文件login.html。
url | 视图 | 模板文件 |
---|---|---|
/login | login | login.html |
- 登录校验功能
-
a) 设计url,点击登录页的登录按钮发起请求http://127.0.0.1:8000/login_check时进行登录校验。
-
b) 设计url对应的视图函数login_check。
接收表单提交过来的数据。
进行登录校验,若用户名密码正确则跳转到登录成功页。若失败在跳转到登录页面。 -
c) 登录成功后跳转到首页。
url | 视图 | 模板文件 |
---|---|---|
/login_check | login_check | 无 |
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
POST:提交的参数请求头。数据安全性要求比较高的时候使用post.
GET:提交的参数在url中。
<form method="post" action="/login_check">
用户名:<input type="text" name="username" value="{
{ username }}"><br/>
密码:<input type="password" name="password"><br/>
<input type="checkbox" name="remember">记住用户名<br/>
<input type="submit" value="登录">
</form>
</body>
</html>
view.py
def login(request):
'''显示登录页面'''
return render(request, 'booktest/login.html')
def login_check(request):
'''登录校验视图'''
# request.POST 保存的是post方式提交的参数 QueryDict
# request.GET 保存是get方式提交的参数
print(request.method)
# 1.获取提交的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
remember = request.POST.get('remember')
# 2.进行登录的校验
# 实际开发:根据用户名和密码查找数据库
# 模拟: smart 123
if username == 'smart' and password == '123':
# 用户名密码正确,跳转到首页
response = redirect('/index')
urls.py
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^index$', views.index), # 首页
# url(r'^showarg(\d+)$', views.show_arg), # 捕获url参数:位置参数
url(r'^showarg(?P<num>\d+)$', views.show_arg),# 捕获url参数:关键字参数
url(r'^login$', views.login), # 显示登录页面
url(r'^login_check$', views.login_check), # 用户登录校验
]
Ajax
基本概念
异步的javascript。在不全部加载某一个页面部的情况下,对页面进行局的刷新,ajax请求都在后台。
图片,css文件,js文件都是静态文件。
设置静态文件夹
- 发起ajax请求:jquery发起
- 执行相应的视图函数,返回json内容
- 执行相应的回调函数。通过判断json内容,进行相应处理。
test_ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax</title>
<script src="/static/js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
// 绑定btnAjax的click事件
$('#btnAjax').click(function () {
alert(1)
$.ajax({
'url': '/ajax_handle',
'dataType': 'json',
// 'async': false, // 同步的ajax请求
}).success(function (data) {
// 进行处理
alert(2)
if (data.res == 1){
$('#message').show().html('提示信息')
}
})
alert(3)
})
})
</script>
<style>
#message {
display: none;
color: red;
}
</style>
</head>
<body>
<input type="button" id="btnAjax" value="ajax请求">
<div id="message"></div>
</body>
</html>
view.py
# /test_ajax
def ajax_test(request):
'''显示ajax页面'''
return render(request, 'booktest/test_ajax.html')
def ajax_handle(request):
'''ajax请求处理'''
# 返回的json数据 {'res':1}
return JsonResponse({
'res':1})
urls.py
from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^index$', views.index), # 首页
# url(r'^showarg(\d+)$', views.show_arg), # 捕获url参数:位置参数
url(r'^showarg(?P<num>\d+)$', views.show_arg),# 捕获url参数:关键字参数
url(r'^login$', views.login), # 显示登录页面
url(r'^login_check$', views.login_check), # 用户登录校验
url(r'^test_ajax$', views.ajax_test), # 显示ajax页面
url(r'^ajax_handle$', views.ajax_handle), # ajax处理
]
ajax调试方法
Ajax登录案例
1) 首先分析出请求地址时需要携带的参数。
2) 视图函数处理完成之后,所返回的json的格式。
- 显示出登录页面
a) 设计url,通过浏览器访问 http://127.0.0.1:8000/login_ajax 时显示登录页面。
b) 设计url对应的视图函数login_ajax。
c) 编写模板文件login_ajax.html。
在里面写jquery代码发起ajax请求。
- 登录校验功能
a) 设计url,点击登录页的登录按钮发起请求http://127.0.0.1:8000/login_ajax_check时进行登录校验。
b) 设计url对应的视图函数login_ajax_check。
接收post提交过来的数据。
进行登录校验,并返回json内容。 JsonRepsone
Json格式如下
{‘res’:‘1’} #表示登录成功
{‘res’:‘0’} #表示登录失败
login_ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax登录页面</title>
<script src="/static/js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
$('#btnLogin').click(function () {
// 1.获取用户名和密码
username = $('#username').val()
password = $('#password').val()
// 2.发起post ajax请求,/login_ajax_check, 携带用户名和密码
$.ajax({
'url':'/login_ajax_check',
'type': 'post',
'data': {
'username':username, 'password':password},
'dataType': 'json'
}).success(function (data) {
// 登录成功 {
'res':1}
// 登录失败 {
'res':0}
if (data.res == 0){
$('#errmsg').show().html('用户名或密码错误')
}
else{
// 跳转到首页
location.href = '/index'
}
})
})
})
</script>
<style>
#errmsg{
display: none;
color: red;
}
</style>
</head>
<body>
<div>
用户名:<input type="text" id="username"><br/>
密码:<input type="password" id="password"><br/>
<input type="button" id="btnLogin" value="登录">
<div id="errmsg"></div>
</div>
</body>
</html>
urls.py
from django.conf.urls import url
from booktest import views
url(r'^login_ajax$', views.login_ajax), # 显示ajax登录页面
url(r'^login_ajax_check$', views.login_ajax_check), # ajax登录校验
view.py
# /login_ajax
def login_ajax(request):
'''显示ajax登录页面'''
return render(request, 'booktest/login_ajax.html')
# /login_ajax_check
def login_ajax_check(request):
'''ajax登录校验'''
# 1.获取用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# 2.进行校验,返回json数据
if username == 'smart' and password == '123':
# 用户名密码正确
return JsonResponse({
'res':1})
# return redirect('/index') ajax请求在后台,不要返回页面或者重定向
else:
# 用户名或密码错误
return JsonResponse({
'res':0})
状态保持
http协议是无状态的。下一次去访问一个页面时并不知道上一次对这个页面做了什么。
Cookie
cookie是由服务器生成,存储在浏览器端的一小段文本信息。
cookie的特点:
- 以键值对方式进行存储。
- 通过浏览器访问一个网站时,会将浏览器存储的跟网站相关的所有cookie信息发送给该网站的服务器。request.COOKIES
- cookie是基于域名安全的。www.baidu.com www.tudou.com
- cookie是有过期时间的,如果不指定,默认关闭浏览器之后cookie就会过期。
view.py
from django.shortcuts import render,redirect
from django.http import HttpResponse,JsonResponse
from datetime import datetime,timedelta
# /set_cookie
def set_cookie(request):
'''设置cookie信息'''
response = HttpResponse('设置cookie')
# 设置一个cookie信息,名字为num, 值为1 过期时间为14天
response.set_cookie('num', 1, max_age=14*24*3600)
# response.set_cookie('num', 1, expires=datetime.now()+timedelta(days=14)) #同上
# response.set_cookie('num2', 2)
# 返回response
return response
# /get_cookie
def get_cookie(request):
'''获取cookie的信息'''
# 取出cookie num的值
num = request.COOKIES['num']
return HttpResponse(num)
记住用户名案例
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
POST:提交的参数请求头。数据安全性要求比较高的时候使用post.
GET:提交的参数在url中。
<form method="post" action="/login_check">
用户名:<input type="text" name="username" value="{
{ username }}"><br/>
密码:<input type="password" name="password"><br/>
<input type="checkbox" name="remember">记住用户名<br/>
<input type="submit" value="登录">
</form>
</body>
</html>
view.py
from django.shortcuts import render,redirect
from django.http import HttpResponse,JsonResponse
from datetime import datetime,timedelta
def login(request):
'''显示登录页面'''
# 判断用户是否登录
if request.session.has_key('islogin'):
# 用户已登录, 跳转到首页
return redirect('/index')
else:
# 用户未登录
# 获取cookie username
if 'username' in request.COOKIES:
# 获取记住的用户名
username = request.COOKIES['username']
else:
username = ''
return render(request, 'booktest/login.html', {
'username':username})
def login_check(request):
'''登录校验视图'''
# request.POST 保存的是post方式提交的参数 QueryDict
# request.GET 保存是get方式提交的参数
print(request.method)
# 1.获取提交的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
remember = request.POST.get('remember')
# 2.进行登录的校验
# 实际开发:根据用户名和密码查找数据库
# 模拟: smart 123
if username == 'smart' and password == '123':
# 用户名密码正确,跳转到首页
response = redirect('/index')
# 判断是否需要记住用户名
if remember == 'on':
# 设置cookie username,过期时间1周
response.set_cookie('username', username, max_age=7*24*3600)
Session
对于敏感、重要的信息,建议要储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息。
在服务器端进行状态保持的方案就是Session。
启用Session
Django项目默认启用Session。
打开test3/settings.py文件,在项MIDDLEWARE_CLASSES中启用Session中间件。
session中间件
禁用Session:将Session中间件删除。
存储方式
打开test3/settings.py文件,设置SESSION_ENGINE项指定Session数据存储的方式,可以存储在数据库、缓存、Redis等。
1)存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式。
SESSION_ENGINE='django.contrib.sessions.backends.db'
2)存储在缓存中:存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
SESSION_ENGINE='django.contrib.sessions.backends.cache'
3)混合存储:优先从本机内存中存取,如果没有则从数据库中存取。
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
4)如果存储在数据库中,需要在项INSTALLED_APPS中安装Session应用。
5)迁移后会在数据库中创建出存储Session的表。
6)表结构如下图。
session存储在服务器端。
session的特点:
- session是以键值对进行存储的。
- session依赖于cookie。唯一的标识码保存在sessionid cookie中。
- session也是有过期时间,如果不指定,默认两周就会过期。
记住用户登录状态案例。
对象及方法
通过HttpRequest对象的session属性进行会话的读写操作。
1) 以键值对的格式写session。
request.session['键']=值
2)根据键读取值。
request.session.get('键',默认值)
3)清除所有session,在存储中删除值部分。
request.session.clear()
4)清除session数据,在存储中删除session的整条数据。
request.session.flush()
5)删除session中的指定键及值,在存储中只删除某个键及对应的值。
del request.session['键']
6)设置会话的超时时间,如果没有指定过期时间则两个星期后过期。
request.session.set_expiry(value)
- 如果value是一个整数,会话将在value秒没有活动后过期。
- 如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期。
- 如果value为None,那么会话永不过期。
view.py
# /set_session
def set_session(request):
'''设置session'''
request.session['username'] = 'smart'
request.session['age'] = 18
# request.session.set_expiry(5)
return HttpResponse('设置session')
# /get_session
def get_session(request):
'''获取session'''
username = request.session['username']
age = request.session['age']
return HttpResponse(username+':'+str(age))
# /clear_session
def clear_session(request):
'''清除session信息'''
# request.session.clear()
request.session.flush()
return HttpResponse('清除成功')
cookie和session的应用场景
cookie:记住用户名。安全性要求不高。
session:涉及到安全性要求比较高的数据。银行卡账户,密码
def login_check(request):
'''登录校验视图'''
# request.POST 保存的是post方式提交的参数 QueryDict
# request.GET 保存是get方式提交的参数
print(request.method)
# 1.获取提交的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
remember = request.POST.get('remember')
# 2.进行登录的校验
# 实际开发:根据用户名和密码查找数据库
# 模拟: smart 123
if username == 'smart' and password == '123':
# 用户名密码正确,跳转到首页
response = redirect('/index')
# 判断是否需要记住用户名
if remember == 'on':
# 设置cookie username,过期时间1周
response.set_cookie('username', username, max_age=7*24*3600)
# 记住用户登录状态
# 只有session中有islogin,就认为用户已登录
request.session['islogin'] = True
# 返回应答
return response
else:
# 用户名或密码错误,跳转到登录页面
return redirect('/login')
使用Redis存储Session
会话还支持文件、纯cookie、Memcached、Redis等方式存储,下面演示使用redis存储。
1)安装包。
pip install django-redis-sessions==0.5.6
2)修改test3/settings文件,增加如下项:
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 2
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'
3)打开booktest/views.py文件,修改session_test视图如下:
def session_test(request):
request.session['h1']='hello'
# h1=request.session.get('h1')
# del request.session['h1']
# request.session.flush()
return HttpResponse('ok')
4)管理redis的命令,需要保证redis服务被开启。
查看:ps ajx|grep redis
启动:sudo service redis start
停止:sudo service redis stop
使用客户端连接服务器:redis-cli
切换数据库:select 2
查看所有的键:keys *
获取指定键的值:get name
5)刷新浏览器,在redis客户端中查看数据如下。