ListView

TemplateView

DetailView

之前的代码实例基本上都是基于FBV的模式来撰写的,好处么,当然就是简单粗暴。。正如:

def index(request):return HttpResponse('hello world')

上面的写法,基本接触不到视图函数里面的通用视图。只是在介绍CBV的时候稍微介绍了下引用,大概用法。

导入

之前的导入一直用的是

from django.views import View

这里从view下钻一下会发现:

from django.views.generic.base import View__all__ = ['View']

对头、view视图函数基本都来自于generic里面,此篇blog具体讲述的内容也是generic内部的几个通用视图:ListView、DetailView、TemplateView。

View

基础类视图:

from django.http import HttpResponse
from django.views import Viewclass MyView(View):def get(self, request):return HttpResponse('ok')

urlpatterns = [path('index/',views.MyView.as_view(), name='index'),
]

as_view()方法会返回一个函数来处理请求和响应,还可以将类视图中定义的属性作为该方法参数,覆盖类视图中的属性值。

基本视图

基本视图包括三类:View、TemplateView和RedirectView。用户可继承基本类视图来定义视图,所有的通用视图也都继承与这三类基本视图实现,因此相比于通用视图,基本视图提供的功能较少。

View

View是所有类视图的父类,可以直接从from django.views中导入,如:

from django.views import Viewclass MyView(View):def get(self,request):pass

http请求的方法

http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

as_view():该方法是一个类方法,被@classonlymethod修饰,是http请求和响应的入口,用于url配置。在Http请求和响应的过程中,会将request对象和其他参数作为参数传入该方法,内部调用dispatch()方法后返回一个Response对象。

TemplateView

继承结构:

class TemplateView(TemplateResponseMixin, ContextMixin, View):

TemplateView视图通过给定的模板进行渲染。

实例

class StudentDetailTemplate(TemplateView):  # 继承TemplateViewtemplate_name = 'student_template.html'  # 模版名称def get_context_data(self, **kwargs):context = super().get_context_data(**kwargs)  # 继承父类里面的get_context_data,返回上下文数据context['name'] = 'dandy'  # 添加新的数据context['data'] = {'age': 18,  # 添加新的字典'flag': 'aaa'}context['data1'] = models.Student.objects.all()  # 添加新的querysetreturn context  # 返回更新过的上下文文数据

url:

    path('templateview/', views.StudentDetailTemplate.as_view(), name='student_template'),

其他为涉及到的属性或方法:

get_template_names()

除了使用template_name指定模板文件,也可通过该方法指定模板文件:

def get_template_names(self):return "student_template.html"

extra_content

除了在get_context_data()中添加上下文信息外,也可以在url配置时在as_view()方法中指定extra_context属性来添加上下文信息,如:

    path('templateview/', views.StudentDetailTemplate.as_view(extra_context={"extra": "。。。。"}), name='student_template'),

CBV正常是需要在下面定义一个get或之类的方法,用来匹配method,但是此处是不需要的,因为查看TemplateView内部时会发现:

class TemplateView(TemplateResponseMixin, ContextMixin, View):"""Render a template. Pass keyword arguments from the URLconf to the context."""def get(self, request, *args, **kwargs):context = self.get_context_data(**kwargs)return self.render_to_response(context)

内部已经写好了这个get方法,一方面TemplateView的基础需求其实就是返回模版给浏览器的。当然了,因为继承了TemplateView,这里还是可以重写这个get方法,进行自定义数据。

    def get(self, request, *args, **kwargs):context = self.get_context_data(**kwargs)context['end'] = 'ending'new_data ={'a': 'b'}context.update(new_data)return self.render_to_response(context)

RedirectView

用来进行跳转, 默认是永久重定向(301),可以直接在urls.py中使用,非常方便:

    path('', views.IndexPage.as_view(), name='baidu'),

class ArticleCounterRedirectView(RedirectView):url = ' # 要跳转的网址,# url 可以不给,用 pattern_name 和 get_redirect_url() 函数 来解析到要跳转的网址
     permanent = False #是否为永久重定向, 默认为 Falsequery_string = True # 是否传递GET的参数到跳转网址,True时会传递,默认为 Falsepattern_name = 'article-detail' # 用来跳转的 URL, 看下面的 get_redirect_url() 函数# 如果url没有设定,此函数就会尝试用pattern_name和从网址中捕捉的参数来获取对应网址# 即 reverse(pattern_name, args) 得到相应的网址,def get_redirect_url(self, *args, **kwargs):article = get_object_or_404(Article, pk=kwargs['pk'])article.update_counter() # 更新文章点击数,在models.py中实现return super(ArticleCounterRedirectView, self).get_redirect_url(*args, **kwargs)

RedirectView源码:

class RedirectView(View):"""Provide a redirect on any GET request."""permanent = Falseurl = Nonepattern_name = Nonequery_string = Falsedef get_redirect_url(self, *args, **kwargs):"""Return the URL redirect to. Keyword arguments from the URL patternmatch generating the redirect request are provided as kwargs to thismethod."""if self.url:url = self.url % kwargselif self.pattern_name:url = reverse(self.pattern_name, args=args, kwargs=kwargs)else:return Noneargs = self.request.META.get('QUERY_STRING', '')if args and self.query_string:url = "%s?%s" % (url, args)return urldef get(self, request, *args, **kwargs):url = self.get_redirect_url(*args, **kwargs)if url:if self.permanent:return HttpResponsePermanentRedirect(url)else:return HttpResponseRedirect(url)else:logger.warning('Gone: %s', request.path,extra={'status_code': 410, 'request': request})return HttpResponseGone()def head(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def post(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def options(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def delete(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def put(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def patch(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)

View Code

看完应该就会一目了然。

    path('', RedirectView.as_view(pattern_name='backend:index')),

通用显示视图

ListView

继承关系:

ListView,用于显示一个对象列表的视图,包含一个属性值object_list,表示对象的列表。因此在模板文件中可以通过遍历该属性来显示model的所有数据。

class StudentList(ListView):model = models.Student  # orm的modeltemplate_name = 'student_list.html'  # 要返回的模版文件context_object_name = 'student_obj'  # orm数据实例化对象,前端调用的名称extra_context = {'name': 'dandy'}  # 额外的上下文数据信息def get(self, request, *args, **kwargs):  # 重写get方法response = super().get(request, *args, **kwargs)return responsedef get_context_data(self, *, object_list=None, **kwargs):  # 重写get_context_data方法context = super().get_context_data(**kwargs)  # 拿到返回值context并更新或者扩充context['num'] = 11return contextdef get_queryset(self):# query_set = super().get_queryset()# query_set = super().get_queryset()[:1]self.kwargs['name'] = 'dandy'cate = get_object_or_404(models.Student, name=self.kwargs.get('name'))return super().get_queryset().filter(name=cate)

上面有一个参数没有设计到:

queryset = Student.objects.filter(name='zhangsan')

该属性表示该视图显示项的集合,可以通过get_queryset()方法来进行定义。

所以上面的这一句筛选跟上面的get_queryset自定义的筛选,其实差不多。

context_object_name

在模板中使用object_list是一个不太友好的方法,因为不知道object_list具体指的是哪个模板的数据,因此在通用视图中还提供了一个属性:context_object_name来制定一个上下文,如:

class showStu(ListView):...context_object_name = "student"

看一下模版内:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h3>{{ name }}</h3><table><thead><td>姓名</td><td>年龄</td></thead><tbody>{% for student in student_obj %}<tr><td>{{ student.name }}</td><td>{{ student.age }}</td></tr>{% endfor %}</tbody></table><br><h2>{{ num }}</h2>
</body>
</html>

View Code

DetailView

继承关系:

DetailView用于显示一个特定类型对象的详细信息。DetailView的大部分属性和方法和ListView相同。不同的是该视图没有object_list属性,因为该视图负责显示一个特定对象的详细信息,因此有一个object属性,表示model的一个对象(或一条记录)。

class StudentDetailView(DetailView):model = models.Student  # orm的modeltemplate_name = 'student_detail.html'  # 调用的模版文件context_object_name = 'aaa'  # 模版文件里面对应的orm数据对象的名称def get(self, request, *args, **kwargs):response = super().get(request, *args, **kwargs)  # 同样的重写的方法可以做一些自定义,比如访问量+1等等的return responsedef get_object(self):obj = super().get_object()return obj  # 这里的obj其实已经是指向一条数据了;比如一篇文章,可以进行一些修改之类的操作,obj.aa = 'dandy', obj.save()def get_context_data(self, **kwargs):context = super().get_context_data(**kwargs)  # 重写,获取返回数据classes = self.object.classes_set.all()  # 反向获取所有关联数据context.update({  # 添加新的上下文信息'classes': classes,'test_name': 'dandy'})return context

这里需要注意的是url,因为明确表面了这个通用视图的目的,所以url固定的指向了某个具体的事物的id

    path('detailview/<int:pk>/', views.StudentDetailView.as_view(), name='student_detail'),

内部形成处理。

默认情况下,DetailView 使用<appname>/<model name>_detail.html的模板,如果没有该模板,则应该通过”template_name”指定一个模板。

转载于:https://www.cnblogs.com/wuzdandz/p/9448310.html

Python Django CBV下的通用视图函数相关推荐

  1. Django 基于类的通用视图详解

    原文出处:https://segmentfault.com/a/1190000005685454 Django 学习小组:基于类的通用视图详解(一) 通过三周的时间我们开发了一个简单的个人 Blog, ...

  2. python框架django教程_[Python] Django框架入门3——深入视图

    说明: 本文主要深入了解视图(views.py),涉及路由配置.定义视图.Request对象.Response对象.状态保持等. 一.路由配置 1.配置位置(settings.py 的 ROOT_UR ...

  3. python Django框架之URL与视图(3)

    文章目录 一.视图的介绍 1.视图是什么? 2.视图模板的配置 3.视图函数的使用 二. URL映射 1.URL路由分发 2.URL反向解析 3.URL正则路径 4.URL命名空间 一.视图的介绍 1 ...

  4. Django笔记7(通用视图)

    1. 一个呈现静态"关于"页面的URLconf from django.conf.urls.defaults import * from django.views.generic. ...

  5. Python Django框架下做电商项目

    这个项目是在Linux 环境下做的,需要安装的有 ubuntu.pycharm. pycharm如果没有激活的可以使用-----pycharm 最新激活码激活可用 流程 总体流程 https://bl ...

  6. django通用视图(CBV)

    1. 介绍 Django提供了很多通用的基于类的视图(Class Based View),来帮我们简化视图的编写.这些View与上述操作的对应关系如下: 展示对象列表(比如所有用户,所有文章)- Li ...

  7. Python的web框架Django(1):HTTP、简介、静态文件配置、路由系统、视图函数、模板语言、ORM、Ajax、分页器、forms、Cookie、Session、中间件、ModelForm

    1. HTTP协议 1)HTTP请求协议 请求格式 POST(方法) /form/entry(URI) HTTP/1.1(协议版本) HOST:hackr.jp(服务端地址) Connection:k ...

  8. 深入Django(1): 通用视图 (generic views)

    如果对Django的基础部分尚不熟悉,请参考<Django实战>系列. 内容提要 1. 回顾Django的视图函数(view function) 2. 在视图函数中使用模板 3. 简化视图 ...

  9. Django使用Ajax传递中文字符串给视图函数显示乱码的解决方法

    网上看到许多Ajax传递中文字符的解决方法,但都是比较高级的方法.我看不懂啊,觉得好复杂.翻了好多前辈的网页,找到一个解决方案.我这里用比较直白的语言解答一下,让像我这样的小白不必看到别人的解答方法就 ...

最新文章

  1. Python爬虫(三)_urllib2:get和post请求
  2. Openstack 安装部署指南翻译系列 之 概况
  3. Stefan Tilkov:跳过单体应用,从微服务开始
  4. C++编程中的头文件包含问题
  5. iphone屏幕录制_如何将iPhone投屏到Mac上?iphone投屏到苹果电脑方法
  6. Linux系统IP地址
  7. Red Hat日志文件系统-ext3
  8. ios java环境变量_iOS 环境变量配置(DebugReleaseTest)
  9. 苹果,你拿什么勇气来跟 Android 比?
  10. 多算法综合的文本挖掘系统
  11. 【javascript】基于javascript的小时钟
  12. 用人话解释比特币原理
  13. 计算机考试数据库相关知识点,计算机等级考试四级数据库工程师知识点总结
  14. 拒绝996,选对框架很关键!看这里。。。。。。
  15. 计算机学院军训条幅,最新各大高校欢迎新生横幅,确认过眼神,师兄师姐Skr人才。...
  16. 新手自己搭建服务器步骤
  17. 世界名车各种图标及文字说明
  18. 如何在YouTube上制作播放列表
  19. 网页视频播放器-插件
  20. 金融小知识 | Fama-Macbeth回归

热门文章

  1. consistent gets在Oracle使用特例
  2. PowerShell2.0之Windows排错(一)启动故障排错
  3. sybase 珍藏(五)
  4. 作幼儿教育软件的感受(2005-05-09)
  5. 学习笔记2——对象初始化和面向对象特性
  6. Go 永久阻塞的方法
  7. golang内置类型
  8. tcp/ip详解--环回接口
  9. Eclipse配置Tomcat和JDK方法
  10. python三十六:shelve模块