Django类视图CBV扩展基类之通用显示视图ListView、DetailView

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

通用显示视图

ListView

显示一个结果集数据

dispatch()
http_method_not_allowed()
get_template_names()
get_queryset()
get_context_object_name()
get_context_data()
get()
render_to_response()
  • 这是这个视图的源码以及一些相应属性
class ListView(MultipleObjectTemplateResponseMixin, BaseListView):
    """
    Render some list of objects, set by `self.model` or `self.queryset`.
    `self.queryset` can actually be any iterable of items, not just a queryset.
    """
    model = models.User # 重写model类属性,指定模型的列表
    template_name = 'userlist.html' # 指定这个列表的模板。
    context_object_name = 'userdata' # 指定这个列表模型在模板中的参数名称。
    ordering = 'create_time'   # 以时间进行排序展示
    # -----------------------------------------------------------
    paginate_by = 10  # 每一页需要展示多少条数据
    page_kwarg = 'p'   # 指定换页面的参数 默认为page 以GET的方式传递参数
  • MultipleObjectTemplateResponseMixin:重写了get_template_names方法,改写了获取模版文件的路径名,默认为app_name/model_name_list.html

  • BaseListView:定义get方法,提供给dispatch方法

可以重写BaseListView->MultipleObjectMixin->get_context_data函数进行自定义上下文数据

可以重写BaseListView->MultipleObjectMixin->get_queryset对视图所返回的数据进行过滤定义

  • 这是一个简单的demo来举例说明两个函数的用法
class ListTest(ListView):
    model = User
   	template_name = 'index.html'
    context_object_name = 'users'
	def get_context_data(self, **kwargs): # 获取上下文的数据。并且可以添加自己的参数
    	context['username'] = 'test'
    	return context
  	def get_queryset(self):
    	if self.model is not None:
      	queryset = self.model._default_manager.all()
        ordering = self.get_ordering()
		if ordering:
			if isinstance(ordering, str):
				ordering = (ordering,)
				queryset = queryset.order_by(*ordering)
		return queryset

DetailView

返回单个对象的数据

dispatch()
http_method_not_allowed()
get_template_names()
get_slug_field()
get_queryset()
get_object()
get_context_object_name()
get_context_data()
get()
render_to_response()
  • 它里面比较重要的一个继承父类,在这个父类中,指明了当前DetailViewu所需要的一些属性,以及一个非常重要的函数get_object,这个函数将会帮助我们返回一个具体要显示的数据
class SingleObjectMixin(ContextMixin):
    """
    Provide the ability to retrieve a single object for further manipulation.
    """
    model = None # 数据模型,将在视图页面展示数据
    queryset = None # queryset如果提供,则值queryset取代设置model的值
    slug_field = 'slug' # 过滤的字段
    context_object_name = None
    slug_url_kwarg = 'slug' # 过滤条件,通过链接参数给定;如 a.com/<str:slug>/
    pk_url_kwarg = 'pk' # 启用主键作为链接参数过滤条件
    query_pk_and_slug = False # 当依赖主键查询不为空时,设置该值为True,可以继续过滤字段,就是又过滤pk还过滤field
    def get_object(self, queryset=None):
      	pass
  • 如果现在想要根据用户名获取具体的某个用户数据,那么可以定义这样一个视图
class DetailTest(DetailView):
    model = User
    slug_field = 'name' # 这是我要查询的字段
    context_object_name = 'user'
    slug_url_kwarg = 'name' 
    # 这个视图会通过这里定义的这个字段中去链接中匹配查找符合的数据,用来配合slug_field做查询条件
    query_pk_and_slug = True
	# 默认数据的返回模版页面定义规则如下:appname/modelname_detail.html
  • 这样定义好一个简单的视图后,我们还需要路由匹配部分进行配合
path('<str:name>/',DetailTest.as_view()) # 这里是传递到DetailView视图用来过滤的条件值
  • 如果需要自定义捕捉链接参数指明多个链式过滤条件,可以通过重写get_object方法,比如需要通过关联外键与数据本体查找某个你想要的数据,那么可以这样
class DetailTest(DetailView): 
    model = Info
    context_object_name = 'info'
   	def get_object(self,queryset=None):
      	some_id = self.kwargs.get('some_id') # a.com/<int:some_id>/<str:other>
        other = self.kwargs.get('other') # a.com/<int:some_id>/<str:other>/
        try:
            obj = self.model._default_manager.get(some_id=some_id,other=other)
        except:
            obj = None
        return obj
   	def get_context_data(self,**kwargs):
    	# 在这里可以通过context额外设置上下文
    	pass
  • 配合的路由将会是这样的
path('<int:some_id>/<str:other>/',DetailTest.as_view()),

猜你喜欢

转载自blog.csdn.net/HeroicLee/article/details/121508068