ICode9

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

今日学习内容总结5.1

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

标签:总结 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

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

ICode9版权所有