zoukankan      html  css  js  c++  java
  • 062.Python前段框架Django视图CBV


    一 CBV与FBV

    • CBV:Class Based View
    • FBV:Function Based View
    • 之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的,那就是CBV。

    1.1 创建项目

    root@darren-virtual-machine:~/PycharmProjects# django-admin startproject cbv_test

    root@darren-virtual-machine:~/PycharmProjects# cd cbv_test/

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# python3 manage.py startapp app01

    setting注册app

    复制代码
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
    ]
    复制代码

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# mkdir templates

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# vim cbv_test/settings.py

    复制代码
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR,"templates")],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    复制代码

    路由分发

    复制代码
    from django.contrib import admin
    from django.urls import path,include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('app01/',include(app01.urls)),
    ]
    复制代码

    配置一个登录页面

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>用户登录</h3>
    <form action="" method="POST">
        {% csrf_token %}
        <p>用户名:<input type="text" name="username"></p>
        <p>密 码:<input type="password" name="password"></p>
        <input type="submit">
    </form>
    
    </body>
    </html>
    复制代码

    url文件

    复制代码
    from django.urls import  path,re_path
    from app01 import views
    
    urlpatterns = [
        path('login/',views.login),
    ]
    复制代码

    views视图文件

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    
    # Create your views here.
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    复制代码

    访问

    1.2 使用CBV改写

    urls文件

    复制代码
    from django.urls import  path,re_path
    from app01 import views
    
    urlpatterns = [
        path('login_fbv/',views.login),
        path('login_cbv/', views.Login.as_view()),
    ]
    复制代码

    views文件

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    from django.views import  View
    
    # Create your views here.
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    
    
    #CBV
    class Login(View):
        def get(self,request):
            return render(request, "login.html")
        def post(self,request):
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request, "login.html")
    复制代码

    访问http://127.0.0.1:8000/app01/login_cbv/登录

    FBV本身就是一个函数,所以和给普通的函数加装饰器无差

    1.3 使用装饰器装饰CBV

    给CBV加装饰器

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    from django.views import  View
    import  time
    
    # Create your views here.
    
    def timer(func):
        def inner(request,*args,**kwargs):
            start_time = time.time()
            time.sleep(2)
            rep = func(request,*args,**kwargs)
            end_time = time.time()
            print (end_time-start_time)
            return rep
        return inner
    
    #FBV
    @timer
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    复制代码

    1.4 使用装饰器装饰FBV

    类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

    1.4.1 给某个方法加上装饰器

    此例给get方法加上)

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    from django.views import  View
    import  time
    from django.utils.decorators import method_decorator
    # Create your views here.
    
    def timer(func):
        def inner(request,*args,**kwargs):
            start_time = time.time()
            time.sleep(2)
            rep = func(request,*args,**kwargs)
            end_time = time.time()
            print (end_time-start_time)
            return rep
        return inner
    
    #FBV
    @timer
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    
    
    #CBV
    class Login(View):
        @method_decorator(timer)
        def get(self,request):
            return render(request, "login.html")
        def post(self,request):
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request, "login.html")
    复制代码

    访问http://127.0.0.1:8000/app01/login_cbv/,只有get有,post并没有用到装饰器

    [10/Apr/2020 11:27:53] "GET /app01/login_cbv HTTP/1.1" 301 0
    2.024909496307373
    [10/Apr/2020 11:27:55] "GET /app01/login_cbv/ HTTP/1.1" 200 456
    [10/Apr/2020 11:28:05] "POST /app01/login_cbv/ HTTP/1.1" 200 16

    1.4.2 加在dispatch方法上面

    会给类下的所有方法加上此装饰器

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    from django.views import  View
    import  time
    from django.utils.decorators import method_decorator
    # Create your views here.
    
    def timer(func):
        def inner(request,*args,**kwargs):
            start_time = time.time()
            time.sleep(2)
            rep = func(request,*args,**kwargs)
            end_time = time.time()
            print (end_time-start_time)
            return rep
        return inner
    
    #FBV
    @timer
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    
    
    #CBV
    class Login(View):
        @method_decorator(timer)
        def dispatch(self, request, *args, **kwargs):
            obj = super().dispatch(request,*args,**kwargs)
            return obj     #这里必须返回,否则Httpresponse错误
        #@method_decorator(timer)
        def get(self,request):
            return render(request, "login.html")
        def post(self,request):
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request, "login.html")
    复制代码

    访问http://127.0.0.1:8000/app01/login_cbv

    [10/Apr/2020 11:35:08] "GET /app01/login_cbv/ HTTP/1.1" 200 456
    2.01680588722229
    2.00297474861145
    [10/Apr/2020 11:35:16] "POST /app01/login_cbv/ HTTP/1.1" 200 16

    1.4.3加在类上面

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    from django.views import  View
    import  time
    from django.utils.decorators import method_decorator
    # Create your views here.
    
    def timer(func):
        def inner(request,*args,**kwargs):
            start_time = time.time()
            time.sleep(2)
            rep = func(request,*args,**kwargs)
            end_time = time.time()
            print (end_time-start_time)
            return rep
        return inner
    
    #FBV
    @timer
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    
    
    #CBV
    @method_decorator(timer,name="get")
    #如果需要给post方法家装饰器,method_decorator(timer,nmae="post"),必须制定name的值,否则报错

    class Login(View): #@method_decorator(timer) def dispatch(self, request, *args, **kwargs): obj = super().dispatch(request,*args,**kwargs) return obj #这里必须返回,否则Httpresponse错误 #@method_decorator(timer) def get(self,request): return render(request, "login.html") def post(self,request): username = request.POST.get("username") password = request.POST.get("password") if username == "joy" and password == "123456": return HttpResponse("login success...") else: return render(request, "login.html")
    复制代码

    访问http://127.0.0.1:8000/app01/login_cbv/

    2.017592191696167
    [10/Apr/2020 11:39:04] "GET /app01/login_cbv/ HTTP/1.1" 200 456
    [10/Apr/2020 11:39:10] "POST /app01/login_cbv/ HTTP/1.1" 200 16

    在给类加装饰器的时候,也可以使用name=dispatch,也可以,关键是必须有这个类存在

    学习记录,小白一枚
  • 相关阅读:
    python-观察者模式
    python-迭代器模式
    python-策略模式
    python-组合模式
    python-享元模式
    python-代理模式
    虚基类与虚继承
    指针与地址的关系
    大数相加和大数相乘以及打印从1到最大的n位数
    各种排序实现以及稳定性分析
  • 原文地址:https://www.cnblogs.com/wangsirde0428/p/14322935.html
Copyright © 2011-2022 走看看