zoukankan      html  css  js  c++  java
  • 三、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方法"""
    

  • 相关阅读:
    Javascript事件处理进阶
    Restful API设计指南
    Git&GitHub
    Linux补充
    堡垒机
    Python发送邮件
    js获取当前页面url网址信息
    高并发的秒杀系统
    CMDB开发
    Tornado
  • 原文地址:https://www.cnblogs.com/borntodie/p/14330623.html
Copyright © 2011-2022 走看看