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 View class 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 View

class 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):  # 继承TemplateView
template_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() # 添加新的queryset
return 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 #是否为永久重定向, 默认为 False
query_string = True # 是否传递GET的参数到跳转网址,True时会传递,默认为 False
pattern_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 = False
url = None
pattern_name = None
query_string = False def get_redirect_url(self, *args, **kwargs):
"""
Return the URL redirect to. Keyword arguments from the URL pattern
match generating the redirect request are provided as kwargs to this
method.
"""
if self.url:
url = self.url % kwargs
elif self.pattern_name:
url = reverse(self.pattern_name, args=args, kwargs=kwargs)
else:
return None args = self.request.META.get('QUERY_STRING', '')
if args and self.query_string:
url = "%s?%s" % (url, args)
return url
def 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)

看完应该就会一目了然。

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

通用显示视图

ListView

继承关系:

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

class StudentList(ListView):
model = models.Student # orm的model
template_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 response def get_context_data(self, *, object_list=None, **kwargs): # 重写get_context_data方法
context = super().get_context_data(**kwargs) # 拿到返回值context并更新或者扩充
context['num'] = 11
return context def 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>

DetailView

继承关系:

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

class StudentDetailView(DetailView):
model = models.Student # orm的model
template_name = 'student_detail.html' # 调用的模版文件
context_object_name = 'aaa' # 模版文件里面对应的orm数据对象的名称 def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs) # 同样的重写的方法可以做一些自定义,比如访问量+1等等的
return response def 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”指定一个模板。

Python Django CBV下的通用视图函数的更多相关文章

  1. Python/Django(CBV/FBV/ORM操作)

    Python/Django(CBV/FBV/ORM操作) CBV:url对应的类(模式) ##====================================CBV操作============ ...

  2. 第三百零五节,Django框架,Views(视图函数),也就是逻辑处理函数里的各种方法与属性

    Django框架,Views(视图函数),也就是逻辑处理函数里的各种方法与属性 Views(视图函数)逻辑处理,最终是围绕着两个对象实现的 http请求中产生两个核心对象: http请求:HttpRe ...

  3. 三 Django框架,Views(视图函数),也就是逻辑处理函数里的各种方法与属性

    Django框架,Views(视图函数),也就是逻辑处理函数里的各种方法与属性 Views(视图函数)逻辑处理,最终是围绕着两个对象实现的 http请求中产生两个核心对象: http请求:HttpRe ...

  4. Django创建通用视图函数

    想在我们有两个视图: def thinkingview(request): user = request.user if request.method == 'GET': return render( ...

  5. Django中使用Bootstrap----带view.py视图函数(也就是项目下的脚本文件)

    一.Django中使用Bootstrap 1.首先建立工程,建立工程请参照:https://www.cnblogs.com/effortsing/p/10394511.html 2.在Firstdja ...

  6. Django的一些操作与视图函数

    一 . Django的安装 pip install django==1.14.6 # 后面的数字是django的版本 二 .  通过命令行(cmd)来创建Django项目 1. 切换到保存项目的文件夹 ...

  7. python web框架篇:views视图函数

    Django请求的生命周期是怎样的? 简单地说,通过URL对应关系匹配 ->找到对应的函数(或者类)->返回字符串(或者读取Html之后返回渲染的字符串) 解剖起来如下: 1. 当用户在浏 ...

  8. django创建app、在视图函数及url中使用参数、url命名、通过redirect实现网页路径跳转

    app用来实现一个独立的功能,视图一般都写在app的view.py中,并且视图的第一个参数永远是request,视图的返回值必须是HttpResponseBase对象或子类的对象. 创建一个app:f ...

  9. [Python] Django框架入门3——深入视图

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

随机推荐

  1. react-native-deprecated-custom-components

    速记:从0.44版本开始,Navigator被从react native的核心组件库中剥离到了一个名为react-native-deprecated-custom-components的单独模块中. ...

  2. bzoj1791[IOI2008]Island岛屿(基环树+DP)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1791 题目大意:给你一棵n条边的基环树森林,要你求出所有基环树/树的直径之和.n< ...

  3. ES6学习:Map结构的目的和基本用法

    Map结构的目的和基本用法 JavaScript的对象(Object)本质上是键值对的集合(Hash结构),但是只能用字符串作为键.这给它的使用带来了很大的限制.   1 2 3 4 5 6 7 8 ...

  4. (二叉树 BFS) leetcode103. Binary Tree Zigzag Level Order Traversal

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...

  5. (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row

    You need to find the largest value in each row of a binary tree. Example: Input: 1 / \ 3 2 / \ \ 5 3 ...

  6. 使用rdbtools工具来解析redis rdb文件

    工欲善其事必先利其器,日常工作中,好的工具能够高效的协助我们工作:今天介绍一款用来解析redis rdb文件的工具,非常好用.会之,受用无穷! 一.rdbtools工具介绍 源码地址:https:// ...

  7. 基于RBAC模型的权限系统设计(Github开源项目)

    RBAC(基于角色的访问控制):英文名称Rose base Access Controller.本博客介绍这种模型的权限系统设计.取消了用户和权限的直接关联,改为通过用户关联角色.角色关联权限的方法来 ...

  8. MySQL数据库详解之"双1设置"的数据安全的关键参数案例分享

    mysql的"双1验证"指的是innodb_flush_log_at_trx_commit和sync_binlog两个参数设置,这两个是是控制MySQL 磁盘写入策略以及数据安全性 ...

  9. nginx跨域的简单应用

    nginx跨域的简单应用 要求:1.浏览器访问print.qianbaihe.wang/zt 直接调转至 www.flybirdprint.com/zt,浏览器显示域名不变. server { lis ...

  10. hostnamectl 修改 CentOS7 主机名

    hostnamectl 控制主机名 # 显示状态 hostnamectl Static hostname: centos Icon name: computer-vm Chassis: vm Mach ...