您的位置:首页 > 大数据 > 人工智能

django通用视图的DetailView

2020-03-20 10:43 197 查看

SingleObjectMixin

主要功能:

  1. def get_queryset(self):
    返回query_set里的所有对象

      如果提供的
      queryset
      为空且
      model
      不为空,返回
      self.model._default_manager.all()
    • 提供了
      queryset
      ,返回
      self.queryset.all()
  2. get_object(self, queryset=None)
    :根据请求url里的关键字参数pk或者slug过滤query_set来获取单一对象(obj)

    queryset = queryset.filter(pk=pk) 或者 queryset = queryset.filter(**{slug_field: slug})
    obj = queryset.get()
    return obj
  3. def get_context_data(self, **kwargs):
    将对象(obj)其插入到渲染模板所需的上下文中

    self.object = self.get_object
    context['object'] = self.object
    # 或者可以自定义对象名,两者是同时存在的:
    context[context_object_name] = self.object
class SingleObjectMixin(ContextMixin):
"""
提供了可以操纵检索单一对象的能力
"""
model = None
queryset = None
slug_field = 'slug'
context_object_name = None
slug_url_kwarg = 'slug'
pk_url_kwarg = 'pk'
query_pk_and_slug = False

def get_object(self, queryset=None):
# 根据pk和slug查找object
# 如果自定义了queryset就使用它,这是子类需要的
# 比如DateDetailView
if queryset is None:
queryset = self.get_queryset()

# 接着试着查询pk
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)

# 接着试着查询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 in the URLconf." % 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

def get_context_data(self, **kwargs):
"""插入单一对象到上下文字典中"""
context = {}
if self.object:
context['object'] = self.object
context_object_name = self.get_context_object_name(self.object)
if context_object_name:
context[context_object_name] = self.object
context.update(kwargs)
return super().get_context_data(**context)

BaseDetailView

BaseDetailView
主要是组合
SingleObjectMixin
view
的各种方法来实现服务器处理一个获取单一对象的get请求的一般流程。

class BaseDetailView(SingleObjectMixin, View):
"""一个展示单一对象的基本视图"""
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)

SingleObjectTemplateResponseMixin

SingleObjectTemplateResponseMixin主要是重写了

get_template_names
方法,也就是其模板的名字是

app_label + model_name(小写) + template_name_suffix(_detail)

class SingleObjectTemplateResponseMixin(TemplateResponseMixin):
template_name_field = None
template_name_suffix = '_detail'

def get_template_names(self):
# 省略....
if isinstance(self.object, models.Model):
object_meta = self.object._meta
names.append("%s/%s%s.html" % (
object_meta.app_label,
object_meta.model_name,
self.template_name_suffix
))
elif getattr(self, 'model', None) is not None and issubclass(self.model, models.Model):
names.append("%s/%s%s.html" % (
self.model._meta.app_label,
self.model._meta.model_name,
self.template_name_suffix
))

return names

DetailView

class DetailView(SingleObjectTemplateResponseMixin, BaseDetailView):
"""
Render a "detail" view of an object.

By default this is a model instance looked up from `self.queryset`, but the
view will support display of *any* object by overriding `self.get_object()`.
"""

总结

  1. SingleObjectMixin.get_context_data
    获取含有单个对象的上下文(
    context
    )

  2. SingleObjectTemplateResponseMixin.render_to_response
    利用上下文进行渲染并返回响应,并重写其

    get_template_names方法

  3. BaseDetailView组合SingleObjectMixin和View
    并实现
    get
    请求和分发

  4. DetailView
    组合
    SingleObjectTemplateResponseMixin
    BaseDetailView
    实现完整的逻辑处理

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: