zoukankan      html  css  js  c++  java
  • 探究CBV视图

    CBV视图

    数据显示视图

    RedirectView重定向视图;

    源码位置:django/views/generic/base.py
    该类继承父类View,类View是所有视图类的底层功能类。
    该类定义了4个属性和8个类方法

    permanent:根据属性的真假来选择重定向方式,若为True,则HTTP状态码为301,否则为HTTP状态码为302.
    url:代表重定向的路由地址
    pattern_name:代表重定向的路由命名。如果已设置参数url,则无需设置该参数,否则提示异常信息
    query_string:是否将当前路由的请求参数传递到重定向的路由地址
    ### 方法
    get_redirect_url():根据属性pattern_name所指向的路由命名来生成相应的路由地址。
    get():触发HTTP的GET请求所指向的响应处理
    剩余的类方法head(),post(),options(),delete(),put()和patch()是HTTP的不同请求方式,他们都由get方法完成响应处理。
    
    实例
    class turnTo(RedirectView):
        '''
        RedirectView类定义了4个属性和8个类方法
        对该RedirectView类功能扩展只需要重新相应的类方法即可
        '''
        permanent = False
        url = None
        pattern_name = 'index:index'
        query_string = True
    
        def get_redirect_url(self, *args, **kwargs):
            print('This is get_redirect_url')
            return super().get_redirect_url(*args, **kwargs)
    
        def get(self, request, *args, **kwargs): # 只定义了重定向get的请求过程
            print(request.META.get('HTTP_USER_AGENT'))
            return super().get(request, *args, **kwargs)
    

    html文件

    <a href="{% url 'index:turnTo' %}?k=1">ToTurn</a>
    

    urls文件,需要使用视图类,需要对视图类进行实例化操作as_view()方法(django/views/generic/base.py)

    urlpatterns = [
        # 定义路由
        path('', index, name='index'),
        # as_view()对视图重定向类实例化
        path('turnTo', turnTo.as_view(), name='turnTo')
    ]
    

    总之重定向视图get_redirect_url()函数一定要写的,该方法也只是对get请求做处理,post()请求及其他htto请求可以修改对应的类方法。

    基础视图TemplateView

    源码位置:django/views/generic/base.py
    他继承TemplateResponseMixin, ContextMixin, View三各类。只有一个get方法

    class TemplateView(TemplateResponseMixin, ContextMixin, View):
        """
        Render a template. Pass keyword arguments from the URLconf to the context.
        """
        def get(self, request, *args, **kwargs):
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
    

    该类继承的类

    class TemplateResponseMixin:
        """A mixin that can be used to render a template."""
        template_name = None # 设置模板文件的文件名
        template_engine = None #设置解析模板文件的模板引擎
        response_class = TemplateResponse #设置HTTP请求的响应类
        content_type = None # 设置响应内容的数据格式
    
        def render_to_response(self, context, **response_kwargs): # 实现响应处理,由TemplateResponse响应类完成
            """
            Return a response, using the `response_class` for this view, with a
            template rendered with the given context.
    
            Pass response_kwargs to the constructor of the response class.
            """
            response_kwargs.setdefault('content_type', self.content_type)
            return self.response_class(
                request=self.request,
                template=self.get_template_names(),
                context=context,
                using=self.template_engine,
                **response_kwargs
            )
    
        def get_template_names(self): # 获取属性template_name的值
            """
            Return a list of template names to be used for the request. Must return
            a list. May not be called if render_to_response() is overridden.
            """
            if self.template_name is None:
                raise ImproperlyConfigured(
                    "TemplateResponseMixin requires either a definition of "
                    "'template_name' or an implementation of 'get_template_names()'")
            else:
                return [self.template_name]
    
    
    class TemplateView(TemplateResponseMixin, ContextMixin, View):
        """
        Render a template. Pass keyword arguments from the URLconf to the context.
        """
        def get(self, request, *args, **kwargs):
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
    class ContextMixin:
        """
        A default context mixin that passes the keyword arguments received by
        get_context_data() as the template context.
        """
        extra_context = None
    
        def get_context_data(self, **kwargs):
            kwargs.setdefault('view', self) # 说这函数是获取视图中的上下文模板
            if self.extra_context is not None:
                kwargs.update(self.extra_context)
            return kwargs
    
    实例
    from django.views.generic.base import TemplateView
    # 视图类TemplateView是所有视图类最基础的应用视图类
    class index(TemplateView):
        template_name = 'index.html' # 设置模板文件
        template_engine = None # 设置模板文件的模板引擎
        content_type = None # 设置响应内容的数据格式
        extra_context = {'title': 'This is GET'} # 模板变量设置值
    
        # 重新定义模版上下文的获取方式
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['value'] = 'I am MyDjango'
            return context
    
        # 定义HTTP的POST请求处理
        def post(self, request, *args, **kwargs):
            self.extra_context = {'title': 'This is POST'}
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
    

    列表视图类ListView

    将数据表的数据以列表的形式显示,常用于查询和展示。
    源码位置:django/views/generic/list.py
    继承MultipleObjectTemplateResponseMixin, BaseListView这两个类

    class ListView(MultipleObjectTemplateResponseMixin, BaseListView):
        """
        Render some list of objects, set by `self.model` or `self.queryset`.
        `self.queryset` can actually be any iterable of items, not just a queryset.
        """
    

    ListView类继承的和TemplateView类差不多,在此基础上还新增了以下属性和方法.基本上都是和数据查询,分页有关的。

    实例
    from django.views.generic import ListView # 将数据表的数据以列表的形式显示
    from .models import PersonInfo # 需要导入模板
    class index(ListView):
        # 设置模版文件
        template_name = 'index.html'
        # 设置模型外的数据
        extra_context = {'title': '人员信息表'}
        # 查询模型PersonInfo
        queryset = PersonInfo.objects.all() # 这个一定要填,这是向该类传入数据库查询对象
        # 每页的展示一条数据
        paginate_by = 1
        # 意思就是数据库的模板对象,在html页面可调用数据
        # 如不设置,则模版上下文默认为personinfo_list;就是数据库名_list
        # context_object_name = 'personinfo'
    

    详细视图类DetailView

    是将数据库某一条数据详细显示在网页上
    源码位置:django/views/generic/detail.py
    该类与ViewList视图类在继承上面有一定的相似之处。同时也具有TemplateView的所有属性和方法,并新增了以下属性和方法

    用时再找
    
    实例views.py
    from django.views.generic import DetailView # 详细视图DetailVie是将数据库某一条数据详细显示在网页上
    from .models import PersonInfo
    class index(DetailView):
        # 设置模版文件
        template_name = 'index.html'
        # 设置模型外的数据
        extra_context = {'title': '人员信息表'}
        # 设置模型的查询字段
        slug_field = 'age' # 可以根据路由名,get方法来查询数据库,url?age=xxx之类的
        # 设置路由的变量名,与属性slug_field实现模型的查询操作
        
        slug_url_kwarg = 'age' # 用于查询模型的其他字段
        pk_url_kwarg = 'pk' # 用于查询模型的主键
        # 设置查询模型PersonInfo
        model = PersonInfo #
        # 属性queryset可以做简单的查询操作
        # queryset = PersonInfo.objects.all()
        # 如不设置,则模版上下文默认为personinfo
        # context_object_name = 'personinfo' # context_object_name属性,模型对象用模型类的小写表示
        # 是否将pk和slug作为查询条件
        # query_pk_and_slug = False # 为false则优先查询pk_url_kwarg
    

    实例urls.py

    urlpatterns = [
        # 定义路由<>参数来源于views.py中的查询数据库字段
        path('<pk>/<age>.html', index.as_view(), name='index'),
    ]
    
    

    数据操作视图

    对模型进行操作,如增、删、改,从而实现Django与数据库的数据交互。有四个视图类

    FormView

    表单视图类:通过表单实现数据验证、响应输出等功能,用于显示表单数据
    源码位置:
    django/views/generic/edit.py
    继承自两个视图TemplateResponseMixin, BaseFormView

    class FormView(TemplateResponseMixin, BaseFormView):
        """A view for displaying a form and rendering a template response."""
    

    还和基本视图类TemplateView一样,但新增了些属性和方法

    待补
    
    实例views.py
    from django.views.generic.edit import FormView # 表单视图类
    from .form import PersonInfoForm
    from django.http import HttpResponse
    
    def result(request):
        return HttpResponse('Success')
    
    class index(FormView): # 该例子就是点击之后,跳转成功页面有success_url提供路由
        initial = {'name': 'Betty', 'age': 20} # 设置默认初始的表单值
        template_name = 'index.html' # 定义模型表单
        success_url = '/result' # 为success_url属性提供路由
        form_class = PersonInfoForm # 表单的实例化,在html页面所使用的模板变量为form.as_p,
        # 这命名固定的,是由FormMixin类的get_context_data()函数生成
        extra_context = {'title': '人员信息表'} # 模板上下文
    

    urls.py

    urlpatterns = [
        # 定义路由
        path('', index.as_view(), name='index'),
        path('result', result, name='result')
    ]
    

    表单视图类肯定要创建表单forms.py,最基本的表单类(这里是模型表单)

    from django import forms
    from .models import PersonInfo
    class PersonInfoForm(forms.ModelForm):
        class Meta:
            model = PersonInfo
            fields = '__all__'
    

    CreateView新增视图

    是对模型新增数据的视图类,他是在表单视图类FormView类的基础上加以封装的
    源码位置:django/views/generic/edit.py
    继承自SingleObjectTemplateResponseMixin, BaseCreateView这两个类

    class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
        """
        View for creating a new object, with a response rendered by a template.
        """
        template_name_suffix = '_form'
    

    到目前为止,几乎所有的视图类都会继承TemplateResponseMixin,除了重定向视图类RedirectView
    新增属性和方法:

    待补
    

    有两种表单生成方式,第一种是设置属性form_class,通过属性form_class指定表单对象,这种方式需要开发者自行定义表单对象。加入自定义的表单和模型的字符不相符,在运行过程中会出现异常情况,第二种设置model和fields属性。由模型对象和模型字段来生成相应的表单对象,生成的表单字段与模型的字段要求相符。

    实例

    views.py

    from django.views.generic.edit import CreateView# 是对模型新增数据的视图类,他是在表单视图类FormView类的基础上加以封装的
    from .form import PersonInfoForm
    from .models import PersonInfo
    from django.http import HttpResponse
    
    def result(request):
        return HttpResponse('Success')
    
    class index(CreateView): # 字段设置除了表单生成和之前的表单视图类似
        initial = {'name': 'Betty', 'age': 20}
        template_name = 'index.html'
        success_url = '/result'
        # 表单生成方式一
        # form_class = PersonInfoForm
        # 表单生成方式二
        model = PersonInfo
        # fields设置模型字段,从而生成表单字段
        fields = ['name', 'age']
        extra_context = {'title': '人员信息表'}
    

    html

    <head>
        <title>{{ title }}</title>
    <body>
        <h3>{{ title }}</h3>
        <form method="post">
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" value="确定">
        </form>
    </body>
    

    UpdateView 修改视图

    该类的实现是在FormView和DetailView类基础上实现的。是通过路由查询数据,在后再通过表单修改数据。
    源码位置:django/views/generic/edit.py
    继承自SingleObjectTemplateResponseMixin, BaseUpdateView这两个类

    class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView):
        """View for updating an object, with a response rendered by a template."""
        template_name_suffix = '_form'
    
    实例:

    views.py

    from django.views.generic.edit import UpdateView # 修改视图
    from .models import PersonInfo
    from django.http import HttpResponse
    
    def result(request):
        return HttpResponse('Success')
    
    class index(UpdateView):
        template_name = 'index.html'
        success_url = '/result'
        model = PersonInfo
        # fields设置模型字段,从而生成表单字段
        fields = ['name', 'age']
        slug_url_kwarg = 'age'
        slug_field = 'age'
        context_object_name = 'personinfo'
        extra_context = {'title': '人员信息表'}
    

    urls.py

    urlpatterns = [
        # 定义路由
        path('<age>.html', index.as_view(), name='index'),
        path('result', result, name='result')
    ]
    

    DeleteView 删除视图

    只能删除单条数据,路由变量为模型主键提供查询范围。查询出来的数据通过POST请求实现数据删除,删除过程由类DeletionMixin的delete()方法实现。
    源码位置:django/views/generic/edit.py
    继承自SingleObjectTemplateResponseMixin, BaseDeleteView这两个类

    class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView):
        """
        View for deleting an object retrieved with self.get_object(), with a
        response rendered by a template.
        """
        template_name_suffix = '_confirm_delete'
    
    实例views.py
    from django.views.generic.edit import DeleteView # 删除视图
    from .models import PersonInfo
    from django.http import HttpResponse
    
    def result(request):
        return HttpResponse('Success')
    
    class index(DeleteView):
        template_name = 'index.html'
        success_url = '/result'
        model = PersonInfo
        context_object_name = 'personinfo'
        extra_context = {'title': '人员信息表'}
    

    urls.py
    去掉.html留数字执行路由跳转时候报错

    from django.urls import path
    from .views import *
    
    urlpatterns = [
        # 定义路由pk,来自属性pk_url_kwarg,默认值为pk,可在SingleObjectMixin类中找到
        # 尽量不要使用数字单独做后缀,不加.html,容易报错ValueError: invalid literal for int() with base 10: 
        path('<pk>.html', index.as_view(), name='index'),
        path('result', result, name='result')
    ]
    

    日期筛选视图

    是根据某个日期字段进行数据筛选的,然后将符合结果的数据以一定的形式显示在网页上。在列表视图ListView或详细视图DetailView的基础上增加日期筛选所实现的视图类。一共有7个日期视图类

    1.ArchiveIndexView 是将数据表所有的数据以某个日期字段的降序方式进行排序显示的。
    2.YearArchiveView是在数据表筛选某个日期字段某年的所有数据,默认以升序的方式排序显示,年份的筛选范围由路由变量提供。
    3.MonthArchiveView是在数据表筛选某个日期字段某年某月的所有的数据,默认以升序的方式排序显示。
    4.WeekArchiveView是在数据表筛选某个日期字段某年某周的所有的数据,总周数是将一年的总天数除以7所得的,数据默认以升序的方式排序显示,年份和周数的筛选范围都是由路由变量提供的。
    5.DayArchiveView是对数据表的某个日期字段精准筛选到某年某月某天,将符合条件的数据以升序的方式排序显示,年份,月份和天数都是由路由变量提供的
    6.TodayArchiveView是在视图DayArchiveView的基础上进行封装的,他将数据表某个日期字段的筛选条件设为当天时间,符合条件的数据以升序的方式排序显示
    7.DateDetailView是查询某年某月某日某条数据的详细信息,在视图类DetailView类的基础上增加了日期筛选功能,筛选条件主要有年份、月份、天数和某个模型字段,其中某个模型字段必须具有唯一性,才能确保查询数据的唯一性。
    

    是在数据表筛选某个日期字段某年某月的所有数据,默认以升序的方式排序显示

    MonthArchiveView 月份视图

    源码位置:django/views/generic/dates.py
    继承MultipleObjectTemplateResponseMixin, BaseWeekArchiveView这两个类

    class WeekArchiveView(MultipleObjectTemplateResponseMixin, BaseWeekArchiveView):
        """List of objects published in a given week."""
        template_name_suffix = '_archive_week'
    

    为什么不在这里写新增方法,属性,太多了

    实例

    views.py

    from django.views.generic.dates import MonthArchiveView #是在数据表筛选某个日期字段某年某月的所有数据,默认以升序的方式排序显示
    from .models import PersonInfo
    
    class index(MonthArchiveView):
        allow_empty = True
        allow_future = True
        context_object_name = 'mylist'
        template_name = 'index.html'
        model = PersonInfo
        date_field = 'hireDate' # 日期数据筛选
        queryset = PersonInfo.objects.all()
        year_format = '%Y'
        # month_format默认格式是支持英文日期,如Oct、Sep
        month_format = '%m' # 默认值为%b,mouth在url中的属性是整型,所以改为%m
        paginate_by = 50
    

    urls.py

    from django.urls import path
    from .views import *
    
    urlpatterns = [
        # 定义路由
        path('<int:year>/<int:month>.html', index.as_view(), name='index'),
        # path('<int:year>/<str:month>.html', index.as_view(), name='index'),
    ]
    

    html文件

    <body>
    <ul>
        {% for v in object_list %}<!--由模型查询所得的数据对象,默认为object_list或者page_obj(常用在分页)-->
            <li>{{ v.hireDate }}: {{ v.name }}</li>
        {% endfor %}
    </ul>
    <p>
        {% if previous_month %}
            Previous Month: {{ previous_month }} <!--根据路由变量year和month的日期计算出上一个月的日期-->
        {% endif %}
        <br>
        {% if next_month %}<!--下一个月日期-->
            Next Month: {{ next_month }}
        {% endif %}
    </p>
    </body>
    

    WeekArchiveView 周期视图

    是在数据表筛选某个日期字段某年某周的所有的数据
    源码位置:django/views/generic/dates.py
    继承自MultipleObjectTemplateResponseMixin, BaseWeekArchiveView这两个类。

    class WeekArchiveView(MultipleObjectTemplateResponseMixin, BaseWeekArchiveView):
        """List of objects published in a given week."""
        template_name_suffix = '_archive_week'
    
    实例views.py
    from django.views.generic.dates import WeekArchiveView # 是在数据表筛选某个日期字段某年某周的所有的数据
    from .models import PersonInfo
    
    class index(WeekArchiveView):
        allow_empty = True 
        allow_future = True # 设置是否显示未来日期的数据,如产品有效期
        context_object_name = 'mylist'
        template_name = 'index.html'
        model = PersonInfo
        date_field = 'hireDate' # 日期数据筛选
        queryset = PersonInfo.objects.all()
        year_format = '%Y'
        week_format = '%W' # 改变的地方和上个相比
        paginate_by = 50
    

    urls.py

    from django.urls import path
    from .views import *
    
    urlpatterns = [
        # 定义路由;最好设置为整型,不同的数据类型会影响视图类MonthArchiveView的属性month_format的值。
        path('<int:year>/<int:week>.html', index.as_view(), name='index'),
    ]
    

    知识点as.view()实例化视图类,写在视图函数中(urls.py中也可以,只要那里导入了视图类)

    笔记来源:Django Web应用开发实战

    努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。
  • 相关阅读:
    Java 工程转 C#
    初涉Linux ----------> 打造自己的 Vim IDE
    初涉Linux ----------> Ubuntu15.04的安装与美化
    没学过CSS等前端的我,也想美化一下自己的博客
    作为程序员之 Vim(一)
    win7升win10,初体验
    作为程序员之正则表达式
    数据库系统原理
    Mysql数据库笔记
    我的个人常用快捷键
  • 原文地址:https://www.cnblogs.com/wkhzwmr/p/15634153.html
Copyright © 2011-2022 走看看