请稍候,加载中....

No.14 通用视图

通用视图

什么是通用视图

如果我们稍微留心一下我们写的代码,就会发现我们写的app无非是实现这么几个功能,列表页,详情页

列表页从模型的数据库对象里获取一组数据,然后通过模版渲染出来

详情页根据数据的PK_ID值,从数据库读取一条记录及关联数据,然后通过模版渲染出来

Django对于这些常见的页面逻辑,提供了实现好的视图类,只要经过继承,就可以直接使用,可以精简很多重复的代码

创建第二个APP

为了方便对比学习,我们创建第二个app应用,把第二个app命名为"newpolls"

创建过程参照第一个app:

1. python manage.py startapp newpolls

   并将newpolls添加到INSTALL_APP

2. 创建模型  - 模型从polls中复制

3. 生成数据表

4. 编写视图  - 将使用通用视图类来创建,模版从polls中复制到newpolls/templates/newpolls

5. 编写urls

接下来开始通过通用视图类来实现与polls相同的功能

ListView视图类

ListView类帮助我们来实现列表类的视图

导入ListView类

from django.views.generic import ListView

创建IndexView类

from django.views.generic import ListView
from .models import Question, Choice

class IndexView(ListView):
    template_name = "newpolls/index.html"
    context_object_name = "question_list"

    def get_queryset(self):
        return Question.objects.all()

template_name - 视图使用的模版路径

context_object_name - 模版引用变量名

get_queryset - 重写父类方法,加载数据

添加urls规则

修改newpolls/urls.py

这里需要注意,由于使用的是视图类,在url规则需要使用as_view()方法

app_name = "newpolls"
urlpatterns = [
    path("", views.IndexView.as_view(), name="index"),
]

修改myproject/urls.py

urlpatterns = [
    path("polls/", include("polls.urls")),
    path('admin/', admin.site.urls),
    # 新增
    path("newpolls/", include("newpolls.urls")),
]

到这里,我们就可以访问newpolls的列表页面了,可以看到代码精简不少

接下来我们创建详情页视图

DetailView视图类

DetailView视图接受一个pk_id, 然后查询数据,渲染模版

导入DetailView类

from django.views.gerneric import DetailView as DjangoDetail

这里导入DetailView类,我们使用了一个别名:DjangoDetailView,避免与后面自己创建的DetailView类重名

创建DetailView类

class DetailView(DjangoDetail):
    model = Question
    template_name = "newpolls/detail.html"

在DetailView类中,会根据pk_id,从model指定的数据表中查找数据,数据变量名自动命名为“question”,也就是模型的小写名

现在还需要为DetailView类添加一条url规则

添加url规则

DetailView类需要根据pk_id查询数据,因此URL规则如下

path('<int:pk>/', views.DetailView.as_view(), name='detail')

这里别忘了将"index.html"中的详情页链接修改为当前的链接

<a href="{%  url 'newpolls:detail' question.id %}">{{ question.question_text }}</a>

创建result视图

result视图与详情页视图都是一样的,从数据表中根据pk_id查询一条数据,不同的是模版

创建ResultView类

class ResultView(DjangoDetail):
    model = Question
    template_name = "newpolls/result.html"

创建url规则

path('result/<int:pk>', views.ResultView.as_view(), name='result')

Django还提供了其他的内置视图类,比如CreateView, UpdateView, DeleteView....我们会在后面的课程讲解到

 


Python学习手册-