zoukankan      html  css  js  c++  java
  • 第四篇:Django的视图层

    视图层的方法

    HttpResponse

    返回的是字符串

    def index(request):
        return HttpResponse('你好啊小妹妹')
    

    render

    返回html页面 并且可以给html页面传数据

    def login(request):
        return render(request, 'login.html', {'user_dic': {'username': 'json', 'password': 123}, 'mes': 'hello'})
     
    # 返回html页面,并可以给html传入字典
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {#取字典中的值#}
    {{ user_dic.username }}
    </body>
    </html>
     
    

    render原理

    from django.template import Template, Context
    def ab_render(request):
        temp = Template('<h3>{{user_dict}}<br>{{user_dict.name}}<br> {{user_dict.password}}</h3>')
        context = Context({'user_dict': {'name': 'jason', 'password': 123}})
        res = temp.render(context)
        return HttpResponse(res)
    

    redirect

    重定向

    def home(request):
        return redirect('https://www.baidu.com')
    

    JsonResponse

    import json from django.http import JsonResponse
    def xxx(request):
        user_dict = {'username':'jason好帅哦 我好喜欢!','password':'123'}
        # json_str = json.dumps(user_dict,ensure_ascii=False)
        # return HttpResponse(json_str)
        l = [1,2,3,4,5,6,7,8,9,]
        # return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
        return JsonResponse(l,safe=False)  # 序列化非字典格式数据 需要将safe改为False
     
    from django.http import JsonResponse
    def xxx(request):
        user_dict = {'username':'jason好帅哦 我好喜欢!','password':'123'}
        # json_str = json.dumps(user_dict,ensure_ascii=False)
        # return HttpResponse(json_str)
        l = [1,2,3,4,5,6,7,8,9,]
        # return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
        return JsonResponse(l,safe=False)  # 序列化非字典格式数据 需要将safe改为False
    

    前后端数据交互

    form表单上传文件

    action   什么都不写,默认朝当前页面提交数据
     
    method   post  什么都不写默认为get请求,不会提交数据,需要改为post
     
    enctype  formdata  更改为上传文件
    

    示例:
    home.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">    </script>
        <link href="https://cdn.bootcss.com/twitterbootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitterbootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="myfile">
        <input type="submit">
    </form>
     
    </body>
    </html>
    

    views.py

    def home(request):
        if request.method == 'POST':
            # 获取用户上传的文件数据
            print(request.FILES)
            file_obj = request.FILES.get('myfile')  # 文件句柄
            print(file_obj.name)  # 获取文件名
     
            # 下面的for循环可以写成django推荐的写法
            # for chunk in file_obj.chunks():
            #       print(chunk)
            with open(file_obj.name,'wb') as f:
                for line in file_obj:
                    f.write(line)
     
       return render(request,'home.html')
    

    视图函数的FBV和CBV

    FBV:基于函数的视图

    CBV:基于类的视图

    CBV基本写法:

    # views.py
    from django.views import View
     
     
    class MyLogin(View):
        def get(self, request):
            return render(request, 'login.html')
     
        def post(self, request):
            return HttpResponse('我是类里面的POST方法')
     
     
    # urls.py
    url(r'login/', views.MyLogin.as_view())
    

    朝login提交get请求会自动执行MyLogin里面的get方法

    而提交post请求也会自动执行MyLogin里面的post方法

    为什么MyLogin针对不同的请求方法能够自动执行对应的方法?

    研究源码的突破口

    url(r'^login/', views.MyLogin.as_view())
    

    as_view要么是类里面定义的普通函数 @staticmethod
    要么是类里面定义的绑定给类的方法 @classmethod
    点进去查看:

    我们发现,最后返回的是一个view,因此我们外面的url相当于下面:

    url(r'^login/', views.MyLogin.view)
    

    再去看view函数:

    url(r'^login/', views.MyLogin.dispatch)
    

    回到自己创建的MyLogin的类中,查看继承了View这个类,点进去,找到dispatch这个方法:

    继续往下看:

    因此,此时的url相当于:

    url(r'^login/', views.MyLogin.get)
    

    看源码不需要每一句都看懂,只看自己能够看得懂的

    CBV源码(******)
        MyClass.as_view()
        # 函数名加括号执行优先级最高
        @classonlymethod
        def as_view(...):
            def view(...):
                ...
            return view
        # 变形
        url(r'^index/',views.view)  # CBV与FBV在路由匹配上本质是一样的
        
        def view(...):
            self = cls(...)  # 生成的是我们自己写的类的对象
            ...
            return self.dispatch(...)
            """
            当你看到self.属性或方法的时候 不要想当然 
            一定要遵循对象的属性和方法的查询顺序
            对象本身  产生对象的类  类的父类
            """
        def dispatch(...):
            # 先判断当前请求方式是否在默认的八个合法请求方式内
            if request.method.lower() in ['get','post','delete','options'...]
                # 利用反射获取对象中对应的属性
                handler = getattr(self,request.method.lower(),报错信息)
            
            return handler(...)  # 执行获取到的方法
    

    Django Settings源码

    首先我们先获得django的内部的配置文件:

    from django.conf import global_settings, settings
    

    global_settings文件中有很多配置信息
    django暴露给用户一个可以自定义的配置 但是内部也有默认的配置
    用户配置了就用用户的 用户没有配就用默认的
    点settings进去看:

    全局大字典初始为空,因此相当于:

    os.environ.get(ENVIRONMENT_VARIABLE)
    

    点进去ENVIRONMENT_VARIABLE:

    此时:

    {}.get("DJANGO_SETTINGS_MODULE")
    

    因此,我们需要找到谁给大字典里设置了DJANGO_SETTINGS_MODULE的键值对,我们点开 manage.py中查看:

    因此:

    再往下看:

    调用Settings类,传入mysite,产生对象,因此点进Sttings中:

    from django.conf import global_settings,settings
    
    settings = LazySettings()
    
    
    class LazySettings(...):
        def _setup(...):
            # 获取暴露给用户的配置文件字符串路径
            setting_module = os.environ.get(纯大写变量名)
            """
            manage.py
            os.environ.setdefault(纯大写变量名,'暴露给用户的配置文件字符串路径')
            """
            
            Settings(setting_module)
    def Settings(...)
        # 先遍历全局默认的配置文件       给对象设置键值对
        for setting in dir(global_settings):
            if setting.isupper():
                setattr(self,setting,getattr(global_settings,setting))
                
        
        # 再遍历暴露给用户的配置文件     给对象设置键值对
        md = importlib.import_module(setting_module)
        for setting in dir(md):
            if setting.isupper():
                setattr(self,setting,getattr(md,setting))
        """
        利用的其实就是字典的键存在和不存在 下面语句的作用
        dict[key] = value
        """
    
  • 相关阅读:
    项目冲刺——第三篇
    项目冲刺——第五篇
    项目冲刺——第四篇
    团队作业第3周——需求改进&系统设计
    复审与事后分析
    事后诸葛亮分析报告
    团队作业第5周——测试与发布(Alpha版本)
    第四周进销存管理系统冲刺博客汇总
    第三篇 进销存管理系统冲刺博客
    团队作业第3周——需求改进&系统设计
  • 原文地址:https://www.cnblogs.com/cnhyk/p/12173521.html
Copyright © 2011-2022 走看看