ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

今日学习内容总结5.1

2022-05-14 16:32:06  阅读:6  来源: 互联网

标签:总结 5.1 name self request 学习 HttpResponse path view


今日学习内容总结

      

虚拟环境

为什么使用本地虚拟环境

    1. 在时间开发过程中,我们会给不同的项目配备不同的环境

    2. 项目用到什么就装什么,用不到的一概不装

    3. 不同的项目解释器环境都不一样

创建虚拟环境

      1.打开pycharm项目,查看初始的 package : 打开Pycharm----->File----->settings----->Project:[项目名]----->Python Interpreter

      2.进入 Project下 Project-Interpreter,点击show all或者添加新的虚拟环境。

      下次创建新项目可以直接选择已经创建好的虚拟环境。

Django版本区别

路由层

    1. django 1.x路由层使用url方法

    2. django 2.x和3.x版本使用path方法

    url方法与path方法的区别
         url() 第一个参数支持正则
         path()第一个参数是不支持正则的,可以使用 re_path替代url()
              urlpatterns = [
                  # 用法完全一致
                  url(r'^app01/', include(('app01.urls','app01'))),
                  re_path(r'^app02/', include(('app02.urls','app02'))),
              ]

      path方法提供了转换器功能,内部支持五种转换器:

    1. str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
      
    2. int,匹配正整数,包含0。

    3. slug,匹配字母、数字以及横杠、下划线组成的字符串。

    4. uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。

    5. path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)

视图函数返回值

      视图层是实现业务逻辑的关键层,视图函数必须要返回一个 HttpResponse 对象, 如果未返回, 会出现如下错误 :

      提示你没有返回一个 HttpResponse 对象, 而是返回了一个 None

      必须返回该对象的原因,我们 Ctrl + 鼠标点击分别查看三者的源码可得到解释:

    # HttpResponse

    # render
    def render(request, template_name, context=None, content_type=None, status=None, using=None):
            """
            Returns a HttpResponse whose content is filled with the result of calling
            django.template.loader.render_to_string() with the passed arguments.
            """
            content = loader.render_to_string(template_name, context, request, using=using)
            return HttpResponse(content, content_type, status)  # 返回一个HttpResponse对象
            
    # redirect
    内部继承了 HttpResponse 类

JsonResponse 对象

Json格式的作用

    1. JSON的全称是"JavaScript Object Notation", 意思是JavaScript对象表示法

    2. 前后端的交互一般使用 JSON 实现数据的跨域传输

实现给前端返回 json 格式数据

      1.直接自己序列化

    import json

    def test(resquest):
        user_info = {"name":"shawn","age":23,"sex":"male","hobby":"吃饭"}
        data = json.dumps(user_info,ensure_ascii=False)
        return HttpResponse(data)

      2.使用JsonResponse对象

    from django.http import JsonResponse

    def test2(request):
        user_info = {"name":"shawn","age":23,"sex":"male","hobby":"吃饭"}
        return JsonResponse(user_info)

       JsonResponse 对象没有 ensure_ascii 参数是如何保证中文正常显示的,可以查看JsonResponse 源码

      JsonResponse 返回的也是 HttpResponse 对象。并且封装了json模块,对json序列化的数据类型做了扩充。

from表单上传文件

注意事项

    1. method 必须指定 post 提交

    2. enctype 须修改为 multipart/form-data,默认是application/x-www-form-urlencoded。

    3. 后端需要使用request.FILES获取

      代码操作:

    # html
    <body>
    <div class="container">
        <div class="col-md-8 col-md-offset-2">
            <form action="" method="post" enctype="multipart/form-data">
                <input type="file" class="form-control" name="myfile">
                <input type="submit" class="btn btn-warning btn-block" value="提交">
            </form>
        </div>
    </div>
    </body>
    
    # views
      def form_test(request):
          if request.method == "POST":
              # 从文件对象字典中获取名为"myfile"的文件对象
              file_obj = request.FILES.get('myfile')  
              file_name = file_obj.name
              # 保存方式一:
              with open(f'./{file_name}',"wb")as f:
                  for line in file_obj:
                      f.write(line)
              # 保存方式二:(官方推荐)
              with open(f'./{file_name}',"wb")as f:
                  for line in file_obj.chunks():
                      f.write(line)

          return render(request,'test.html')

      # 打印个别结果看看
      print(request.FILES)
      '''
      <MultiValueDict: {'myfile': [<InMemoryUploadedFile: README.md (application/octet-stream)>]}>
      '''
      print(file_obj,type(file_obj))
      '''
      README.md <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
      '''
      print(file_obj.name)
      '''
      README.md
      '''

      # 官方推荐写法 chunks() 的源码
          def chunks(self, chunk_size=None):
              self.file.seek(0)
              yield self.read()
      # 一个迭代器

request其他方法

    1. request.method   获取大写的请求类型

    2. request.POST   获取POST携带的数据

    3. request.GET   获取url?后面的数据

    4. request.FILES   获取文件

    5. request.body   存放的是接收过来的最原始的二进制数据
          request.POST、request.GET、request.FILES这些获取数据的方法其实都从body中获取数据并解析存放

    6. request.path   获取路径

    7. request.path_info   获取路径

    8. request.get_full_path()   获取路径并且还可以获取到路径后面携带的参数

FBV与CBV

FBV : ( function-based-view ) 基于函数的视图

    url(r'^index/',函数名)

      我们之前在视图层写的都是基于函数的视图。

CBV : ( class-based-view ) 基于类的视图

    # views.py 文件
    from django.views import View

    def test_func(request):
        return render(request,'test.html')
        
    class MyView(View):
        def get(self,request):
            return HttpResponse('触发了get方法:')
        
        def post(self,request):
            return HttpResponse('触发了post方法:')

    # urls.py 文件
    from django.urls import path,re_path,include
    from app02 import views

    urlpatterns = [
        re_path(r'^test/',views.test_func),
        re_path(r'^func',views.MyView.as_view())
    ]

    # 模板文件 test.html
    <div>
        <form action="/func/" method="post" enctype="multipart/form-data">
            <input type="file">
            <input type="submit">
        </form>
    </div>

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

CBV源码剖析

切入点

    re_path(r'^func',views.MyView.as_view())  # as_view() 是什么东西

      我们 Ctrl + 点击查看其源码

      发现它是一个类方法, 查看其整体结构(只看框起来的即可, 其他的不用管), 该方法内部有一个 view 方法, 并且返回值是 view 的内存地址, 类似于闭包函数:

      于是我们得到一个初步结果:

    re_path(r'^func',views.MyView.as_view())  # 等同于下面
    re_path(r'^func',views.view) # 看着是不是与普通的路由没有什么区别了 : 通过匹配触发视图函数的运行

      那么 view 是一个什么样的函数呢? 现在突破口变成了 view 方法了。我们再看其源码(只看框起来的即可,其他的不用管) :

    "self = cls(**initkwargs)"
    # cls是什么? 记得上面的类方法吗? 类调用时传入类本身

    # 我们是通过MyView来调用as_view的, 那么cls也就是MyView

    # 类加括号实例化得到对象self, 这个self就是我们自己的类产生的对象 : self=MyView(**initkwargs),我们不用去管里面的参数

    # 接下来看看view的返回值 : self.dispatch(request, *args, **kwargs)

    # 也就是去MyView类实例出的对象里面去找dispatch方法并执行,很显然self对象中没有该方法,于是去类中去找,也没有

    # 最后到父类View中去找,发现就在as_view类方法的下面找到了

      我们在看它下面的逻辑代码:

      逻辑很简单,使用了反射的知识点

    # 先是拿到当前请求方式的大写字符转成小写, 然后判断在不在后面的 self.http_method_names 里面

    # Ctrl+点击 看看这是个什么东西 : 
    'http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']'

    # 发现是8种常用的请求方式列表, 接着返回dispatch源码查看,为了方便我们假设现在的是get请求方式

    # 判断get请求在请求列表里面,于是执行紧跟其下的代码...我们先看看getattr()得到的是什么结果

    # 判断我们的self是否有名叫get的属性或方法,如果有则返回该属性的值或方法的内存地址,否则返回 self.http_method_not_allowed, 这是个啥,我们 Ctrl+点击 也来看看:

模板语法传值

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

	{{}}:主要用于变量相关操作(引用)

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

传值的两种方式

      传值方式1:名字传值,适用于数据量较少的情况,节省资源。

    return render(request, 'ab_temp.html', {'name':name})

      传值方式2:打包传值,适用于数据量较多的情况。

    return render(request, 'ab_temp.html', locals())
        # locals() 将当前名称空间中所有的名字全部传递给html页面

传值的范围

      基本数据类型都可以。

    函数名:会自动将函数名调用之后的返回值传值,但是不支持函数参数

    文件名:直接显示文件IO对象

    类名:自动加括号实例化对象

    对象名:显示对象的地址,并具备调用属性和方法的能力

    取值:.句点符,.key(django内部自动识别)

标签:总结,5.1,name,self,request,学习,HttpResponse,path,view
来源: https://www.cnblogs.com/blank1210/p/16270494.html

专注分享技术,共同学习,共同进步。侵权联系[admin#icode9.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有