linRichielinRichie
前端
Python
Linux
ChatGPT
  • B 站
  • 500px
前端
Python
Linux
ChatGPT
  • B 站
  • 500px
    • Python学习指南
  • 快速开始

    • Python: 输入与输出 (I/O)
    • Python: 异常处理 try-except
    • Python: List深入概述
    • Python: 面向对象编程(OOP)
  • Python 语法库函数

    • 语法库目录
    • 库

      • library目录
      • argparse:解析命令行参数
      • difflib:比较序列并生成差异信息
      • dnspython: DNS处理库
      • IPy:IP地址处理库
      • logging:记录和管理日志信息
      • os:访问和操作操作系统
      • psutil:系统性能信息库
      • re:正则表达式库
      • smtplib:邮件发送库
    • 函数

      • function目录
      • any() 函数
      • input 函数
      • lambda 和 map 函数
      • reversed()函数
      • zip()函数
    • 语句

      • statement目录
      • import 语句
      • Try/Exception 异常
    • 概念

      • concept目录
      • 深拷贝与浅拷贝
      • 列表、字典与元组
      • 文件读写
      • IO: 输入与输出
      • 逻辑判断与条件语句
      • OOP 面向对象:class
      • OOP: 面向对象编程
  • SQLAlchemy

    • 获取insert或者update的id
  • Pandas

    • Pandas目录
    • Pandas:基础操作
    • Pandas:数据处理与转换
    • Pandas: 数据写入 excel 表格
  • Python前端框架

    • Flask

      • 1. Flask简介
      • 2. Flask程序基本结构
      • 3. Flask请求-响应循环
      • 4. flask案例: 框架网页查询IP
      • Python: Flask中的GitHub OAuth
    • Django

      • chapter-01:Django框架认识

        • 1.1 Django的产生背景
        • 1.2 MTV设计模式
        • 1.3 Django 主要功能模块
      • chapter-02:开发环境配置

        • 2.1 Python的安装与配置
        • 2.2 虚拟环境安装与配置
        • 2.3 Django安装与配置
        • 2.4 MySQL安装配置
      • chapter-03:项目框架搭建

        • 3.1 Django管理工具-创建项目骨架
        • 3.2 修改项目的默认配置
        • 3.3 初始化项目环境
      • chapter-04:ORM应用与原理剖析

        • 4.1 构建POST应用需要的数据集
        • 4.2 Model相关的概念和使用方法
        • 4.3 Model的查询操作API
        • 4.4 ORM实现原理
      • chapter-05:Django管理后台

        • 5.1 将Model注册到管理后台
        • 5.2 管理后台实现原理
      • chapter-06:视图

        • 6.1 视图基础
        • 6.2 视图的高级特性和快捷方法
        • 6.3 基于类的通用视图
      • chapter-07:模板系统

        • 7.1 模板系统基础
        • 7.2 模板语言
      • chapter-08:表单系统

        • 8.2 使用表单系统实现表单: ModelForm
      • chapter-09:用户认证系统

        • 9.1 用户与身份认证
        • 9.2 权限管理
        • 9.3 用户认证系统应用
      • chapter-10:Django路由系统

        • 10.1 路由系统基础
      • chapter-11:Django中间件

        • 11.1 中间件基础
  • Python例子

    • Python: Linux的Shell命令
    • Python: PEP8自动格式化代码
    • Python: pip操作
    • Python: 业务服务监控
    • Python: 从文件逐行读取数据
    • 将链表转换为字符串
    • Python: 检查URL是否能正常访问
    • Python: 爬取网易云音乐
    • Python: 读取目录下的所有内容
    • 案例研究:文本统计
  • Python爬虫

    • 数据解析工具:Xpath
  • 算法题

    • 02:两数相加
    • 09:回文数
    • 13:罗马数值转换为整数
    • 14:最长公共前缀

6.3 基于类的通用视图

  • 6.3 基于类的通用视图
    • 6.3.1 用于渲染模板的TemplateView
      • Django查找Template的策略
        • 为什么建议使用TemplateView
        • 具体示例代码
    • 6.3.2 用于重定向的RedirectView
    • 6.3.3 用于展示Model列表的ListView
      • BaseListView
    • 6.3.4 展示Model详情的DetailView

6.3.1 用于渲染模板的TemplateView

  • 当视图中没有复杂的业务逻辑,如系统的引导页面,欢迎页面等,使用TemplateView是明智的选择
  • TemplateView的定义
    • class TemplateView(TemplateResponseMixin, ContextMixin, View)
  • ContextMixin:这个类中定义了一个方法:get_context_data。它返回一个字典对象,用于渲染模板上下文。通常,在使用TemplateView时都会重写这个方法,给模板提供上下文数据
  • TemplateResponseMixin:这个类中定义了两个重要的属性:template_name和render_to_response方法。其中:
    • template_name用于指定模板路径,它是必须要提供的
    • render_to_response方法根据模板路径和上下文数据(context)返回TemplateResponse

Django查找Template的策略

  • 项目的settings.py 文件可以找到TEMPLATES
# settings
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

  • APP_DIRS默认为True(搜索应用下的template目录);False:需要设置DIRS指定模板的位置
# settings.py
'DIRS': [os.path.join(BASE_DIR, 'templates')]
  • 当设置了DIRS和APP_DIRS=True,也会使用DIRS指定路径下模板文件
  • 例子:
    • “”是Django模板系统中引用变量的形式,在使用当前的模板时,context需要包含hello。另外,当前模板文件的完整路径是my_bbs/post/templates/post/index.html
    • 利用TemplateView实例对index.html的渲染
# views.html
from django.views.generic import TemplateView

class IndexView(TemplateView):
    template_name = 'post/index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['hello'] = 'Hello Django BBS post APP'
        return context

重写了get_context_data方法,并在上下文字典中加入了hello, 所以,index.html模板渲染的结果就是:Hello Django BBS。

最后,还需要给IndexView配置URL模式,在post/urls.py文件中添加路由指向

为什么建议使用TemplateView

为什么Django还要提供TemplateView这个通用视图呢?
类的特点是抽象,将共性抽离出来,再利用继承去实现特定的逻辑,可以在很大程度上实现代码复用。而这一点对于函数来说,是很难做到的。虽然可以使用装饰器给函数添加额外的功能,但是这也增加了代码实现的难度和复杂性。
对于通用视图来说,使用它们的优势是可以更加专注地实现业务逻辑,避免了两类样板式的代码。

第一类,对应HTTP请求类型的同名(小写)请求方法。例如,IndexView中并没有提供get方法,但是可以接受GET请求。

第二类,返回HttpResponse对象。同样,也没有在IndexView中返回任何响应,这也是在TemplateView中完成的。

TemplateView是Django提供的一个最简单的通用视图,用于展示给定的模板,但是,不应该在这里实现创建或更新对象的操作

具体示例代码

# settings.py
import os
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR), 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# post/urls.py
from django.urls import path
from post import views
urlpatterns = [
  path('index/', views.IndexView.as_view())
  # View的as_view方法给出视图类的可调用入口
]
# post/views.py
# 基于类的视图
from django.views.generic import TemplateView
class IndexView(TemplateView):
    # template_name = 'post/index.html'  # 除了指定template_name参数,还可以通过函数来获取模板的路径
    def get_template_names(self):
        return 'post/index.html'
    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['hello'] = 'Hello Django BBS templates for view'
        return context

# 不使用TemplateView,而使用视图函数的形式,也可实现相同的功能
def index_view(request):
    return render(request, 'post/index.html', context={'hello':'Hello Django BBS Template for class'})

6.3.2 用于重定向的RedirectView

重定向通用类视图:RedirectView(django/views/generic/base.py)文件中

RedirectView定义了四个类属性和两个方法

  • permanent:标识是否使用永久重定向,默认为False(302),True(301)

  • url:重定向的地址

  • pattern_name:重定向目标URL模式的名称(path中的name参数)

    • url和pattern_name至少需要提供一个
  • query_string:是否将查询字符串拼接到新地址中,默认False(丢弃原地址中的查询字符串)

  • 通常使用RedirectView实现重定向都会重写get_redirect_url方法,在其内部完成视图的业务逻辑,并返回重定向的地址 get_redirect_url

  • TemplateView和RedirectView在构建视图中相当有用,能将视图的功能表达的更为简单直接,隐藏了样式的重复代码

6.3.3 用于展示Model列表的ListView

  • 展示Model列表的视图在任何一个应用中都会存在,而且会出现多次
  • ListView的两个特性
    • 可以不提供模板名称,使用默认的规则
      • 例如Topic默认的模板名称为:post/topic_list.html
    • 提供了template_name,则会使用自定义的模板

BaseListView

  • BaseListView只是为GET请求类型定义了get方法,其中get_queryset、get_allow_empty和get_context_data都来自它的父类MultipleObjectMixin get_queryset

  • get_queryset():获取视图展示的Model列表,返回值必须是可迭代的对象,却可以是QuerySet

    • 如果提供的queryset是一个Model列表,那么,它并不包含model属性,因此,需要自定义模板名称
  • get_allow_empty():返回allow_empty属性,它是一个布尔值,默认是True,代表允许展示空的Model列表。如果设置为False,且Model列表为空,则会返回404

  • get_context_data():返回用于渲染模板的上下文数据

    • get_context_data
    • object_list参数即get_queryset方法的返回值,如果它有model属性,那么这个方法会返回model名称与list拼接得到的字符串(在没有设置context_object_name的情况下)。例如,对于Topic来说,这里的返回值就是topic_list

6.3.4 展示Model详情的DetailView

  • 定义了规则生成默认的模板名称:app_label/model_name_detail.html

  • 继承自:BaseDetailView

  • 重新实现Topic详情视图

# view.py
class TopicDetailView(DetailView):
    model = Topic
    def get_context_data(self, **kwargs):
        context = super(TopicDetailView,self).get_context_data(**kwargs)
        pk = self.kwargs.get(self.pk_url_kwarg)
        context.update({
            'comment_list': Comment.objects.filter(topic=pk)
        })
        return context
# urls.py
urlpatterns = [
    path('topic_views/<int:pk>/',views.TopicDetailView.as_view()),
]
<!-- topic_detail.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% block content %}
    <h2>Topic Detail</h2>
    <ul>
    <li>(id): {{ topic.id }}</li>
    <li>(title): {{ topic.title }}</li>
    <li>(content): {{ topic.content }}</li>
    <li>(user): {{ topic.user.username }}</li>
    <li>(created_time): {{ topic.created_time }}</li>
    <li>(last_modified): {{ topic.last_modified }}</li>
    <li>(评论):
        <table border="1">
            <tr>
                <th>评论id</th>
                <th>内容</th>
                <th>赞同</th>
                <th>返回</th>
            </tr>
            {% for comment in comment_list %}
                <tr>
                <td>{{ comment.id }}</td>
                <td>{{ comment.content }}</td>
                <td>{{ comment.up }}</td>
                <td>{{ comment.down }}</td>
                </tr>
            {% endfor %}
        </table>
    </li>
    </ul>
{% endblock %}
</body>
</html>
最近更新时间:
Prev
6.2 视图的高级特性和快捷方法