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>

posted @ 2022-05-14 00:43  一梦便是数千载  阅读(24)  评论(0编辑  收藏  举报