虚拟环境与django版本与视图层相关知识


目录
  • 虚拟环境
  • django版本区别
  • 视图函数返回值
  • JsonResponse对象
  • form表单上传文件
  • request方法
  • FBV与CBV
  • CBV源码剖析
  • 模板语法传值
    • 传值方式
    • 传值范围

虚拟环境

我们在实际开发工作中,针对不同的项目需要为其配备对应的解释器环境,比如项目1需要django2.2、项目2需要django1.1等。

运行相应的项目时你总不能每次都去下载不同版本进行替换吧?所以这时候就需要用到虚拟环境了。

创建虚拟环境

1.打开pycharm,file-->new project。

2.选择如下相应选项,创建。

3.等待创建完成。

创建完成后,这时项目目录下有一个venv文件夹,有这个文件夹就代表这是一个虚拟环境。

并且我们可以查看当前解释器安装的模块,当前解释器是没有任何其他模块的。

使用虚拟环境

在创建项目时,我们可以选择虚拟环境中的解释器,后缀带有(venv)的解释器就是虚拟环境,选择了虚拟环境后,只需要在虚拟环境中安装对应版本模块就可以了。

django版本区别

django1.x与2.x、3.x有些许区别。

主要区别是在路由层,1.x路由匹配使用url方法,2.x与3.x使用的是path方法

  • url():支持正则表达式
  • path():不支持正则表达式

当然,2.x、3.x的版本也有方法可以支持正则表达式:

  • re_path():支持正则表达式

path方法还提供了转换器功能:

path('index//', index)

上述代码中它会匹配对应位置的数据并且自动转换类型,比如127.0.0.1/index/123/,它会把123转成整型,如果说地址为127.0.0.1/index/abc/,那么它会报错。

其他转换器:

  • str:匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
  • int:匹配正整数,包括0
  • slug:匹配字母、数字、下划线以及横杠组成的字符串
  • uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
  • path:匹配任何非空字符串,包含了路径分隔符(/),不能用"?"

视图函数返回值

视图函数都必须返回一个HttpResponse对象。

首先是之前说的三个返回方法:HttpResponse、render、redirect。

HttpResponse肯定返回的是一个HttpResponse对象,事实上,render()和redirect()方法返回的都是一个HttpResponse对象,我们可以查看这两个方法的源码进行查看。

比如render()方法源码:

redirect()方法往更深的源码去查看,这里不方便演示。

JsonResponse对象

除了HttpResponse、render、redirect这三个可以给视图函数设置返回值,还有一个JsonResponse也可以,它用于返回一个json格式的数据。

from django.http import JsonResponse
def index(request):
    user_dict = {'name':'tom', 'age':18, 'hobby':'读书'}
    return JsonResponse(user_dict)

此时的中文是无法正常显示的,我们需要添加参数才能正常显示:

from django.http import JsonResponse
def index(request):
    user_dict = {'name':'tom', 'age':18, 'hobby':'读书'}
    return JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})

如果想要把其他类型转成json格式发送,需要把JsonResponse方法的safe参数设置为False

from django.http import JsonResponse
def index(request):
    l = [11, 22, 33]
    return JsonResponse(user_dict, safe=False)

form表单上传文件

form表单上传的数据中如果含有文件,那么需要以下要求:

  1. 表单属性method必须是post
  2. 表单属性enctype必须修改为multipart/form-data
  3. 后端需要使用request.FILES获取

index.html




    
    Title


views.py

def index(request):
    if request.method == 'POST':
        print(request.FILES)  # 专门获取文件数据
        file_obj = request.FILES.get('my_file')  # 根据你的input标签的name属性获取
        print(file_obj.name)  # 查看文件名
        with open(file_obj.name,'wb') as f:  # 直接通过文件名保存本件
            for line in file_obj:
                f.write(line)

    return render(request, 'index.html')

request方法

request方法 作用
request.method 获取请求方法
request.POST 获取POST请求数据
request.GET 获取GET请求数据
request.FILES 获取文件数据
request.body 获取最原始请求数据(二进制数据)
request.path 获取地址后缀路径,但不会获取路径后面携带的参数
request.path_info 与request.path一致
request.get_full_path() 获取地址后缀路径并且还可以获取到路径后面携带的参数

FBV与CBV

FBV即基于函数的视图,CBV即基于类的视图。我们之前一直都是使用FBV。

CBV使用

视图层(views.py)

from django import views
class MyView(views.View):
    def get(self, request):
        return HttpResponse("from CBV get view")
    def post(self, request):
        return HttpResponse("from CBV post view")

路由层(urls.py)

urlpatterns = [
    url(r'^index/', views.MyView.as_view()),
]

如果请求方式是GET,则会自动执行类里面的get方法;如果请求方式是POST,则会自动执行类里面的post方法;

CBV源码剖析

想详细了解CBD源码我们可以从路由层出发。

1.首先views.MyView.as_view()很明显是调用了类里面的as_view方法,在pycharm中按住ctrl点击as_view()查看详情。

2.因为我们在类中并没有定义as_view方法,所以这是父类Views中的方法。

3.as_view()返回的是一个view函数,说明路由匹配成功执行了view函数,然后我们在细看view函数。

4.view函数返回了一个dispatch()方法,并且是用我们自己的类实例化得到的对象调用的,我们的类中没有dispatch()这个方法,所以这个明显又是父类Views中的方法。

5.查看dispatch()详情

6.request.method这个方法我们都知道,用于返回请求方法的,这里进行了一个判断:判断请求方法是否在http_method_names中。

7.我们再来看看http_method_names有哪些内容。

8.再回到dispatch()方法if判断中,说如果request.method在http_method_names中,就使用getattr()获取对象中的方法,最后在return那里调用并返回。

总结:也就是说,如果请求的方法(request.method)在http_method_names中,就会调用我们类中的对应的方法。

模板语法传值

django提供的模板语法只有两个符号:

  • {{ }}:主要用于变量相关操作(引用)
  • {% %}:主要用于逻辑相关操作(循环、判断)

传值方式

传值方式一:使用render()方法传值(适用于数据量较少的情况, 节省资源)

后端传值:

def index(request):
    return render(request, 'index.html', {'name': 'tom', 'age':18})

前端获取:

{{ name }}

{{ age }}

传值方式二:使用locals()方法传值,它会将当前名称空间中所有的名字全部传递给html页面(适用于数据量较多的情况,浪费资源)

后端传值:

def index(request):
    name = 'tom'
    age = 18
    return render(request, 'index.html', locals())

前端获取:

{{ name }}

{{ age }}

传值范围

1.基本数据类型都可以。

2.函数名:模板语法会自动加括号执行并将函数的返回值展示到页面上,并且只会执行无参函数,如果是有参函数,模板语法会自动忽略。

3.文件名:直接显示文件IO对象。

4.类名:自动加括号实例化成对象,并显示对象的地址,同时具备调用属性和方法的能力。

5.对象名:直接显示对象的地址,并且具备调用属性和方法的能力。

取值补充

django模板语法针对容器类型的取值,只有一种方式:句点符。

比如我传了一个容器类型数据:

data = {
    'name': [
        1, {'age':18}
    ]
}

前端获取age的值

{{ data.name.1.age }}