zoukankan      html  css  js  c++  java
  • VIEW 视图

     FBV    CBV

     Django中请求处理方式有两种: FBV和CBV

    FBV: function base views    在试图里使用函数处理请求

    # url对应关系:url(r'^add_publisher/', views.add_publisher),
    from django.views import View
    
    def add_publisher(request):
        '''新增出版社数据'''
        if request.method == 'POST':
            # 获取提交的数据(括号内为input的name属性值),没有默认空字符串
            new_name = request.POST.get('new_name','').strip()
            # 设定输入不能为空
            if not new_name:
                return render(request,'add_publisher.html',{'err_msg':'输入不能为空','name':new_name})
            # 设定不能与数据库现有数据重复
            obj_list =  models.Publisher.objects.filter(name=new_name)    # 在数据库中查询数据是否存在
            if obj_list:        # 数据重复
                return render(request, 'add_publisher.html', {'err_msg': '出版社名称已存在', 'name': new_name})
            # orm往数据库中写入数据
            if new_name and not obj_list:
                models.Publisher.objects.create(name=new_name)
                return redirect('/publisher_list/')
        # 如果不是post请求,还是返回本页面
        return render(request,'add_publisher.html')
    示例

    CBV : class base views    在试图里使用类处理请求

    # url对应关系:url(r'^add_publisher/', views.add_publisher.as_view()),
    from django.views import View
    
    class add_publisher(View):
        def get(self,request):
            '''get请求'''
            return render(request, 'add_publisher.html')
        def post(self,request):
            # 获取提交的数据(括号内为input的name属性值),没有默认空字符串
            new_name = request.POST.get('new_name', '').strip()
            # 设定输入不能为空
            if not new_name:
                return render(request, 'add_publisher.html', {'err_msg': '输入不能为空', 'name': new_name})
            # 设定不能与数据库现有数据重复
            obj_list = models.Publisher.objects.filter(name=new_name)  # 在数据库中查询数据是否存在
            if obj_list:  # 数据重复
                return render(request, 'add_publisher.html', {'err_msg': '出版社名称已存在', 'name': new_name})
            # orm往数据库中写入数据
            if new_name and not obj_list:
                models.Publisher.objects.create(name=new_name)
                return redirect('/publisher_list/')
    示例

     as_view()流程

    1.程序启动的时候,执行as_view() 定义view函数并返回return self.dispatch(request, *args, **kwargs)

      url(r'^add_publisher/', views.add_publisher.as_view()) 此时就相当于url(r'^add_publisher/', view)

    2.接收到请求的时候,执行view函数

      1.实例化当前的类 将对象传给self

      2.self.request = request

      3.指定返回的self.dispatch方法:

        1.判断请求方式是否允许

          允许 ---- 通过反射拿到对应请求方式的方法 赋值给handler

          不允许 ---- 执行self.http_method_not_allowed 赋值给handler

        2.执行handler 得到HttpResponse对象 返回

     给视图加装饰器

    FBV本身就是函数,和普通的函数加装饰器的方法一样,没有区别

    给CBV加装饰器

    from django.utils.decorators import method_decorator
    
    #装饰器
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            ret = func(*args,**kwargs)
            print('时间:{}'.format(time.time() - start))
            return ret
        return inner
    
    
    # 1.加在方法上
    
    @method_decorator(timer)
    def get(self,request):
        '''get请求'''
        return render(request, 'add_publisher.html')
    
    
    # 2.加在dispatch方法上
    @method_decorator(timer)
    def dispatch(self, request, *args, **kwargs):     # 将源码中的dispatch方法重新定义,相当于给所有方法加上装饰器
        ret = super().dispatch(request, *args, **kwargs)
        return ret
        
        
    # 3.加在类上
    @method_decorator(timer,name='post')
    @method_decorator(timer,name='get')       # 在name中指定要加装饰器的方法
    class AddPublisher(View):
        def dispatch(self, request, *args, **kwargs):
            pass
        def get(self,request):
            pass
        def post(self,request):
            pass
        
    
    @method_decorator(timer,name='dispatch')        # 或者直接指定dispatch方法,效果同方法2一样,给所有方法加上装饰器
        def dispatch(self, request, *args, **kwargs):
            pass
        def get(self,request):
            pass
        def post(self,request):
            pass
    给CBV加装饰器

    method_decorator使不使用对于代码的运行效果来说,没有什么不同

    但是从参数角度来讲:

    不使用method_decorator,打印args的结果:

      (<app01.views.AddPublisher object at 0x03B465B0>, <WSGIRequest: GET '/add_publisher/'>)

    使用method_decorator,打印args的结果:

      (<WSGIRequest: GET '/add_publisher/'>,)

    request

    当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象

    Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象

    #  属性
    request.method        # 请求方法
    request.GET           # URL上携带的参数
    request.POST          # POST请求提交的数据
    request.FILES         # 上传的文件
    request.path_info     # 路径   不包含IP 端口 参数
    request.body          # 请求体   请求数据 字节  get没有请求体
    request.META          # 请求头的信息  全部大写 HTTP_开头
    request.COOKIES    
    request.session
    
    #  方法
    request.get_full_path()    # 路径  不包含IP和端口 包含参数
    request.is_ajax()          # 是否是ajax请求,布尔值
    request.get_host()         # 获取主机的IP和端口

    上传文件

    1.from表单中规定编码方式 enctype="multipart/form-data"

    2.使用request.FILES方法获取文件

    3.写入文件: 文件名.chunks 将文件分块 循环写入

    from django.shortcuts import render
    
    def upload(request):
        if request.method == 'POST':
            file = request.FILES.get('file')        # request.FILES获取到字典,通过键取值
            with open(file.name,'wb') as f:         # file.name拿到文件名
                for chunk in file.chunks():
                    f.write(chunk)
        return render(request,'upload.html')
    # 文件会自动保存到与manage.py同一个路径下
    函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
    
        文件 <input type="file"  name="s19">
        <button>上传</button>
    </form>
    </body>
    </html>
    模板

    response

    HttpResponse('字符串') 返回字符串

    render(request,'模板的文件名',{k1:v1}) 返回一个完整的HTML页面

    redirect(要跳转的地址) 重定向 Location :地址

    每个视图都需要实例化,填充和返回一个HttpResponse,render和redirect源码中都包含HttpResponse

    JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应

    默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数

    from django.http.response import JsonResponse
    def json_data(request):
        data = {'name':'alex','age':18}
        # lst = [1,2,3,4,5]
        return JsonResponse(data)
        # return JsonResponse(lst,safe=False)          # 传输非字典类型
    示例
  • 相关阅读:
    eclipse luna maven失效的原因
    利用线性探测法解决hash冲突
    PHP和JavaScript将字符串转换为数字string2int
    JavaScript 编程易错点整理
    使用phpstudy创建本地虚拟主机
    单例模式
    PHP使用cookie时遇到的坑
    Redis安装与配置
    CI框架2.x的验证码中所遇问题解决
    用delete和trancate删除表记录的区别
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10677753.html
Copyright © 2011-2022 走看看