>[success] # DetailView ~~~ DetailView 不准确个人总结: 1.请求到达之后,首先会调用distpatch进行分发。 2.接着会调用get方法 3.在get请求中,首先会调用get_object方法,拿到数据源 4.在get_object方法中,调用get_queryset() 获取查询对象,在查询要查询单个数据id 5.接着继续调用get_context_data方法,拿到需要渲染到模板中的数据 6.在get_context_data中,首先会去调用get_paginate_by拿到每页数据 7.接着调用get_context_object_name拿到要渲染到模板中的这个queryset名称 * 8.把拿到的数据转为dict,返回 9.调用render_to_response渲染数据到页面中 10.在render_to_response中会调用get_tempalte_names拿到模板名 11.然后把request, context, template_name等传递到模板中 ~~~ * 文档中的截图 ![](https://box.kancloud.cn/eb3d041fa1f2b5e5883ba214462f938a_644x466.png) * 文档中的用法 ~~~ from django.views.generic.detail import DetailView from django.utils import timezone from articles.models import Article class ArticleDetailView(DetailView): model = Article def get_context_data(self, **kwargs): context = super(ArticleDetailView, self).get_context_data(**kwargs) context['now'] = timezone.now() return context ~~~ ~~~ from django.conf.urls import url from article.views import ArticleDetailView urlpatterns = [ url(r'^(?P<slug>[-\w]+)/$', ArticleDetailView.as_view(), name='article-detail'), ] ~~~ ~~~ <h1>{{ object.headline }}</h1> <p>{{ object.content }}</p> <p>Reporter: {{ object.reporter }}</p> <p>Published: {{ object.pub_date|date }}</p> <p>Date: {{ now|date }}</p> ~~~ * 源码中初始化参数 ~~~ model = None queryset = None slug_field = 'slug' context_object_name = None slug_url_kwarg = 'slug' pk_url_kwarg = 'pk' query_pk_and_slug = False ~~~ >[success] # 博客中的ListView 案例 >[danger] ##### url设计 ~~~ from django.conf.urls import url from django.contrib import admin from blong.views import IndexView, CategoryView, TagView, PostView from config.views import links from .custom_site import custom_site urlpatterns = [ url(r"^$", IndexView.as_view()), url(r'^category/(?P<category_id>\d+)/$', CategoryView.as_view(), name="category"), url(r'^tag/(?P<tag_id>\d+)/$', TagView.as_view(), name="tag"), url(r'^post/(?P<pk>\d+)/$', PostView.as_view(),name="detail"), url(r'^links/$', links), url(r'^admin/', admin.site.urls), url(r'^cus_admin/', custom_site.urls), ] ~~~ >[danger] ##### 分析讲解 ~~~ 1.只要获取对应的id,及获取每个文章的详情 2.也是可以更改get_queryset()方法,但获取的是一组数据 3.重写get_object()查询的是 单条数据 4.注意url 默认使用pk 作为对应名称 ~~~ * 源码中的get_object ~~~ def get_object(self, queryset=None): """ Returns the object the view is displaying. By default this requires `self.queryset` and a `pk` or `slug` argument in the URLconf, but subclasses can override this to return any object. """ # Use a custom queryset if provided; this is required for subclasses # like DateDetailView if queryset is None: queryset = self.get_queryset() # Next, try looking up by primary key. pk = self.kwargs.get(self.pk_url_kwarg) slug = self.kwargs.get(self.slug_url_kwarg) if pk is not None: queryset = queryset.filter(pk=pk) # Next, try looking up by slug. if slug is not None and (pk is None or self.query_pk_and_slug): slug_field = self.get_slug_field() queryset = queryset.filter(**{slug_field: slug}) # If none of those are defined, it's an error. if pk is None and slug is None: raise AttributeError("Generic detail view %s must be called with " "either an object pk or a slug." % self.__class__.__name__) try: # Get the single item from the filtered queryset obj = queryset.get() except queryset.model.DoesNotExist: raise Http404(_("No %(verbose_name)s found matching the query") % {'verbose_name': queryset.model._meta.verbose_name}) return obj ~~~ >[danger] ##### 文章详情页代码 ~~~ class PostView(CommonMixin, DetailView): model = Post template_name = 'blog/detail.html' ~~~