美文网首页工作生活
Django2_08_01_CBV之Mixins

Django2_08_01_CBV之Mixins

作者: 运维开发_西瓜甜 | 来源:发表于2019-09-24 21:12 被阅读0次

    千锋教育云计算好程序员 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)
      返回此视图将显示的单个对象(表中的一条数据)。
      这里的单对象获取的情况有两种:

      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 字段的内容(如果可用)
      • <app_label>/<model_name><template_name_suffix>.html

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

    3.1 MultipleObjectMixin

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

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

    image.png
    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<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 查询集对应的 modelmodel_name_list 的组合。
      比如 model_name 的值是 Article ,则这个上下文的变量名称将会是 Article_list

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

    关于 context 上下文

    • object_list 此视图正在显示的对象列表。
      如果指定了context_object_name,则该变量也将在上下文中设置,其值与object_list 相同。
    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 属性的值(假如提供)
    • <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.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

        本文链接:https://www.haomeiwen.com/subject/pyqocctx.html