Django视图层
虚拟环境
实际开发工作中,针对不同的项目需要为其配备对应的解释器环境
例如:
项目1
django2.28
项目2
django1.11
诸多项目在一个机器上运行
方式一
把所有需要用到的模块全部下载下来,如果有相同模块不同版本每次都采用重新替换
方式二
提前准备好多个解释器环境,针对不同的项目切换即可
创建虚拟环境
相当于再下载一个全新的解释器
识别虚拟环境
文件目录中有一个venv文件夹
如何切换环境
新建项目时选择不用的解释器
注意:一定不要再次勾选new enviroment
django路由层版本区别
django1.x与2.x、3.x有细微区别
路由匹配的方法不一样
url() 支持正则 path() 第一个参数不支持正则
如果想使用正则,需要手动导入re_path
from django.urls import path,re_path
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^home/$', home)
]
path方法提供了转换器功能
path('home/<int:id>/', home)
匹配对应位置的数据并且自动转换类型
Django2.2默认的PathConveter五种转换器
str:匹配除了路径分隔符(/)之外的非空字符串,若没有转换器,默认使用str作为转换器
int:匹配0及正整数
slug:匹配字母、数字以及横杠、下划线组成的字符串
uuid:匹配格式化的uuid,如 048627d3-8569-546e-p6h8-8g931e885d00
path:匹配任何非空字符串,包含路径分隔符(/)
视图函数返回值
视图函数必须返回一个HttpResonse对象
HttpResponse
class HttpResponse(...):
pass
render
def render(...):
return HttpResponse(...)
redirect
def redirect(...):
JsonResponse对象
# 导入方式
from django.http import JsonResponse
# 使用
user_dict = {'name': 'stephanie', 'age': 22, 'nationality': 'UK','hobby':'喜欢中国文化'}
return JsonResponse(user_dict)
return JsonResponse(f'{user_dict}', safe=False)
return JsonResponse(f'字典:{user_dict}', safe=False, json_dumps_params={'ensure_ascii': False})
return JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False})
# JsonResponse的优势
django的JsonResponse对象扩大了json序列化的数据类型的范围
即是选择使用JsonResponse对象而不是原始的json模块的原因
form表单上传文件
form表单上传的数据中如果含有文件,需要单独处理
前提:method必须是post
第一步:enctype需修改为multipart/form-data
默认是application/x-www-form-urlencoded
第二步:后端需要使用request.FILES获取
file = request.FILES.get('file')
print(file)
with open("/".join(["static1/avatar", f"{username}.png"]), 'wb') as f:
for line in file:
f.write(line)
request其他方法
方法 | 作用 |
---|---|
request.method | 获取request具体请求方式 |
request.POST | POST方式获取数据 |
request.GET | GET方式获取数据 |
request.FILES | 获取文件数据 |
request.body | 存放的是接收的原始二进制数据 |
request.path | 获取路径 |
request.path_info | 获取路径 |
request.get_full_path() | 获取路径并且还可以获取到路径后面携带的参数 |
FBV与CBV
FBV:基于函数的视图
url(r'^func/',函数名)
CBV:基于类的视图
from django import views
class MyLoginView(views.View):
def get(self, request):
return HttpResponse("from CBV get view")
def post(self, request):
return HttpResponse("from CBV post view")
# 路由
url(r'^ab_cbv/', views.MyLoginView.as_view())
CBV源码剖析
切入点:路由匹配
类名点属性as_view加括号
as_view可能是普通的静态方法
as_view可能是绑定给类的方法
对象查找属性的顺序
先从对象自身开始、再从产生对象的类、之后是各个父类
MyLoginView.as_view()
先从编写的MyLoginView中查找
没有找到再去父类Views中查找
函数名加括号执行优先级最高
url(r'^login_cbv/', views.MyLoginView.as_view())
项目启动就会执行as_view方法,查看源码返回闭包函数名view
def as_view(cls):
def view(cls):
pass
return view
url(r'^login_cbv/', views.view)
CBV与FBV在路由匹配本质一样
路由匹配成功之后执行view函数
def view():
self = cls()
return self.dispatch(request, *args, **kwargs)
执行dispatch方法
需要注意查找的顺序
def dispatch():
handler = getattr(self, request.method.lower())
return handler(request, *args, **kwargs)
模板语法传值
django提供的模板语法仅有两个符号
{{}}:主要用于变量相关操作
例如:引用
{%%}:主要用于逻辑相关操作
例如:循环、判断
传值的两种方式
传值方式一:键值对形式传值
适用于数据较少的情况,节省资源
return render(request, 'login.html', {'name':name})
class Test_view(views.View):
def get(self, request):
l = [1, 2, 3, 4]
dic = {'name': 'stephanie', 'age': 22}
return render(request, 'test.html', {'l':l, 'dic':dic})
传值方式二:打包传值
适用于数据量较多的情况,资源消耗大
locals() 将当前名称空间中所有的名字全部传递给html页面
class Test_view(views.View):
def get(self, request):
l = [1, 2, 3, 4]
dic = {'name': 'stephanie', 'age': 22}
return render(request, 'test.html', locals())
传值的范围
基本数据类型都可以
函数名
模板语法会自动加括号执行并将函数的返回值展示到页面上
不支持传参,模板语法自动忽略有参函数
def get(self, request):
def func():
return 'from func'
return render(request, 'test.html', locals())
文件名
直接显示文件IO对象
def get(self, request):
base_path = os.path.dirname(os.path.dirname(__file__))
music_path = os.path.join(base_path, 'static1')
print(music_path)
print(os.listdir(music_path))
print(os.listdir(music_path)[0])
music_name = os.listdir(music_path)[0]
return render(request, 'test.html', locals())
类名
自动加括号实例化成对象
def get(self, request):
class myclass:
name = 'tom'
return render(request, 'test.html', locals())
对象名
直接显示对象的地址并且能够调用属性和方法
def get(self, request):
class myclass:
name = 'tom'
obj = myclass()
return render(request, 'test.html', locals())
django模板语法针对容器类型的取值
仅有句点符一种方式
既可以句点符加key也可以句点符加索引,django内部能够自动识别
<div class="row">
<div class="col-md-4 col-md-offset-4" style="text-align: center">
<br><br><br>
<p>{{ l }}</p>
<br>
<p>{{ l.1 }}</p>
<br>
<p>{{ l.2 }}</p>
<br>
<p>{{ l.3 }}</p>
<br>
<p>{{ dic.name }}</p>
<br>
<p>{{ dic.age }}</p>
</div>
</div>