django版本区别,JsonResponse对象,form表单上传文件,request其他方法,FBV与CBV,模板语法传值

虚拟环境

我们在实际开发工作中 针对不同的项目需要为其配备对应的解释器环境
	eg:
          项目1 
          	django2.2 pymysql3.3 requests1.1
          项目2 
          	django1.1
          项目3
          	flask
诸多项目在你的机器上如何无障碍的打开并运行
  方式1:把所有需要用到的模块全部下载下来 如果有相同模块不同版本每次都重新下载替换
  方式2:提前准备好多个解释器环境 针对不同的项目切换即可
 
# 创建虚拟环境 
	相当于在下载一个全新的解释器
# 识别虚拟环境
	文件目录中有一个venv文件夹
# 如何切换环境
	选择不用的解释器即可 全文不要再次勾选new enviroment...

django版本区别

路由的区别
        - django1.X版使用的是url函数
        - django2.x版使用的是re_path与path
从2.x以后,建议使用path——是一个准确路径,path() 第一个参数不支持正则。

from django.urls import path,re_path
如果使用正则方式,建议使用re_path,用法与1.x的url完全一致。

path转化器

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


path('articles/<int:year>/', views.year_archive),
<int:year>相当于一个有名分组,其中int是django提供的转换器,相当于正则表达式,专门用
于匹配数字类型,而year则是我们为有名分组命的名,并且int会将匹配成功的结果转换成整型后按照
格式(year=整型值)传给函数year_archive


实现匹配这种路径:http://127.0.0.1:8000/L/p/4444.html
    - path('<str:name>/p/<int:id>.html', views.lpgin),
    - re_path(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login)
    - url(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login)
    # url在2.x之后的版本不建议使用,可以使用re_path代替

'''转化器不能在re_path中使用'''

JsonResponse对象

使用前需要导入模块
from django.http import JsonResponse
JsonResponse
	
	- 主要用于前后端交互发送数据
	
    - 使用json模块来返回json格式的数据
        def test_json(request):
            import json
            user_dict = {'user': '王', 'password': 123456}
            # ensure_ascii=True会将中文转换为编码 {"user": "\u738b", "password": 123456}
            json_str = json.dumps(user_dict, ensure_ascii=False)
            return HttpResponse(json_str)
    - 使用Django的JsonResponse对象实现
        def test_json(request):
            from django.http import JsonResponse
            user_dict = {'user': '王', 'password': 123456}
            # JsonResponse 的传值方式 将json.dumps()中的参数用字典方式传送
            return JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False})
    - 将非字典格式的序列通过JsonResponse对象传值
        def test_json(request):
            from django.http import JsonResponse
            ls = [i for i in range(10)]
            # JsonResponse 的传值方式 将json.dumps()中的参数用字典方式传送
            # 非字典序列必须设置参数 safe=False
            return JsonResponse(ls, json_dumps_params={'ensure_ascii': False}, safe=False)

form表单上传文件

form表单上传的数据中如果含有文件 那么需要做以下几件事
  1.method必须是post
  2.enctype必须修改为multipart/form-data
  	默认是application/x-www-form-urlencoded
  3.后端需要使用request.FILES获取

案例

前端:
<form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="f1">   
    <button>上传</button>
</form>

后端:
def index(request):
    if request.method == 'POST':
        file = request.FILES.get('f1') # 获取文件对象
        with open(file.name, 'wb') as f: #file.name上传文件的源文件名
            for i in file:
                f.write(i)
    return HttpResponse('ok')

request其他方法

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

针对这个网址:https://pythondjango.cn/blog/articles/?page=2
request.path
	获取路径
'''
  request.path仅提供相对于根目录的url相对路径,不包含参数。它的输出是一个字符串,结果如下所示:

  '/blog/articles/'
'''


request.path_info
	获取路径
'''
  request.path_info也仅提供相对于根目录的url相对路径,不含参数。它的输出也是一个字符
串,与request.path相同:

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

  该方法用于获取包含完整参数的相对于根目录的相对url路径。它的直接输出内容是个WSGI请求对
象。如果要获取字符串形式的完整url路径,一定要不要忘了在后面加括号。

  request.get_full_path()的输出结果为:

  'blog/articles/?page=2'
'''

FBV与CBV

FBV

FBV,即 func base views,函数视图,在视图里使用函数方法处理请求。
我们平时在写前后端不分离项目的时候,视图中的方法基本上都是使用的FBV方法,相对于易于理解的
角度来讲,FBV确实是比较好理解一些,对于一些实现的功能相近,但是功能单一的项目来讲,基本是
完全够使用的,基本的示例如下所示:
def order(request):
  if request.method =='GET":
    return HttpResponse(获取订单')
  elif request.method =="POST":
    return HttpResponse("创建订单')

CBV

CBV,即 class base views ,类视图,就是在视图里使用类方法处理请求。
需要导入一个View类,通过自定义一个子类继承这个类,我们可以利用View里面的dispatch()方法
来判断请求是get还是post。dispatch方法的本质是一个反射器,可以根据名字来调用同名的方法。

View类的部分代码可以看出dispatch通过反射获取列表里面的方法名称
'''
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
  def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
'''

CBV案例


from django.views import View
class Home(View):  
    def get(self,request):
        print(request.method)
        return render(request, 'home.html')
        
    def post(self,request):
        print(request.method,'POST')
        return render(request, 'home.html')

为了调用自定义的类里面的方法,在url里面,我们需要调用View类的as_view()方法作为入口。

from django.conf.urls import url
from myapp.views 
import MyView
urlpatterns = [
    url(r'^about/', MyView.as_view()),
]

CBV执行原理(as_view())

以上面的案例为例
1.首先在项目启动时就会执行一次as_view方法,通过对as_view方法源码的查看,我们可以得知是返回一个闭包函数名view。
'''
源码
@classonlymethod
    def as_view(cls, **initkwargs):
          ......
          def view(request, *args, **kwargs):
              ......
          return view
'''
那么此时的urls.py文件中的配置就相当与,url('^Myviews$',views.Myviews.view),这也说明了CBV与FBV在路由匹配本质是一样的。
2.在路由匹配成功后,会执行view函数会return self.dispatch(request, *args, **kwargs),也就是会执行dispatch函数。
'''
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)
'''
3.dispatch():中  通过 getattr 反射 拿到 子类的 get 或post 方法   给到handler 再返回执行,
          1.判断请求方法 是否存在于  http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

          2. 如果存在 就执行子类 中对应的方法(get,post.......)

          3.handler = getattr(self, request.method.lower(), self.http_method_not_allowed) 

               此时handler 就是一个 方法    return  handler (request ,*args,**kwargs) 加括号执行

'''
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
'''

模板语法传值

语法格式

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

传值的两种方式

传值方式1:指名道姓的传  适用于数据量较少的情况       节省资源
return render(request, 'ab_temp.html', {'name':name})
传值方式2:打包传值  适用于数据量较多的情况(偷懒)     浪费资源
  '''locals() 将当前名称空间中所有的名字全部传递给html页面'''
  return render(request, 'ab_temp.html', locals())

传值的范围

  基本数据类型都可以
  函数名
  	模板语法会自动加括号执行并将函数的返回值展示到页面上
    不支持传参(模板语法会自动忽略有参函数)
  文件名
  	直接显示文件IO对象
  类名
  	自动加括号实例化成对象
  对象名
  	直接显示对象的地址 并且具备调用属性和方法的能力

  django模板语法针对容器类型的取值 只有一种方式>>>:句点符
  	既可以点key也可以点索引  django内部自动识别
  {{ list.0 }} #获取列表第一个值
posted @ 2022-05-13 23:22  春游去动物园  阅读(111)  评论(0编辑  收藏  举报