Django2_08_01_CBV之Mixins

千锋教育云计算好程序员 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 }}

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)
    返回此视图将显示的单个对象(表中的一条数据)。
    这里的单对象获取的情况有两种:

    1. 如果提供了queryset属性的值,则从该 queryset 查询集获取;
    2. 没有提供 queryset 属性的值,将使用 get_queryset() 方法中获取。

    get_object() 在视图的参数中查找 pk_url_kwarg 参数;如果找到此参数,则此方法使用该值执行基于主键的查找。如果找不到此参数,它将查找slug_url_kwarg 参数,并使用 slug_field 执行 slug 查找。

    query_pk_and_slugTrue 时,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=articlearticle 中将会包含 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 字段的内容(如果可用)
    • /.html

3. Multiple object mixins (多个对象 Mixins)

3.1 MultipleObjectMixin

用于为多个对象以列表的方式显示出来。

实际上这个 Mixin 继承了 ContextMixin, 之后又添加了一些分页的属性和方法

Django2_08_01_CBV之Mixins_第1张图片
image.png

Django2_08_01_CBV之Mixins_第2张图片
image.png

class 类

django.views.generic.list.MultipleObjectMixin

Attributes 属性

  • model
    此视图将显示数据的模型。
    model = Foo 等同于 model = Foo.objects.all()

  • queryset
    一个对象的查询集,如果提供了此值,model 属性提供的值将会被取代
    所以可以利用这个属性,对反回对象列表进行简单的过滤。

  • page_kwarg
    用于指定当前请求页码的关键字参数名称。

  • paginate_by
    一个整数,指定每页应显示的对象数。默认是 None。表示不进行分页。
    假如指定了具体的数字,视图就会进行分页。
    视图可以从以下两种途径获取到当前请求的页码。

    1. 从 GET 方法的参数中得到,URL 就像下面这样
    /objects/?page=3
    
    1. 从 URLconf 中获取, URLconf 中的 URL就像这样
    path('objects/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 查询集对应的 modelmodel_name_list 的组合。
    比如 model_name 的值是 Article ,则这个上下文的变量名称将会是 Article_list

  • get_context_data(**kwargs)
    返回用于显示对象列表的上下文数据。

关于 context 上下文

  • object_list 此视图正在显示的对象列表。
    如果指定了context_object_name,则该变量也将在上下文中设置,其值与object_list 相同。
Django2_08_01_CBV之Mixins_第3张图片
image.png

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 属性的值(假如提供)
  • /.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.objectqueryset 确定。

  • 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

你可能感兴趣的:(Django2_08_01_CBV之Mixins)