2.3. 认识视图类

2.3.1. 1.什么是视图类

在视图里使用类处理方式,被称为类视图(CBV)

采用面向对象的思维,把每个方法处理逻辑变成视图类中的的单个方法,这样可以使程序逻辑变得更新简单、清晰。

2.3.2. 2.对比视图函数和视图类

2.1 视图函数

def index_page(request):
    if request.method == "GET":
        return HttpResponse("GET请求")
    if request.method == "POST":
        return HttpResponse("POST请求")

2.2 视图类

from django.views import View


class IndexPageView(View):
    """
    类视图
    """

    def get(self, request):
        return HttpResponse("GET请求")

    def post(self, request):
        return HttpResponse("POST请求")

其中视图类IndexPageView集成了django.views模块下的View类。

视图类的路由定义如下:

from django.urls import path
from app2 import views

urlpatterns = [
    path('app2/indexpage',views.IndexPageView.as_view())
]

视图类在调用时,只能是函数的方式,而不能是类的方式,需要将视图类as_view()转化为视图函数。

2.3.3. 3.利用视图类进行功能设计

Django提供了众多视图类,可以通过视图类简化开发过程。

3.1 通用视图类-TemplateView

TemplateView是一个视图类,用来渲染指定的模板。

app2/views_class.py

from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView, ListView, DetailView
from .models import *


class TestTemplateView(TemplateView):
    # 设置模板文件
    template_name = "2/test_templateview.html"

    # 重写父类get_context_data()方法
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 增加模板变量info
        context["info"] = "该变量可以传递到模板"
        return context

通过from django.views.generic import TemplateView导入TemplateView类。

通过继承TestTemplateView类的方式创建一个TestTemplateView类,在TestTemplateView类中设置模板文件。

app2/urls.py

路由配置如下:

from django.urls import path
from app2 import views
from app2.views_class import TestTemplateView

urlpatterns = [
    path('app2/test_templateview/', TestTemplateView.as_view()),
]

请注意路由中as_view()方法的用法。

3.2 列表视图类-ListView

ListView视图类用于将数据表的数据以列表的形式显示。

app2/views_class.py增加视图类TestListView。

from django.views.generic import TemplateView, ListView, DetailView
from .models import *

class TestListView(ListView):
    model = UserBaseInfo
    template_name = "2/test_listview.html"
    # 设置模板变量
    context_object_name = "users"
    # 每页显示的条数
    paginate_by = 1

    # 返回状态为1的数据
    # queryset=UserBaseInfo.objects.filter(status=1)
    # 重新父类的get_queryset()
    def get_queryset(self):
        # 返回所有数据
        userinfo = UserBaseInfo.objects.all()
        return userinfo

    # 重写父类get_context_data()方法
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 增加模板变量info
        context["info"] = "ListView变量可以传递到模板"
        print(context)
        return context

templates/2/test_listview.html

<div>
    接收变量
    <br>
   {{info}}
   <table border=1>
   {% for user in users %}
   <tr>
       <td>{{ user.username }}</td>
       <td>{{ user.status }}</td>
       <td>{{ user.createdate }}</td>
   </tr>
   {% endfor%}
    </table>

    <table>
        <tr>
        {% if page_obj.has_previous %}
            <td>
            <a href="?page={{ page_obj.previous_page_number }}">
                上一页
            </a>
            </td>
        {% endif %}
        {% if page_obj.has_next %}
        <td>
            <a href="?page={{ page_obj.next_page_number }}">
                下一页
            </a>
        </td>
        {% endif %}
    </tr>
    </table>
</div>

编写路由

app2/urls.py

from django.urls import path
from app2 import views
from app2.views_class import TestListView

urlpatterns = [
    path('app2/test_listview/', TestListView.as_view()),
]

访问:http://127.0.0.1:8000/app2/test_listview/

通过控制台查看context变量

{'paginator': <django.core.paginator.Paginator object at 0x00000195F8EC2910>, 'page_obj': <Page 1 of 2>, 'is_paginated': True, 'object_list': <QuerySet [<UserBaseInfo: 1>]>, 'users': <QuerySet [<UserBaseInfo: 1>]>, 'view': <app2.views_class.TestListView object at 0x00000195F8EC22B0>, 'info': 'ListView变量可以传递到模板'}
[30/Apr/2022 17:02:46] "GET /app2/test_listview/?page=1 HTTP/1.1" 200 376

3.3 详细视图类-DetailView

DetailView视图类用于将数据表的数据以详细视图的形式显示。

app2/views_class.py

class TestDetailView(DetailView):
    model = UserBaseInfo
    template_name = "2/test_detailview.html"
    # 设置模板变量
    context_object_name = "users"
    pk_url_kwarg = 'userid'

templates/2/test_detailview.html

<div>
    <br>
   {{info}}
   <table border="1">
    <tr>
        <td>姓名:</td>
        <td>{{ users.username }}</td>
    </tr>
    <tr>
        <td>注册时间:</td>
        <td>{{ users.createdate }}</td>
    </tr>
</table>
</div>

编写路由规则

app2/urls.py

from django.urls import path
from app2 import views
from app2.views_class import TestTemplateView, TestListView, TestDetailView

urlpatterns = [
    path('app2/test_detailview/<int:userid>/', TestDetailView.as_view())
]

访问:http://127.0.0.1:8000/app2/test_detailview/1/