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:最长公共前缀

5.2 管理后台实现原理

  • 5.2 管理后台实现原理
    • 5.2.1 Python装饰器
      • 简单装饰器
      • 带参数的装饰器
    • 5.2.2 contenttypes应用分析
      • model_class
      • get_object_for_this_type
      • get_all_object_for_this_type

  • 使用管理后台需要:先注册
    • admin.site.register() 方法
    • @admin.register() 装饰器方法
  • 使用ModelAdmin自定义管理后台的样式和功能

5.2.1 Python装饰器

  • 考虑问题:如何打印函数的执行时间?

简单装饰器

  • 定义一个打印函数执行时间的装饰器 exec_time
import time
def exec_time(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        print('%ss elapsed for %s' % (time.time()-start, func.__name__))
        return res
    return wrapper

# exec_time:接受一个函数作为参数,且参数被wrapper包裹起来
# wrapper执行函数并打印时间,最后将wrapper返回
# wrapper函数的参数定义是(*args, **kwargs), 所以可以接受任意参数的调用
  • 装饰器:本质上是一个函数或类,他的返回值也是一个函数或类

  • 上面的方式,总体来说不够方便;下面,使用Python提供的语法 糖@,把装饰器放入到函数的定义处,并执行函数 语法糖

  • @语法糖,在使用装饰器会方便许多

  • 需要给函数添加额外的功能,可以不需要修改函数定义,也不需要修改函数的调用方式,这其实就是面向切面编程的效果

带参数的装饰器

  • 需要给装饰器传递参数,实际上需要写一个返回装饰器的函数
import time
def exec_time_with_name(name):
    def decorator(func):
        def wrapper(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)
            print('(%s): %ss elapsed for %s' % (name, time.time()-start, func.__name__))
            return res
        return wrapper
    return decorator

exec_time_with_name

  • 上面的例子,exec_time_with_name装饰器就是对之前简单装饰器的函数封装,使用时,需要传递一个参数name

  • 装饰器的其他问题:

    • 如在打印函数的属性时,打印它的__name__属性,会显示为 wrapper
  • 要解决上面的问题,需要使用Python内置的functools.wraps装饰器,作用:将原函数对象的属性复制到包装函数对象

  • 如重新定义exec_time_with_name装饰器

import time
import functools
def exec_time_with_name(name):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            start = time.time
            res = func(*args, **kwargs)
            print('(%s): %ss elapsed for %s' % (name, time.time()-start, func.__name__))
            return res
        return wrapper
    return decorator
  • 在此定义其他函数的属性,并打印__name__属性,会发现正常
  • 重新定义exec_time装饰器也可采用类似的方式
import time
import functools
def exec_time(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        print('%ss elapsed for %s' % (time.time()-start, func.__name__))
        return res
    return wrapper

使用装饰器的场景:

  • 打印日志,事务处理,权限校验等
  • 通过装饰器,可以将原本在函数中但又与函数功能本身无关的代码抽离出来,解耦的同事也提高代码的重用性
  • Django中的很多模块都使用了装饰器,如:注册Model的@admin.register

5.2.2 contenttypes应用分析

  • contenttypes是Django的内置应用,会记录项目中所有App和model的对应关系,并记录于ContentType中
  • ContentType的定义(django/contrib/contenttypes/models.py)
  • 创建Django项目的时候,INSTALLED_APPS就包含了contenttypes应用,经过数据库迁移后,生成了django_content_type表,并记录了Django内置应用的Model信息,加入新的Model,会自动地创建ContentType实例
  • 强大的功能:通过记录的信息动态地访问Model对象

model_class

  • 核心方法,获取当前ContentType实例所对应的Model对象
  • model_name是对大小写不敏感的(在获取Model对象的时候传递的是model_name.lower())

get_object_for_this_type

  • 通过传递关键字参数可以获取到Model实例对象
  • 先通过model_class方法获取到Model对象,在使用查询管理器get到匹配关键字参数的实例对象

get_all_object_for_this_type

  • 根据提供的关键字参数返回QuerySet,实现原理与get_object_for_this_type类似

  • ContentType自己提供了查询管理器 ContentTypeManager

  • ContentTypeManager 继承自 models.Manager,所以如get filter等方法都直接继承自父类

  • ContentTypeManager的两个重要方法

    • get_for_id方法
      • 通过id获取ContentType实例对象,先从缓存中获取,获取不到才会从数据表中检索
      • 通过id查询,尽量使用此方法
    • get_for_model方法
      • 通过传递的Model或Model实例获取对应的ContentType实例对象
最近更新时间:
Prev
5.1 将Model注册到管理后台