第四篇:Django的视图层
Posted cnhyk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第四篇:Django的视图层相关的知识,希望对你有一定的参考价值。
视图层的方法
HttpResponse
返回的是字符串
def index(request):
return HttpResponse('你好啊小妹妹')
render
返回html页面 并且可以给html页面传数据
def login(request):
return render(request, 'login.html', {'user_dic': {'username': 'json', 'password': 123}, 'mes': 'hello'})
# 返回html页面,并可以给html传入字典
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#取字典中的值#}
{{ user_dic.username }}
</body>
</html>
render原理
from django.template import Template, Context
def ab_render(request):
temp = Template('<h3>{{user_dict}}<br>{{user_dict.name}}<br> {{user_dict.password}}</h3>')
context = Context({'user_dict': {'name': 'jason', 'password': 123}})
res = temp.render(context)
return HttpResponse(res)
redirect
重定向
def home(request):
return redirect('https://www.baidu.com')
JsonResponse
import json from django.http import JsonResponse
def xxx(request):
user_dict = {'username':'jason好帅哦 我好喜欢!','password':'123'}
# json_str = json.dumps(user_dict,ensure_ascii=False)
# return HttpResponse(json_str)
l = [1,2,3,4,5,6,7,8,9,]
# return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
return JsonResponse(l,safe=False) # 序列化非字典格式数据 需要将safe改为False
from django.http import JsonResponse
def xxx(request):
user_dict = {'username':'jason好帅哦 我好喜欢!','password':'123'}
# json_str = json.dumps(user_dict,ensure_ascii=False)
# return HttpResponse(json_str)
l = [1,2,3,4,5,6,7,8,9,]
# return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
return JsonResponse(l,safe=False) # 序列化非字典格式数据 需要将safe改为False
前后端数据交互
form表单上传文件
action 什么都不写,默认朝当前页面提交数据
method post 什么都不写默认为get请求,不会提交数据,需要改为post
enctype formdata 更改为上传文件
示例:
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"> </script>
<link href="https://cdn.bootcss.com/twitterbootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitterbootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="myfile">
<input type="submit">
</form>
</body>
</html>
views.py
def home(request):
if request.method == 'POST':
# 获取用户上传的文件数据
print(request.FILES)
file_obj = request.FILES.get('myfile') # 文件句柄
print(file_obj.name) # 获取文件名
# 下面的for循环可以写成django推荐的写法
# for chunk in file_obj.chunks():
# print(chunk)
with open(file_obj.name,'wb') as f:
for line in file_obj:
f.write(line)
return render(request,'home.html')
视图函数的FBV和CBV
FBV:基于函数的视图
CBV:基于类的视图
CBV基本写法:
# views.py
from django.views import View
class MyLogin(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
return HttpResponse('我是类里面的POST方法')
# urls.py
url(r'login/', views.MyLogin.as_view())
朝login提交get请求会自动执行MyLogin里面的get方法
而提交post请求也会自动执行MyLogin里面的post方法
为什么MyLogin针对不同的请求方法能够自动执行对应的方法?
研究源码的突破口
url(r'^login/', views.MyLogin.as_view())
as_view要么是类里面定义的普通函数 @staticmethod
要么是类里面定义的绑定给类的方法 @classmethod
点进去查看:
我们发现,最后返回的是一个view,因此我们外面的url相当于下面:
url(r'^login/', views.MyLogin.view)
再去看view函数:
url(r'^login/', views.MyLogin.dispatch)
回到自己创建的MyLogin的类中,查看继承了View这个类,点进去,找到dispatch这个方法:
继续往下看:
因此,此时的url相当于:
url(r'^login/', views.MyLogin.get)
看源码不需要每一句都看懂,只看自己能够看得懂的
CBV源码(******)
MyClass.as_view()
# 函数名加括号执行优先级最高
@classonlymethod
def as_view(...):
def view(...):
...
return view
# 变形
url(r'^index/',views.view) # CBV与FBV在路由匹配上本质是一样的
def view(...):
self = cls(...) # 生成的是我们自己写的类的对象
...
return self.dispatch(...)
"""
当你看到self.属性或方法的时候 不要想当然
一定要遵循对象的属性和方法的查询顺序
对象本身 产生对象的类 类的父类
"""
def dispatch(...):
# 先判断当前请求方式是否在默认的八个合法请求方式内
if request.method.lower() in ['get','post','delete','options'...]
# 利用反射获取对象中对应的属性
handler = getattr(self,request.method.lower(),报错信息)
return handler(...) # 执行获取到的方法
Django Settings源码
首先我们先获得django的内部的配置文件:
from django.conf import global_settings, settings
global_settings文件中有很多配置信息
django暴露给用户一个可以自定义的配置 但是内部也有默认的配置
用户配置了就用用户的 用户没有配就用默认的
点settings进去看:
全局大字典初始为空,因此相当于:
os.environ.get(ENVIRONMENT_VARIABLE)
点进去ENVIRONMENT_VARIABLE:
此时:
{}.get("DJANGO_SETTINGS_MODULE")
因此,我们需要找到谁给大字典里设置了DJANGO_SETTINGS_MODULE的键值对,我们点开 manage.py中查看:
因此:
再往下看:
调用Settings类,传入mysite,产生对象,因此点进Sttings中:
from django.conf import global_settings,settings
settings = LazySettings()
class LazySettings(...):
def _setup(...):
# 获取暴露给用户的配置文件字符串路径
setting_module = os.environ.get(纯大写变量名)
"""
manage.py
os.environ.setdefault(纯大写变量名,'暴露给用户的配置文件字符串路径')
"""
Settings(setting_module)
def Settings(...)
# 先遍历全局默认的配置文件 给对象设置键值对
for setting in dir(global_settings):
if setting.isupper():
setattr(self,setting,getattr(global_settings,setting))
# 再遍历暴露给用户的配置文件 给对象设置键值对
md = importlib.import_module(setting_module)
for setting in dir(md):
if setting.isupper():
setattr(self,setting,getattr(md,setting))
"""
利用的其实就是字典的键存在和不存在 下面语句的作用
dict[key] = value
"""
以上是关于第四篇:Django的视图层的主要内容,如果未能解决你的问题,请参考以下文章