Django-04 View
Django中视图的功能主要是处理用户操作,操作数据和返回数据给用户。
0 start
0.1 设置路由
helloapp/urls.py , 子路由
from django.urls import path
from helloapp.views import index as index_view
urlpatterns = [
path('haha', index_view)
]
HelloWorldPro/HelloWorldPro/urls.py , 主路由
from django.contrib import admin
from django.urls import path, include
from helloapp.views import hello as hello_view
urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', hello_view),
path('index', include('helloapp.urls'))
]
可以在主陆游获取导入视图,也可以使用include导入。
0.2 编写视图函数
修改HelloWorldPro/helloapp/views.py
from django.shortcuts import HttpResponse, redirect
def hello(request):
print(dir(request))
return redirect('/index')
return HttpResponse("Hello Baloneo")
def index(req):
return HttpResponse("Hello Django")
1 获取请求信息
1.1 基础
- 在ajax中
contentType:主要设置你发送给服务器的格式,
dataType:设置你收到服务器数据的格式。 - 在html表单中,enctype有
application/x-www-form-urlencoded 默认
multipart/form-data
text/xml
- 在http实体首部字段中,Content-Type表示实体内容是什么
除了上面的enctype所有的,还有
application/json
enctype和ajax的contentType选项的会影响HTTP报文的Content-Type类型。以上都是在POST请求。
对于请求方法为GET请求的,会在URI上传递数据。
在Django中,视图的第一个参数request可以直接获取到请求报文的实体数据:
- GET(request.GET['name'])
- POST(request.POST['passwd'])
对于其它请求例如PUT,可以使用如下方法:
from django.http import QueryDict
put = QueryDict(request.body)
key = put.get('key')
field = put.get('field')
field_value = put.get('field-value')
2 Cookie
http协议是无状态的。下一次去访问一个页面时并不知道上一次对这个页面做了什么。使用Cookie可以存储每个网站的信息。并且是不能跨源。
设置cookie:
def cookie(request):
response = HttpResponse("<h1>设置Cookie</h1>")
response.set_cookie('h1', '你好', max_age=60 * 24)
return response
在js中也是可以设置cookie的。
获取cookie
def cookie_get(request):
response = HttpResponse("读取Cookie,数据如下:<br>")
if 'id' in request.COOKIES:
response.write('<h1>' + request.COOKIES['h1'] + '</h1>')
return response
request.COOKIES
是类字典类型。
同样的,js中也是可以获取cookie的。
3 Session
Session需要服务器保存用户唯一id,也需要使用cookie。
通过存储在浏览器的id,服务器也存储一个相同的id,根据这个id,服务器可以找到相应的信息。
这个id是很难伪造的。
使用session需要配置。默认已经配置。
设置:
def login(request):
request.session['is_login']=True
return HttpResponse('写session')
删除:
del request.session['键']
设置超时时间:
request.session.set_expiry(value)
value=数字
value=0
value=None 永不消失
3.1 Login
使用前后端分离逻辑,利用session,用户登陆成功,将数据存储到session里面。
if passwd is True and user is True:
request.session['is_login'] = True
request.session['user_id'] = userAuthent.id
request.session['user_name'] = userAuthent.username
request.session.set_expiry(60 * 60 * 24)
return JsonResponse({'result': 200, 'msg': '登录成功'})
4 CSRF
假如你登陆的你的银行帐号,cookie信息都还没有消失。你访问了另一个黑网站,这个网站会把POST请求地址改成银行网站地址。给银行网站(相当于用户点击了转帐的链接),如果没有任何校验,它发送出去了,如何解决这个安全问题?
在银行网站里的cookie设置一个csrf_token,cookie会在每次传输都带上,但是还不够,需要在表单提交的数据
上添加一个csrf_token字段,提交给服务器,服务器判断这两个token是否相同。
Flask实现的逻辑不是这样的。Flask中是比较数据库里面的存储值和上传的值。
那么,黑网站不能获取cookie数据吗?
不能,浏览器的同源策略,黑网站获取不了银行网站的cookie。
每一次刷新页面的csrf_token值不一样。
在HelloWorldPro/HelloWorldPro/settings.py 的MIDDLEWARE
列表里,默认配置了。
'django.middleware.csrf.CsrfViewMiddleware',
一般403状态码就是csrf问题。
那么,对于前后端分离的架构,可以写一个视图获取一个随机生成的token。
def get_token(request):
token = django.middleware.csrf.get_token(request)
return JsonResponse({'token': token})
在ajax中设置请求头:
'X-CSRFToken':cookies.get('csrftoken')
5 Json响应
使用HttoResponse:
from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
import json
# Create your views here.
def index(request):
data={
'name':'zhangsan',
'age':18,
}
return HttpResponse(json.dumps(data),content_type="application/json")
使用JsonResponse:
from django.shortcuts import render
from django.http import JsonResponse
def hello(request):
return JsonResponse({'result': 200, 'msg': '连接成功'})
传递列表格式的Json(不推荐)
from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
# Create your views here.
def index(request):
listdata=[1,2,3,4,5]
return JsonResponse(listdata,safe=False)