• 三、Django之视图层


    Django之视图层

    1、三板斧

    """
    HttpResponse
    	返回字符串类型
    render
    	返回html页面,并且在返回给浏览器之前还可以给html文件传值
    redirect
    	重定向
    	
    如果我们一个视图函数没有返回值的话,会直接报如下错误
    The view app01.views.index didn't return an HttpResponse object. It returned None instead.
    点击三板斧的源码,我们会发现最后都是HttpResponse对象,所以视图函数必须要返回HTTPResponse对象
    """
    
    # render简单内部原理
    from django.template import Template,Context
    res = Template('<h1>{{ user }}</h1>')
    con = Context({ 'user':{'username':'jason','password':123} })
    ret = res.render(con)
    return HttpResponse(ret)
    

    2、JsonResponse对象

    """
    json格式的数据可以跨语言交互,前端后端数据加护需要使用使用json作为过渡
    
    前端序列化					后端序列化(python)
    JSON.stringify()				json.dumps()
    JSON.parse()					json.loads()
    """
    
    1. 原始方法实现数据序列化

      # 在视图函数中,我们要把一个字符串的数据转化成json数据,然后传递给前端
      import json
      from django.http import JsonResponse
      
      def ab_json(request):
          user_dict = {'username':'jason','password':123,'hobby':'read'}
          # json模块方式,ensure_ascii=False在dumps里默认是True,默认不显示中文字符
          json_str = json.dumps(user_dict,ensure_ascii=False)
          return HttpResponse(json_str) 
      
    2. 使用JsonResponse实现数据序列化

      import json
      from django.http import JsonResponse
      
      def ab_json(request):
          user_dict={'username':'jason','password':123,'hobby':'read'}
          return JsonResponse(user_dict,json_dumps_parse={'ensure_ascii':False}) # 读源码可以知道 本质上还是用json模块实现的,只是添加了一些其他的功能
      
    3. 注意:JsonResponse默认只能序列化字典,序列化其他需要加safe参数

      # 默认只能序列化字典,序列化其他需要加safe参数
      import json
      from django.http import JsonResponse
      
      def ab_json(request):
          l = [111,222,333,444,555]
          return JsonResponse(l,safe=False)
      

    3、from表单上传文件及后端获取

    1. 注意:from表单上传文件类型的数据

      • method必须指定成post
      • enctype必须换成multipart/form-data
    2. 具体实现

      def ab_fire(request):
      	if request.method == 'POST':
              # print(request.POST) 只能获取普通的简单键值对 文件不行
              print(request.FIRE) # 获取列表嵌对象的文件数据对象
              # <MultiValueDict: {'file': [<InMemoryUploadedFile: u=1288812541,1979816195&fm=26&gp=0.jpg (image/jpeg)>]}>
              fire_obj = request.FIRE.get('fire') # 获取具体的文件对象
              with open(fire_obj.name,'wb') as f:
                  for line in fire_obj.chunks():   # 官方推荐加上chunks方法 其他加不加都一样
                      f.write(line)
      	return render(request,'from.html')
      

    4、FBV与CBV

    1. FBV(function base views)

      # 路由层
      	url(r'^login/',views.login)
      # 视图层
      	def login(request):
              user_id = request.GET.get('user_id')
            	user_obj = 	models.User.object.filter(id=user_id).first()
              if request.method == 'POST':
                  user_name = request.POST.get('username')
                  pass_word = request.POST.get('password')
                  if user_obj:
                      if user_obj.password == pass_word:
                          return HttpResponse('登录成功')
                  else:
                      return HttpResponse('登录失败')
      		return redirect('/register/')
      
    2. CBV(class base views)

      # 路由层
         	url(r'^login/',views.Login.as_view())
      # 视图层
      	from django.views import View
      	class Login(View):
          	def get(self,request):
              	return render(request,'form.html')
          	def post(self,request):
              	return HttpResponse('post方法')
      # CBV可以根据不同的请求直接匹配到不同的方法去执行
      

    5、CBV源码

    # 突破口在urls.py
    url(r'^login/',views.MyLogin.as_view())
    
    """
    函数名/方法名加括号执行优先级最高
    猜测
    	as_view()
    		要么是被staticmethod修饰的静态方法
    		要么是被classmethod修饰的类方法  ------ 正确
    		
    	@classonlymethod
    	def as_view(cls,**initkwargs):
    		pass
    """
    
    # 具体源码解析
    
    # 1.as_view里面的源码
    @classonlymethod
    def as_view(cls,**initkwargs):
    	# cls就是我们自己写的类 MyLogin
        def view(request,*args,**kwargs):
            self = cls(**initkwargs) # cls就是我们自己写的类
            # self = MyLogin(**initkwargs) 产生一个我们自己写的类的对象
            return self.dispatch(request,*args,**kwargs)
       		"""
       		以后我们会经常需要看源码 但是在看python源码的时候 一定要时刻提醒自己面向对象属性方法查询顺序
       			先从对象自己这里找
       			再去产生对象的类里面找
       			之后再去父类里面找
       			...
       		总结:看源码只要看到了self点一个东西 一定要问你自己当前这个self到底是谁
       		"""
        view.view_class = cls
        view.view_initkwargs = initkwargs
        update_wrapper(view, cls, updated=())
        update_wrapper(view, cls.dispatch, assigned=())
    	return view  
    # 2.dspatch里的源码 CBV的精髓
    def dispatch(self,request,*args,**kwargs):
        # 获取当前请求的小写格式,然后对比当前请求方式是否合法
        # get请求为例
        # post请求为例
        if request.method.lower() in self.http_method_names:
            handler = getattr(self,request.method.lower(),self.http_method_not__allowed)
            """
            反射:通过字符串来操作对象的属性或者类方法
            	handler = getattr(自己写的类产生的对象,'get',当前找不到get属性或者方法的时候就会使用第三个参数)
            	handler = 我们自己写的类里面的get方法
            """
        else:
            handler = self.http_method_not_allowed
        return handler(request,*args,**kwargs)
    	"""自动调用get方法"""
    

  • 相关阅读:
    Nodejs下载和第一个Nodejs示例
    永久关闭Win10工具栏的TaskbarSearch控件
    对称加密,非对称加密,散列算法,签名算法
    【转】TTL和RS232之间的详细对比
    zlg核心板linux系统中查看系统内存等使用信息
    Power BI后台自动刷新数据报错 The operation was throttled by Power BI Premium because there were too many datasets being processed concurrently.
    剪切板和上传文件内容获取
    CSS, LESS, SCSS, SASS总结
    文字程序
    electron 打包“ERR_ELECTRON_BUILDER_CANNOT_EXECUTE”
  • 原文地址:https://www.cnblogs.com/borntodie/p/14330623.html
Copyright © 2020-2023  润新知