zoukankan      html  css  js  c++  java
  • Django -- 视图层

    三板斧

    """
    HttpResponse
        返回字符串类型
    render
        返回html页面 并且在返回给浏览器之前还可以给html文件传值
    redirect
        重定向
    """
    # 视图函数必须要返回一个HttpResponse对象  正确   研究三者的源码即可得处结论
    # The view app01.views.index didn't return an HttpResponse object. It returned None instead.
    
    # render简单内部原理
        from django.template import Template,Context
        res = Template('<h1>{{ user }}</h1>')
        con = Context({'user':{'username':'jason','password':123}})
        ret = res.render(con)
        print(ret)
        return HttpResponse(ret)

    jsonResponse对象

    """
    json格式的数据有什么用?
        前后端数据交互需要使用到json作为过渡 实现跨语言传输数据
    
    前端序列化
        JSON.stringify()                    json.dumps()
        JSON.parse()                            json.loads()
    """
    import json
    from django.http import JsonResponse
    def ab_json(request):
        user_dict = {'username':'jason好帅哦,我好喜欢!','password':'123','hobby':'girl'}
    
        l = [111,222,333,444,555]
        # 先转成json格式字符串
        # json_str = json.dumps(user_dict,ensure_ascii=False)
        # 将该字符串返回
        # return HttpResponse(json_str)
        # 读源码掌握用法
        return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
        # In order to allow non-dict objects to be serialized set the safe parameter to False.
        return JsonResponse(l,safe=False)  
        # 默认只能序列化字典 序列化其他需要加safe参数    

    form表单上传文件

    """
    form表单上传文件类型的数据
        1.method必须指定成post
        2.enctype必须换成formdata
    """
    def ab_file(request):
        if request.method == 'POST':
            # print(request.POST)  # 只能获取普通的简直对数据 文件不行
            print(request.FILES)  # 获取文件数据
            # <MultiValueDict: {'file': [<InMemoryUploadedFile: u=1288812541,1979816195&fm=26&gp=0.jpg (image/jpeg)>]}>
            file_obj = request.FILES.get('file')  # 获取文件对象
            print(file_obj.name) # 获取文件名
            with open(file_obj.name,'wb') as f:
                for line in file_obj.chunks():  # 推荐加上chunks方法 加与不加效果一样
                    f.write(line)
    
        return render(request,'form.html')

    request对象方法

    """
    request.method            获取标点提交的请求方式
        request.POST        获取POST请求数据
        request.GET            获取GET请求数据
    request.FILES            获取文件
    request.body            原生的浏览器发过来的二进制数据  后面详细的讲
    request.path            只能拿到路由无法拿到路由后面的参数
    request.path_info        只能拿到路由无法拿到路由后面的参数
    request.get_full_path()  能过获取完整的url及问号后面的参数 
    """
        print(request.path)  # /app01/ab_file/
        print(request.path_info)  # /app01/ab_file/
        print(request.get_full_path())  # /app01/ab_file/?username=jason

    FBV(function based view)与CBV(class based view)

    • 视图函数既可以是函数也可以是类
    #CBV
        #CBV路由层:
        url(r'^login/',views.MyLogin.as_view())
    
        视图层:
        from django.views import View
        class MyLogin(View):
            def get(self,request):
                return render(request,'')
    
            def post(self,request):
                return HttpResponse('post方法')
    • CBV内部执行流程
    # CBV本质上也是FBV,同样也是views.函数内存地址
    
    #CBV
    #路由
    url(r'^login/', views.MyLogin.as_views())
    '''
    as_views()是类MyLogin所继承的父类View下的一个类方法
    views.MyLogin.as_views()会优先执行as_views()方法并将MyLogin作为第一个参数传入
    as_views()方法是一个闭包函数,内部嵌套了函数view,并将view的内存地址作为返回值返回
    '''
    # 路由层可变形为:url(r'^login/', views.view)
    # 由此可以判断出CBV与FBV在路由匹配上本质是一样的,都是路由对应函数内存地址
    
    # 后端
    from django.views import View
    class MyLogin(View):
        def get(self, request):
            return render(request, 'login.html')
        def post(self, request):
            return HttpResponse('post请求')
    '''
    view函数在当浏览器访问login时被触发,此时会先产生一个MyLogin的对象绑定给变量self
    
    self.属性,依照面向对象的查找顺序先找自己再找对象所在的类,再找父类依次往上,直到找到为止。
    
    view方法最终会返回一个self.dispatch方法的执行结果
    很显然对象本身以及产生对象的MyLogin类中都没有dispatch方法,只有MyLogin继承的父类View中有
    
    执行父类View下的dispatch方法,会先判断浏览器的请求是否合法。
    如果合法,就会通过getattr反射到MyLogin中对应的方法,
    handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    getattr(自定义类生成的对象self, 浏览器请求方式的小写, 如果请求不合法就执行第三个参数)
    假设请求为get,handler = MyLogin下的get方法
    假设请求为post,handler = MyLogin下的post方法
    return handler(request, *args, **kwargs)
    handler加括号,自动调用对应的方法执行,也就是实现了与FBV相同的展示效果
    '''
    # 结合源码,细品
    class View(object):
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        
        @classonlymethod
        def as_view(cls, **initkwargs):
            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)
            return view
        
        def dispatch(self, request, *args, **kwargs):
            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)
        
        def http_method_not_allowed(self, request, *args, **kwargs):
            logger.warning(
                'Method Not Allowed (%s): %s', request.method, request.path,
                extra={'status_code': 405, 'request': request}
            )
            return http.HttpResponseNotAllowed(self._allowed_methods())

    多对多三种创建方式

    # 全自动:利用orm自动帮我们创建第三张关系表
        class Book(models.Model):
        name = models.CharField(max_length=32)
        authors = models.ManyToManyField(to='Author')
        class Author(models.Model):
        name = models.CharField(max_length=32)
        """
        优点:代码不需要你写 非常的方便 还支持orm提供操作第三张关系表的方法...
        不足之处:第三张关系表的扩展性极差
        """
    
    # 纯手动
        class Book(models.Model):
        name = models.CharField(max_length=32)
        
        class Author(models.Model):
        name = models.CharField(max_length=32)
      
      class Book2Author(models.Model):
        book_id = models.ForeignKey(to='Book')
        author_id = models.ForeignKey(to='Author')
      '''
      优点:第三张表可以进行额外的扩展
      不足之处:需要写的代码较多,不能够再使用orm提供的简单的方法
      '''
    
    # 半自动
    class Book(models.Model):
        name = models.CharField(max_length=32)
        authors = models.ManyToManyField(to='Author',
                                         through='Book2Author',
                                         through_fields=('book','author')
                                         )
    class Author(models.Model):
        name = models.CharField(max_length=32)
        # books = models.ManyToManyField(to='Book',
        #                                  through='Book2Author',
        #                                  through_fields=('author','book')
        #                                  )
    class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Author')
    
    """
    through_fields字段先后顺序
        判断的本质: 通过第三张表查询对应的表 需要用到哪个字段就把哪个字段放前面
        
            
      半自动:可以使用orm的正反向查询 但是没法使用add,set,remove,clear这四个方法
    """

     

     
  • 相关阅读:
    void die(const char *msg)
    [C] Re-execute itself from elf file.
    在cnblog中使用syntax方法
    CVE-2016-0822-MTK-drivers/misc/mediatek/connectivity/common/combo/linux/wmt_dev.c#1158
    CVE-2016-2502-drivers/usb/gadget/f_serial.c in the Qualcomm USB driver in Android. Buffer Overflow Vulnerability reported by #plzdonthackme, Soctt.
    Insertion Sort
    [Java] 歐付寶金流串接教學
    [面試題]C符號的優先順序
    [LeetCode]Search a 2D Matrix
    [leetcode] Search a 2D Matrix II
  • 原文地址:https://www.cnblogs.com/zhenghuiwen/p/13027650.html
Copyright © 2011-2022 走看看