美文网首页
基于"类"的视图(1)---View

基于"类"的视图(1)---View

作者: 费云帆 | 来源:发表于2020-01-17 15:04 被阅读0次

    在写视图的时候,Django除了使用'函数'作为视图,也可以使用'类'作为视图。
    使用类视图可以使用类的一些特性,比如继承等

    ● django.views.generic.base.View是主要的类视图,所有的类视图都是继承自他。如果我们写自己的类视图,也可以继承自他。然后再根据当前请求的method,来实现不同的方法

    View支持以下方法['get','post','put','patch','delete','head','options','trace']

    示例 1:

    基本用法

    # app.views
    from django.views.generic import View # 自定义的'视图类'必须继承View类
    
    class FirstView(View):
        # 注意get()接收的参数
        # 这里其实可以这么写 def get(self,request) # 也就是说,后面的*args 和 kwargs可以忽略不写
        def get(self,request,*args,**kwargs): # 只允许get()请求
            return HttpResponse('A ClassView Test.')
    
    # urls
        ......
        # 调用as_view()方法---注意这里传入的是'定值',不再是函数对象---as_views
        path('firstview/', views.FirstView.as_view(),name='firstview'),
    
        '''由于只定义了get()方法,那么这个类就只允许get请求,使用'postman'用'post'方法访问url,
        是不被允许的---405Method Not Allowed'''
    
    示例 2:

    如果是'get'请求,那么就加载表单;如果是'post'请求,就把表单传过来的数据,打印在'终端控制台'

    # views
    class AddBookView(View):
    
        def get(self,request,*args,**kwargs): # 如果是get,就加载前端模板
            return render(request,'add_book.html')
    
        def post(self,request,*args,**kwargs): # 如果是post,首先获取前端提交的数据,然后打印在'终端'
            bname=request.POST.get('bname') # 服务端,既可以传数据给前端(例如context),也可以获取前端提交的数据
            bauthor=request.POST.get('bauthor')
            print("书名:{}---作者:{}".format(bname,bauthor))
            return HttpResponse('Add Book Successful!')
    
    # urls
    
        path('add_book_view/', views.AddBookView.as_view(),name='add_book_view') 
        .....
    
    # add_book.html
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Add Book</title>
    </head>
    <body>
        <form action="" method="post">
            <table>
                <tbody>
                    <tr>
                        <td>书名</td>
                        <td><input type="text" name="bname"></td>
                    </tr>
                    <tr>
                        <td>作者</td>
                        <td><input type="text" name="bauthor"></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td><input type="submit" value="submit"></td>
                    </tr>
                </tbody>
            </table>
        </form>
    </body>
    </html>
    
    示例 3:
    • 接收url传参
    # views
    class GetBookIdView(View):
        def get(self,request,book_id): # 接收url传过来的参数'book_id'
            message='你输的图书id是:{}'.format(book_id)
            return HttpResponse(message)
    
    # urls
    urlpatterns = [
        ......
        path('book_id/<book_id>', views.GetBookIdView.as_view()),
    ]
    
    • 返回更'友好'的'请求方法限制提示'
    class GetBookIdView(View):
    
        def get(self,request,book_id):
            message='你输的图书id是:{}'.format(book_id)
            return HttpResponse(message)
    
        def http_method_not_allowed(self, request, *args, **kwargs):
            return HttpResponse('不支持GET以外的其他请求(例如POST!)')
         '''
         若没有定义'http_method_not_allowed()',使用post方法访问url,postman
         只会给一个'Method not allowed'提示,而定义了这个方法以后,就提示HTTPResponse的内容
         显然更加'友好'
         '''
    
    示例4

    dispatch()方法介绍:
    不管是get请求还是post请求,都会走dispatch(request,args,*kwargs)方法
    所以如果实现这个方法,调用get/post方法之前,都会优先调用这个方法,了解以后,看到dispatch()方法,不会慌...

    # views
    class DispatchView(View):
        def dispatch(self, request, *args, **kwargs):
            print('优先执行dispatch()方法')
            super().dispatch(request,*args,**kwargs)
            print('再次调用dispatch()方法')
            return HttpResponse('dispatch()方法测试!')
        def get(self,request):
            print('get()方法')
            return HttpResponse('get请求')
    
        def post(self,request):
            print('post()方法')
            return HttpResponse('post请求')
    
    # urls
    from django.urls import path
    from front import views
    
    urlpatterns = [
        ......
        path('dispatch/', views.DispatchView.as_view()),
    ]
    
    '''
    <1>首先访问: http://127.0.0.1:8000/dispatch/
    终端输出:
    
    [17/Jan/2020 14:48:05] "GET /dispatch/ HTTP/1.1" 200 23
    优先执行dispatch()方法
    get()方法
    再次调用dispatch()方法
    
    <2>使用post访问: http://127.0.0.1:8000/dispatch/
    终端输出:
    
    [17/Jan/2020 14:48:23] "POST /dispatch/ HTTP/1.1" 200 23
    优先执行dispatch()方法
    post()方法
    再次调用dispatch()方法
    '''
    
    <3>无论是get/post,网页的内容都是'dispatch()方法测试!'
    所以,只要dispatch()返回了HttpResponse,那么,原来的get/post
    返回的HttpResponse会被覆盖!怎么解决这个问题?dispatch()可以这么
    写:
    
    class DispatchView(View):
        def dispatch(self, request, *args, **kwargs):
            print('优先执行dispatch()方法')
            # 使用result存储
            result=super().dispatch(request,*args,**kwargs)
            print('再次调用dispatch()方法')
            # 不再返回HttpResponse,我们返回result
            return result
        def get(self,request):
            ......
    再次刷新网页,get请求就返回---get请求;post请求就返回---post请求
    

    相关文章

      网友评论

          本文标题:基于"类"的视图(1)---View

          本文链接:https://www.haomeiwen.com/subject/srrczctx.html