千锋教育云计算好程序员 shark
本文链接 https://www.jianshu.com/p/88a33406466e
Django 的内建的基于类的视图提供很多函数特性,有些情况下可能会想单独使用它们。
因为这个原因,Django 也提供了很多提供分离特性的mixins。比如,模板渲染被封装在 TemplateResponseMixin
里。
一、下面介绍 Django 提供的所有的 Mixin
1. Simple mixins 简单的 mixins
1.1 ContextMixin
class 类名
django.views.generic.base.ContextMixin
Attributes 属性
extra_context
一个包含了上下文的字典,假设你在返回模板时,只需要返回简单的上下文,这个是不错的选择。
用法示例:from django.views.generic import TemplateView path('/index/', TemplateView.as_view(extra_context={'title': '自定义 title'})),
模板中使用
<title>{{ title }}</title>
Methods 方法
get_context_data(**kwargs)
返回表示模板上下文的字典。 提供的任意的关键字参数将合并到返回的上下文字典中。
用法示例:def get_context_data(self, **kwargs): # 调用超类方法 context = super().get_context_data(**kwargs) # 添加额外的数据,这个和模型中的数据是平级的 context['number'] = random.randrange(1, 100) return context
1.2 TemplateResponseMixin
class 类
django.views.generic.base.TemplateResponseMixin
Attributes 属性
template_name
是由字符串定义使用的模板的全名,不定义就会抛出异常-
response_class
render_to_response
方法返回的响应类。默认是TemplateResponse
。
Methods 方法
render_to_response(context, **response_kwargs)
返回self.response_class实例。
如果提供了任何关键字参数,它们将被传递给响应类的构造函数。
调用get_template_names()
以获取将搜索的模板名称列表,以查找现有模板。
get_template_names()
返回呈现模板时要搜索的模板名称列表。 将使用找到的第一个模板。
如果用template_name
指定了自定义的模板名称,则返回模板列表中会包含template_name
指定的模板名称。
2. Single object mixins (单个对象 mixins)
2.1 SingleObjectMixin
class 类
django.views.generic.detail.SingleObjectMixin
Attributes 属性
model
此视图用这个 Model 进行数据展示。
model = Foo
实际上与queryset = Foo.objects.all()
是相同的。
queryset
一个表示对象的 QuerySet 。
如果提供,queryset的值将取代为model提供的值。
slug_field
model 中的字段名称。默认情况下,slug_field
的值是slug
,用于过滤查找。你应该设置为自己 model 中的字段名。
slug_url_kwarg
URLConf 中关键字参数的名称,会把对应的值作为关键字参数传递给视图。默认值是slug
pk_url_kwarg
URLConf 中关键字参数的名称,其值会作为主键的值进行查找。默认是pk
context_object_name
指定传递给前端代表 model 数据对象的变量名。
query_pk_and_slug
如果为True
,则get_object()
将使用主键和slug
执行其查找。默认为False
。
Methods 方法
get_object(queryset=None)
返回此视图将显示的单个对象(表中的一条数据)。
这里的单对象获取的情况有两种:
- 如果提供了
queryset
属性的值,则从该queryset
查询集获取;- 没有提供
queryset
属性的值,将使用get_queryset()
方法中获取。
get_object()
在视图的参数中查找pk_url_kwarg
参数;如果找到此参数,则此方法使用该值执行基于主键的查找。如果找不到此参数,它将查找slug_url_kwarg
参数,并使用slug_field
执行slug
查找。当
query_pk_and_slug
为True
时,get_object()
将使用主键和slug
执行其查找。
get_queryset()
返回此视图将显示的对象的查询集。默认情况下,get_queryset()
返回queryset
属性的值(如果已设置),否则它通过调用Foo.objects.all()
方法来构造 QuerySet。
get_context_object_name(obj)
返回包含此视图正在操作的数据的上下文变量名称。用于前端模板语言的使用。
如果未设置context_object_name
,则将根据组成查询集的模型的model_name
的小写构造上下文名称。
例如,模型Article
将具有名为article
的上下文对象。
get_context_data(**kwargs)
返回用于显示对象的上下文数据。
此方法的基本实现要求视图设置self.object属性(即使None)。
具体来说会返回包含一下内容的字典:
object
:此视图正在显示的对象(self.object)。context_object_name
:self.object
也会包含在这个名字下。
例如,设置context_object_name=article
,article
中将会包含self.object
这个名称默认是 model 名称的小写形式。
get_slug_field()
返回用于通过 slug 查找的slug
字段的名称。
默认情况下,这只返回slug_field
的值。
2.2 SingleObjectTemplateResponseMixin
class 类
django.views.generic.detail.SingleObjectTemplateResponseMixin
一个mixin类,它为对单个对象实例进行操作的视图执行基于模板的响应呈现。 要求与其混合的视图提供 self.object
,即视图正在操作的对象实例。 self.object
通常是 Django 模型的一个实例,但这不是必须的。 如果视图正在构建新实例的过程中,它可能为 None
。
Attributes 属性
template_name_field
当前对象实例上的字段,可用于确定候选模板的名称。 如果template_name_field
本身或当前对象实例上的template_name_field
的值为None
,则该对象将不会用于候选模板名称。
template_name_suffix
附加到自动生成的候选模板名称的后缀。 默认后缀是_detail
。
Methods 方法
get_template_names()
返回候选模板名称列表。 返回以下列表:
- 视图上
template_name
的值(如果提供)- 视图所在的对象实例上的
template_name_field
字段的内容(如果可用)<app_label>/<model_name><template_name_suffix>.html
3. Multiple object mixins (多个对象 Mixins)
3.1 MultipleObjectMixin
image.png用于为多个对象以列表的方式显示出来。
实际上这个 Mixin 继承了
ContextMixin
, 之后又添加了一些分页的属性和方法
image.png
class 类
django.views.generic.list.MultipleObjectMixin
Attributes 属性
model
此视图将显示数据的模型。
model = Foo
等同于model = Foo.objects.all()
queryset
一个对象的查询集,如果提供了此值,model
属性提供的值将会被取代
所以可以利用这个属性,对反回对象列表进行简单的过滤。
page_kwarg
用于指定当前请求页码的关键字参数名称。
paginate_by
一个整数,指定每页应显示的对象数。默认是 None。表示不进行分页。
假如指定了具体的数字,视图就会进行分页。
视图可以从以下两种途径获取到当前请求的页码。
- 从 GET 方法的参数中得到,URL 就像下面这样
/objects/?page=3
- 从 URLconf 中获取, URLconf 中的 URL就像这样
path('objects/page<int:page>/', PaginatedView.as_view()),
paginate_orphans
是否允许最后一页显示的对象超出paginate_by
指定的值。默认是 0。
假如指定了具体的值,这样可以防止最后一页显示太少的对象。
比如: 总共 10 条数据(对象),规定每页显示 4 条数据,那应该被分页 3 页,最后一页只有 2 条数据。
假如指定paginate_orphans
的值是 2 及以上的值,则就会分为 2 页,最后一页将线上 6 条数据( 4 + 2)
allow_empty
一个布尔值,指定在没有可用对象时是否显示页面。默认是True。
如果是,False并且没有可用的对象,则视图将引发404而不是显示空白页面。
paginator_class
用于分页的类。 默认使用django.core.paginator.Paginator
。
要想使用自定义的分页类,可以覆盖此值。
context_object_name
指定要在上下文中使用的变量的名称。
ordering
字符串或字符串列表,指定要应用于queryset
的排序规则。
Methods 方法
get_queryset()
返回一个这个视图所要展示的对象列表。
假如提供了queryset
属性的值,就返回。
没有提供queryset
,并且提供了model
属性的值,就返回model
属性值的所有查询集(Foo.objects.all())。
假如以上两个属性都没提供,就抛出异常。
最后,假设提供了queryset
属性和model
属性的任何一个。
接着判断ordering
是否为真,为真就根据此条件对queryset
排序。
最终返回queryset
get_ordering()
返回用于queryset
排序的字段或可被迭代的字段集合,字符串类型。默认是ordering
属性的值。
get_allow_empty()
返回allow_empty
属性的值
get_paginate_orphans()
默认返回paginate_orphans
属性的值
get_paginator(queryset, per_page, orphans=0, allow_empty_first_page=True)
返回用于此视图的分页类实例。默认情况下,实例化一个paginator_class
实例。
get_paginate_by(queryset)
默认返回paginate_by
属性的值。
paginate_queryset(queryset, page_size)
返回一个 4 元组(paginator, page, object_list, is_paginated)
get_context_object_name(object_list)
返回将用于此视图正在操作数据列表上下文变量名称
假如提供context_object_name
属性的值,则返回此值。
没有提供context_object_name
属性的值,并且传入的object_list
是 Django 对象的查询集, 则返回
object_list
查询集对应的model
的model_name
和_list
的组合。
比如model_name
的值是Article
,则这个上下文的变量名称将会是Article_list
get_context_data(**kwargs)
返回用于显示对象列表的上下文数据。
关于 context
上下文
image.png
object_list
此视图正在显示的对象列表。
如果指定了context_object_name
,则该变量也将在上下文中设置,其值与object_list
相同。
3.2 MultipleObjectTemplateResponseMixin
class 类
django.views.generic.list.MultipleObjectTemplateResponseMixin
继承
TemplateResponseMixin
一个mixin类,用于视图对其操作的对象列表,响应一个基于模板展示的请求。 要求与其混合的视图提供
self.object_list
,即视图正在操作的对象实例的列表。self.object_list
可以是QuerySet
, 但不限于QuerySet
Attributes 属性
template_name_suffix
附加到自动生成的候选模板名称的后缀。 默认后缀为
_list
。
Methods 方法
get_template_names()
返回候选模板名称列表。 返回以下列表:
- 视图上的
template_name
属性的值(假如提供)<app_label>/<model_name><template_name_suffix>.html
4. Editing mixins (编辑 Mixins)
4.1 FormMixin
一个mixin类,提供创建和显示表单的工具。
源码
class FormMixin(ContextMixin):
"""Provide a way to show and handle a form in a request."""
initial = {}
form_class = None
success_url = None
prefix = None
def get_initial(self):
"""Return the initial data to use for forms on this view."""
return self.initial.copy()
def get_prefix(self):
"""Return the prefix to use for forms."""
return self.prefix
def get_form_class(self):
"""Return the form class to use."""
return self.form_class
def get_form(self, form_class=None):
"""Return an instance of the form to be used in this view."""
if form_class is None:
form_class = self.get_form_class()
return form_class(**self.get_form_kwargs())
def get_form_kwargs(self):
"""Return the keyword arguments for instantiating the form."""
kwargs = {
'initial': self.get_initial(),
'prefix': self.get_prefix(),
}
if self.request.method in ('POST', 'PUT'):
kwargs.update({
'data': self.request.POST,
'files': self.request.FILES,
})
return kwargs
def get_success_url(self):
"""Return the URL to redirect to after processing a valid form."""
if not self.success_url:
raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
return str(self.success_url) # success_url may be lazy
def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL."""
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form):
"""If the form is invalid, render the invalid form."""
return self.render_to_response(self.get_context_data(form=form))
def get_context_data(self, **kwargs):
"""Insert the form into the context dict."""
if 'form' not in kwargs:
kwargs['form'] = self.get_form()
return super().get_context_data(**kwargs)
class 类
django.views.generic.edit.FormMixin
Attributes 属性
initial
包含表单初始数据的字典。
form_class
要实例化的表单类。
success_url
成功处理表单时重定向到的URL。
Methods 方法
get_initial()
返回表单的初始数据。默认情况下,返回initial
的副本 。
get_form_class()
返回要实例化的表单类。默认情况下是form_class
。
get_form(form_class=None)
返回要在此视图中使用的表单实例。
get_form_kwargs()
构建实例化表单所需的关键字参数。
form_valid(form)
如果表单有效时,重定向到提供的URL。
form_invalid(form)
如何表单数据是无效的,将无效表单作为上下文返回。
get_context_data(**kwargs)
调用get_form()
并将结果添加到名为form
的上下文数据中。
4.2 ModelFormMixin
源码
class ModelFormMixin(FormMixin, SingleObjectMixin):
"""Provide a way to show and handle a ModelForm in a request."""
fields = None
def get_form_class(self):
"""Return the form class to use in this view."""
if self.fields is not None and self.form_class:
raise ImproperlyConfigured(
"Specifying both 'fields' and 'form_class' is not permitted."
)
if self.form_class:
return self.form_class
else:
if self.model is not None:
# If a model has been explicitly provided, use it
model = self.model
elif getattr(self, 'object', None) is not None:
# If this view is operating on a single object, use
# the class of that object
model = self.object.__class__
else:
# Try to get a queryset and extract the model class
# from that
model = self.get_queryset().model
if self.fields is None:
raise ImproperlyConfigured(
"Using ModelFormMixin (base class of %s) without "
"the 'fields' attribute is prohibited." % self.__class__.__name__
)
return model_forms.modelform_factory(model, fields=self.fields)
def get_form_kwargs(self):
"""Return the keyword arguments for instantiating the form."""
kwargs = super().get_form_kwargs()
if hasattr(self, 'object'):
kwargs.update({'instance': self.object})
return kwargs
def get_success_url(self):
"""Return the URL to redirect to after processing a valid form."""
if self.success_url:
url = self.success_url.format(**self.object.__dict__)
else:
try:
url = self.object.get_absolute_url()
except AttributeError:
raise ImproperlyConfigured(
"No URL to redirect to. Either provide a url or define"
" a get_absolute_url method on the Model.")
return url
def form_valid(self, form):
"""If the form is valid, save the associated model."""
self.object = form.save()
return super().form_valid(form)
class 类
django.views.generic.edit.ModelFormMixin
可以使用 mixin ModelForms 的表单,而不是独立的表单。
Attributes 属性
model
就是 Model。
可以明确提供,否则将通过检查self.object
或queryset
确定。
fields
存在于 Model 中需要验证的字段。
success_url
成功处理表单时重定向到的URL。
success_url
可能包含字典字符串格式,将根据对象的字段属性进行插值。
例如,您可以使用success_url="/polls/{slug}/"
重定向到由slug模型上的字段组成的 URL 。
Methods 方法
参考
FormMixin
4.3 ProcessFormView
源码
继承:
django.views.generic.base.View
class ProcessFormView(View):
"""Render a form on GET and processes it on POST."""
def get(self, request, *args, **kwargs):
"""Handle GET requests: instantiate a blank version of the form."""
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
"""
Handle POST requests: instantiate a form instance with the passed
POST variables and then check if it's valid.
"""
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
# PUT is a valid HTTP verb for creating (with a known URL) or editing an
# object, note that browsers only support POST for now.
def put(self, *args, **kwargs):
return self.post(*args, **kwargs)
class 类
django.views.generic.edit.ProcessFormView
一个mixin,提供基本的HTTP GET和POST工作流程。
Methods 方法
get(request, *args, **kwargs)
使用get_context_data()
创建的上下文呈现响应。
post(request, *args, **kwargs)
构造一个表单,检查表单的有效性,并相应地处理它。
put(*args, **kwargs
PUT操作也被处理,只是将所有参数传递给post()
。
4.4 DeletionMixin
class DeletionMixin:
"""Provide the ability to delete objects."""
success_url = None
def delete(self, request, *args, **kwargs):
"""
Call the delete() method on the fetched object and then redirect to the
success URL.
"""
self.object = self.get_object()
success_url = self.get_success_url()
self.object.delete()
return HttpResponseRedirect(success_url)
# Add support for browsers which only accept GET and POST for now.
def post(self, request, *args, **kwargs):
return self.delete(request, *args, **kwargs)
def get_success_url(self):
if self.success_url:
return self.success_url.format(**self.object.__dict__)
else:
raise ImproperlyConfigured(
"No URL to redirect to. Provide a success_url.")
class 类
django.views.generic.edit.DeletionMixin
处理HTTP DELETE 请求
Attributes 属性
success_url
成功删除指定对象时重定向到的URL。
Methods 方法
delete(request, *args, **kwargs)
检索目标对象并调用其delete()
方法,然后重定向到成功URL。
get_success_url()
返回成功删除指定对象时要重定向的URL。默认返回success_url
。
网友评论