Django基础

MVC介绍:

MVC的全拼为Model-View-Controller, 最早由TrygveReenskaug在1978年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一-种软件设计模式,是为了将传统的输入(input) 、处理( processing)、输出(output)任务运用到图形化用户交互模型中而设计的。随着标准输入输入设备的出现,开发人员只需要将精力集中在业务逻辑的分析与实现上。后来被推荐为Oracle旗下Sun公司Java EE平台的设计模式,并且受到越来越多的使用ColdFusion和PHP的开发者的欢迎。现在虽然不再使用原来的分工方式,但是这种分工的思想被沿用下来,广泛应用于软件工程中,是一种典型并且应用广泛的软件架构模式。MVC结构提供了一种按功能对各种对象进行分割的方法(这些对象是用来维护和表现数据的),其目的是为了将各对象间的耦合程度减至最小。现在的MVC结构中,模型(Model)代表应用程序的数据(data) 和用于控制访问和修改这些数据的业务规则(businessrule)。通常模型被用来作为对现实世界中一个处理过程的软件近似,当定义-一个模型时,可以采用--般的简单的建模技术。当模型发生改变时,它会通知视(View) ,并且为视提供查询模型相关状态的能力。同时,它也为控制器(Controller)提供访问封装在模型内部的应用程序功能的能力。-一个视(View)用来组织模型的内容。它从模型那里获得数据并指定这些数据如何表现。当模型变化时,视负责维持数据表现的一- 致性。视同时将用户要求告知控制器(Controller) 。控制器(Controller) 定义了应用程序的行为;它负责对来自视的用户要求进行解释,并把这些要求映射成相应的行为,这些行为由模型负责实现,在独立运行的GUI客户端,用户要求可能是一些鼠标单击或是菜单选择操作。在一个WEB应用程序中,他们的表现形式可能是一些来自客户端的GET或POST的HTTP请求,模型所实现的行为包括处理业务和修改模型的状态。根据用户要求和模型行为的结果,控制器选择一个视作为对用户请求的应答,通常一组相关功能集对应一个控制器。

MVC框架的核心思想是:解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。

M全拼是Model,主要是封装对数据库层的访问,内嵌ORM框架,实现面向对象的编程来操作数据库,不用考虑数据库的差异性,简单配置就可以完成数据库切换。ORM是将python中的对象转化为关系型数据库操作,将关系型数据库中的行转化为python当中的对象。ORM不用程序员自己手写SQL语句。

V全拼是View,用于封装结果,内嵌了模板引擎,实现动态展示数据。

C全拼是Controller,用于接收GET或POST请求,处理业务逻辑,与Model和View交互,返回结果。

uploading.4e448015.gif转存失败重新上传取消

Django简介

    Django,是用python语言写的开源web开发框架,并遵循MVC设计,并且有一个专有名词:MVT。T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html,内嵌了模板引擎。

MVT

uploading.4e448015.gif转存失败重新上传取消

差异就在于图中的黑线部分:

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

    创建虚拟环境:mkvirtualenv django_env -p python3

                  pip install django==1.11.11

                  mkvirtualenv #创建虚拟环境

                  rmvirtualenv #删除虚拟环境

                  workon # 进入虚拟环境=

                  deactivate # 退出虚拟环境

                  #pip

                  pip install #安装依赖包

                  pip uninstall #卸载依赖包

                  pip list # 查看已安装的依赖包

             

 

创建一个工程

     生成一个django项目工程的使用方法:

            django-admin startproject 工程名称

       说明:在pycharm里的terminal里输入此命令

   工程目录的说明

                各文件的作用:

              settings-py是项目的整体配置文件

              uris.py是项目的URL配置文件

              wsgi.py是项目与WSGI兼容的Web服务器入口

              manage.py是项目管理文件。通过它管理项目

            创建子应用

                  python manage.py startapp 子应用名

                  说明:进入工程主目录里创建

                            各文件作用:

                                   __init__.py

admin.py文件跟网站的后台管理站点配置相关。

                                   apps.py配置文件用于配置当前子应用的相关信息。

                                   models.py 文件用户保存数据库模型类。

                                   views.py视图文件用于编写web应用视图。

                                   migrations目录用于存放数据库迁移历史文件。

项目目录中创建数据库:

运行生成迁移

迁移  

总结:

       进入桌面,防止权限问题cd Desktop

       进入虚拟环境:workon py_django

       创建项目文件:django-admin stratproject test1

       进入项目目录:cd test1

       创建应用:python manage.py startapp booktest

       安装应用

       虚拟环境:一个python项目运行所需要包含的集合。

  1. 使用模型
    1. 定义模型类
    2. 生成迁移,生成sql脚本:python manage.py makemigrattions
    3. 执行迁移,根据迁移文件创建表:python manage.py migrates  

数据操作:

    进入项目的shell,进行简单的API操作

    按ctrl+d或输入quit()可以退出shell

        1. 进入项目python manage.py shell
        2. from booktest.models import BookInfo
        3. BookInfo.objects.all()
        4. 添加

创建book=BookInfo()

           book.*** = ***

           book.save()

删除:book.delete()

查询:BookInfo.objects.all()

              BookInfo.object.get()

关系:根据图书对象找英雄对象book.heroinfo_set.all()

           根据英雄找图书:hero.book

    后台管理

  • 站点分为内容发布和公共访问两部分
  1. 内容发布的部分由网站的管理员负责查看、添加、修改、删除数据,开发这些重复的功能是- -件单调乏味、缺乏创造力的工作,为此,Django能够根据定义的模型类自动地生成管理模块

●使用Django的管理模块,需要按照如下步骤操作

。1.管理界面本地化

。2.创建管理员,

。3.注册模型类

。4.自定义管理页面

1.管理界面本地化

●本地化是将显示的语言、时间等使用本地的习惯,这里的本地化就是进行中国化,中国大陆地区使用简体中文,时区使用亚洲/上海时区,注意这里不使用北京时区表示

  • 打开test1/settings.py文件,找到语言编码、时区的设置项,将内容改为如下

LANGUAGE_CODE = ‘zh-Hans’

TIME_ZONE = ‘Asia/Shanghai’

       2、创建管理员

  1. 创建管理员的代码如下,按提示输入用户名、邮箱、密码

              python manage.py createsuperuser

uploading.4e448015.gif转存失败重新上传取消

  1. 启动服务器

python manage.py runserver

uploading.4e448015.gif转存失败重新上传取消

 

 

 

 

 

Web 应用程序处理流程

学习目标:

了解 web 框架

web 应用程序处理流程

Web 应用程序处理流程

uploading.4e448015.gif转存失败重新上传取消

Web 框架的意义

  • 用于搭建 Web 应用程序
  • 免去不同 Web 应用相同代码部分的重复编写,只需关心 Web 应用核心的业务逻辑实现

Web 应用程序的本质

  • 接收并解析 HTTP 请求 ,获取具体的请求信息
  • 处理本次 HTTP 请求 ,即完成本次请求的业务逻辑处理
  • 构造并返回处理结果 —— HTTP 响应

框架程序学习内容

  • 如何搭建工程程序
    • 工程的组建
    • 工程的配置
    • 路由定义
    • 视图函数定义
  • 如何获取请求数据(操作 request 对象)
  • 如何构造响应数据(构造 response 对象)
  • 如何使用中间层
  • 框架提供的其他功能组件的使用
    • 数据库
    • 模板
    • admin

总结:

  • web 框架的相关请求流程
  • 前端: 发送请求
  • 服务器: 接收请求
  • web 框架: 处理请求
  • 框架的意义: 减少重复造车轮, 减少重复性的步骤
  • 框架的本质是: 接收请求, 处理逻辑, 返回响应
  • django 学习的主要内容.
  • Python Web 框架要点
  • 1. Django介绍
  • 2. 1.工程搭建
    • 2.1. 环境安装
    • 2.2. 创建工程
    • 2.3. 使用 Pycharm 启动项目
    • 2.4. 创建子应用
    • 2.5. 创建视图
  • 3. 2.配置、静态文件与路由
    • 3.1. 配置文件
    • 3.2. 静态文件
    • 3.3. 路由说明
  • 4. 3.请求与响应
    • 4.1. 请求Request
    • 4.2. 响应Response
    • 4.3. Cookie
    • 4.4. Session
      • 4.4.1. Session配置和存储
      • 4.4.2. Session操作
  • 5. 4.类视图与中间件
    • 5.1. 类视图
      • 5.1.1. 定义类视图
      • 5.1.2. 类视图原理
      • 5.1.3. 类视图添加装饰器
      • 5.1.4. 类视图Mixin扩展类
    • 5.2. 中间件
  • 6. 5.模板
    • 6.1. Django自带模板
      • 6.1.1. 模板配置使用
      • 6.1.2. 模板基本语法
      • 6.1.3. 过滤器
      • 6.1.4. 模板继承
      • 6.1.5. 模板注释
    • 6.2. Jinja模板
    • 6.3. csrf攻击
  • 7. 6.数据库
    • 7.1. 配置
    • 7.2. 定义模型类
    • 7.3. 演示工具使用
    • 7.4. 数据库操作
      • 7.4.1. 增加
      • 7.4.2. 删除
      • 7.4.3. 修改
      • 7.4.4. 查询
        • 7.4.4.1. 过滤查询
        • 7.4.4.2. FQ对象
        • 7.4.4.3. 聚合查询
        • 7.4.4.4. 关联查询
    • 7.5. 查询集QuerySet
    • 7.6. 管理器Manager
  • 8. 7.Admin站点
    • 8.1. 使用Admin站点
    • 8.2. 调整列表页展示
    • 8.3. 调整编辑页展示
    • 8.4. 上传图片

环境安装

学习目标:

  • 搭建虚拟环境
  • Django 框架的安装
  • 常用命令的使用

创建虚拟环境

创建一个单独的虚拟环境, 搭建项目.

mkvirtualenv  django_env  -p  python3

  • mkvirtualenv : 创建一个新的虚拟环境
  • django_env : 创建的新虚拟环境名称, 这个名称可以随意制定, 自己能看懂即可
  • -p : 制定使用的python解释器版本
  • python3 : 我们这里使用 python3 的解释器.
  • 注意需要联网

安装 Django

使用 django 1.11.11 版本,注意需要联网

pip install django==1.11.11

  • pip : python 包管理器
  • install : 安装
  • django== 1.11.11 :

我们这里使用 django 1.11.11 这个版本, 现在最新的是 django 2.x 的版本, 但是因为是最新的, 企业使用的不是很多, 所以我们这里还是使用 1.x 版本.

虚拟环境相关命令 pip 相关命令

# 虚拟环境

mkvirtualenv  # 创建虚拟环境

rmvirtualenv  # 删除虚拟环境

workon  # 进入虚拟环境、查看所有虚拟环境

deactivate  # 退出虚拟环境

 

# pip

pip install  # 安装依赖包

pip uninstall  # 卸载依赖包

pip list  # 查看已安装的依赖库

总结:

  • 回顾创建虚拟环境的方式
  • 能够在虚拟环境中安装特定的 django 框架
  • 能够回想起虚拟环境的相关命令
  • 安装和卸载命令能够回想起来

 

创建工程

学习目标:

能够创建 Django 工程

能够了解 Django 工程中的目录结构

创建

创建工程的命令为:

# 生成一个 django 项目工程的使用方式:
 
django-admin startproject 工程名称
  • django-admin : django 生成项目工程的命令
  • startproject : 快速创建一个 django 项目, 使用这个命令可以快速下载一个项目模板, 在我们所在的目录
  • 工程名称 : 你想生成的项目名称, 这个名称可以随意定义

例如:

需求如下: 在桌面的 code 目录中, 创建一个名为 demo 的工程.

实现:

我们可以在桌面定义一个 code 目录, 在目录中,

创建一个名为 demo 的项目工程,可执行如下命令:

# 将目录切换到code: 
cd code
 
# 调用 django 项目生成命令,生成项目: 
django-admin startproject demo

执行后,code 目录中会多出一个新目录, 名为 demo,此即为新创建的工程目录。

这个新创建出来的目录,其实是我们下载的一个 django 开发模板, 我们可以在这个模板中进行 django 的开发.

工程目录说明

我们可以看到刚刚生成的项目目录结构为:

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

各个文件的作用:

  • 与项目同名的目录,此处为 demo。
  • settings.py 是项目的整体配置文件。
  • urls.py 是项目的 URL 配置文件。
  • wsgi.py 是项目与 WSGI 兼容的 Web 服务器入口。
  • manage.py 是项目管理文件,通过它管理项目。

总结:

  • 能够使用 django-admin startproject 工程名 的形式创建工程.
  • 能够对创建的项目结构有简单的认识.

使用开发服务器, 运行项目

学习目标:

能够使用对应的命令把当前项目运行起来

项目运行后, 能够利用浏览器查看

运行命令

在开发阶段,为了能够快速预览到开发的效果

django 提供了一个纯 python 编写的轻量级 web 服务器,仅在开发阶段使用。

# 命令格式:
 
python manage.py runserver

例如:

我们可以通过命令行进入刚刚创建的项目目录中:

# 进入创建的 demo 工程目录
cd demo

运行服务器命令如下:

# 调用如下命令, 就可以使我们的项目运行起来
# 默认运行在 127.0.0.1:8000  IP  端口上:
python manage.py runserver
 
 
# 我们也可以在刚刚的命令后面增加 IP:PORT 参数, 指定特定的 IP  端口号运行:
python manage.py runserver IP地址:端口

运行成功后命令行界面:

uploading.4e448015.gif转存失败重新上传取消

这里会看到一些红色的提示信息, 这些不是错误, 是提示我们有一些没有使用的迁移, 这里不用管它.

查看运行效果:

在浏览器中输入网址“ 127.0.0.1:8000 ”便可看到效果。

uploading.4e448015.gif转存失败重新上传取消

  • django 默认工作在调式 Debug 模式下,如果增加、修改、删除文件,服务器会自动重启。
  • 按 ctrl+c 停止服务器。

总结:

  • 能够使用 django 自带的简易服务器命令: python manage.py runserver来运行项目.
  • 能够通过访问 http:// 127.0.0.1 : 8000 来访问我们运行的项目
  • 能够将项目的虚拟环境配置好
  • 能够把 django 项目配置好, 并且运行起来
  • 首先, 需要在 manage.py 中点击右键, 启动一次
  • 然后选择右上角的编辑按钮, 在 manage.py 命令后面添加 runserver 参数
  • 再次运行当前项目, 利用 pycharm 把当前项目运行起来

创建子应用

学习目标:

创建子应用. 以及配置子应用

创建

我们可以在项目的根目录下, 调用命令行, 创建子应用:

# 创建子应用的常见命令: 
 
python manage.py startapp 子应用名称
  • python : python3 解释器
  • manage.py : 上一章创建项目工程的时候, 生成的管理整个项目的文件
  • startapp : 创建子应用的指令
  • 子应用名称 : 这个名称可以自己随意定, 一般会根据项目需求来指定.

例如:

在刚才创建的 demo 工程中,想要创建一个用户 users 子应用模块,可执行:

# 进入项目的根目录中: 
cd ~/Desktop/code/demo
 
# 执行生成子应用的指令, 生成一个叫users的子应用: 
python manage.py startapp users

执行后,可以看到工程目录中多出了一个名为 users 的子目录。

一般一个子应用代表一个模块, 例如: 购物车模块, 支付模块, 商品展示模块等...

子应用目录说明

查看此时的工程目录,结构如下:

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

生成的子应用中各个文件的作用:

  • admin.py 文件跟网站的后台管理站点配置相关。
  • apps.py 文件用于配置当前子应用的相关信息。
  • migrations 目录用于存放数据库迁移历史文件。
  • models.py 文件用户保存数据库模型类。
  • tests.py 文件用于开发测试用例,编写单元测试。
  • views.py 文件用于编写Web应用视图。

配置子应用

创建出来的子应用目录文件虽然被放到了工程项目目录中,但是 django 工程并不能立即直接使用该子应用,需要注册安装后才能使用。

settings 中默认的配置信息

settings 文件里, installed_apps 列表中工程默认配置的信息:

uploading.4e448015.gif转存失败重新上传取消

添加子应用到 settings

配置子应用信息也被称为: 注册安装一个子应用,

, 将子应用的配置信息文件 apps.py 中的 Config 类添加到 INSTALLED_APPS 列表中。

例如:

将刚创建的 users 子应用中 apps.py 文件的信息

( users.apps.UsersConfig ), 添加到 INSTALLED_APPS , 如图所示:

uploading.4e448015.gif转存失败重新上传取消

使当前总的项目知道我们新添加的模块(子应用). 这样方便项目工程调用.

总结:

  • 创建子应用的命令是: python manage.py startapp 子应用名称
  • 在公司开发过程中, 一个需求模块, 一般对应一个子应用, 例如: 购物车模块, 商品展示模块等.
  • 子应用的各个文件希望大家能够牢记:
    • apps ======= 配置当前子应用的相关信息
    • admin ======= 网站后台管理站点配置
    • migrations === 存放数据库迁移历史文件
    • models ====== 保存数据库模型类
    • tests ======== 开发测试用例, 编写单元测试
    • views ======= 编写web应用视图
  • 创建出来的子应用需要在项目工程的 settings.py 文件中进行配置,才可以使用,否则项目工程不知道添加的子应用模块.

创建视图

学习目标:

视图创建和运行

创建

打开刚创建的 users 模块,在 views.py 中编写视图代码。

#  django.http 模块中导入 HttpRespose
from django.http import HttpResponse
def index(request):
    """
    index视图
    :param request: 包含了请求信息的请求对象
    :return: 响应对象
    """
    return HttpResponse("hello the world!")

说明:

  • 视图函数的第一个传入参数必须定义,用于接收 Django 构造的包含了请求数据的 HttpReqeust 对象,通常名为 request
  • 视图函数的返回值必须为一个响应对象, 可以将要返回的字符串数据放到一个 HTTPResponse 对象中。

定义路由URL

1) 在子应用中新建一个 urls.py 文件保存该应用的路由

uploading.4e448015.gif转存失败重新上传取消

2) users / urls.py 文件中定义路由信息

#  urls 模块中导入 url
from django.conf.urls import url
 
# 从当前目录导入我们的视图模块 views
from . import views
 
# urlpatterns 是被 django 自动识别的路由列表变量
urlpatterns = [
    # 每个路由信息都需要使用 url 函数来构造
    # url (路径, 视图)
    url(r'^index/$', views.index),
]

3) 在工程总路由 demo / urls.py 中添加子应用的路由数据。

# 导入: 
from django.conf.urls import url, include
from django.contrib import admin
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),  # django默认就有的路由配置信息
 
    # 额外添加如下的路由配置信息: 
    url(r'^users/', include('users.urls')), 
]
  • 使用 include 来将子应用 users 里的路由文件( urls.py )包含到工程总路由中
  • r'^users/' 决定了 users 子应用的所有路由都以 /users/ 开头,如我们刚定义的视图 index, 其最终的完整访问路径为 /users/index/

include 函数除了可以传递字符串之外,也可以直接传递应用的 urls 块,如

from django.conf.urls import url, include
from django.contrib import admin
import users.urls  # 先导入应用的urls模块
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # url(r'^users/', include('users.urls')),
    url(r'^users/', include(users.urls)),  # 添加应用的路由
]

4) 启动运行

重新启动 django 程序

python manage.py runserver

在浏览器中输入网址127.0.0.1:8000/users/index/ 可看到返回的信息

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 视图就是函数, 写在 views.py 文件中
  • 视图函数必须有 request 参数
  • 视图也必须要返回一个 HttpResponse( ) 对象
  • 访问视图需要使用路由
  • 总路由一般定义在 urls.py 中
  • 子路由一般定义在子应用中: users / urls.py

配置文件

学习目标:

了解配置文件 settings.py

能够认识配置文件中的 BASE_DIR, DEBUG, 语言等选项

BASE_DIR

指当前工程的根目录Django 会依此来定位工程内的相关文件,我们也可以使用该参数来构造文件路径。

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

  • ___file___ : 可以理解为当前的文件
  • os.path.abspath ( 文件 ) : 获取这个文件的绝对路径
  • os.path.dirname( 路径 ) : 获取这个路径的上一级路径, 例如:
    • path1 = os.path.dirname( 'c://home/setttings.py' )
    • 那么获取的结果为: path1 = 'c://home'
  • os.path.dirname ( 路径 ) : 再次获取这个路径的下一级路径.
  • 这样获取到的 BASE_DIR 其实就是当前项目的根目录.

DEBUG

设置是否为调试模式,创建工程后初始值为 True ,即默认工作在调试模式下。

作用:

  • Django程序出现异常时,向前端显示详细的错误追踪信息

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

注意:部署线上运行的 Django 不要运行在调式模式下,记得修改 DEBUG=False

如果为非调试模式:

程序出错后, 浏览器仅显示 500 的错误代码, 不会显示具体的错误信息:

uploading.4e448015.gif转存失败重新上传取消

本地语言与时区

初始化的工程默认语言和时区为英语和 UTC 标准时区

LANGUAGE_CODE = 'en-us'  # 语言

TIME_ZONE = 'UTC'  # 时区

可以将语言和时区修改为中国大陆信息:

LANGUAGE_CODE = 'zh-hans'  # 中文

TIME_ZONE = 'Asia/Shanghai' # 亚洲上海时区

uploading.4e448015.gif转存失败重新上传取消

总结:

  • django 中 settings.py 是整个项目的配置文件.
  • BASE_DIR 指的是项目的绝对路径
  • 一般在开发时, 我们都会使用 DEBUG 模式, 默认为 True (开启)

静态文件

学习目标:

了解什么是静态文件

知道如何配置静态文件加载路径

静态文件定义与配置

我们一般会把项目中前端写的 CSS、图片、js 以及 html 等看做静态文件

静态文件我们会放在一个静态文件夹, 统一管理

我们在 html 页面中调用时,需要指定静态文件的路径,故, Django 中提供了一种用于配置静态文件路径的解析方式。

静态文件可以放在项目根目录下,也可以放在应用的目录下,由于有些静态文件在项目中是通用的,所以推荐放在项目的根目录下,方便管理。

为了提供静态文件访问路径,我们需要在项目的 settings.py 文件中配置两个参数:

  • STATICFILES_DIRS : 存放查找静态文件的目录
  • STATIC_URL : 访问静态文件的 URL 前缀

例如:

1 在项目根目录下创建 static_files 目录来保存静态文件。

如图:

uploading.4e448015.gif转存失败重新上传取消

2 demo / settings.py 中修改静态文件的两个参数为

# 这个参数默认存在
STATIC_URL = '/static/'
 
# 我们可以添加这个参数, 用于补全静态文件路径
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static_files'),
]

3)此时在 static_files 添加的任何静态文件都可以使用网址 /static/ 文件在 static_files 中的路径 来访问了。

例如

我们向 static_files 目录中添加一个 index.html 文件,在浏览器中就可以使用127.0.0.1:8000/static/index.html 来访问:

uploading.4e448015.gif转存失败重新上传取消

或者我们在 static_files 目录中添加了一个子目录和文件 goods/detail.html,在浏览器中就可以使用127.0.0.1:8000/static/goods/detail.html 来访问。

注意:

Django 仅在调试模式下(DEBUG=True)能对外提供静态文件。

DEBUG=False工作在生产模式时,Django不再对外提供静态文件,需要是用collectstatic命令来收集静态文件并交由其他静态文件服务器来提供。(详细在部署时会讲)

总结:

  • 了解前端访问静态文件所使用的路由, 即 STATIC_URL 配置项的内容
  • 前端访问路由后, django 项目需要按照 STATICFILES_DIRS 中的路径进行寻找
  • 找到对应的静态文件夹后, 在文件夹中, 查找对应的静态文件.

路由说明

学习目标:

路由的定义和使用

什么是路由?

url 的了解:

# 第一种写法:

http://www.itcast.cn:80/users/index/?a=1&b=2&c=3#box

 

# 第二种写法:

http://192.168.238.128:80/users/index/?a=1&b=2&c=3#box

其中:

http:// 代表使用的协议

www.itcast.cn 指的是访问的域名

80 指的是调用的端口

/users/index/ 指的是路由部分

?a=1&b=2&c=3 指的是查询字符串

#box 指的是锚点

uploading.4e448015.gif转存失败重新上传取消

路由定义位置

Django 的主要路由信息定义在工程同名目录下的 urls.py 文件中,该文件是 Django 解析路由的入口。

每个子应用为了保持相对独立,可以在各个子应用中定义属于自己的 urls.py 来保存该应用的路由。然后用主路由文件包含各应用的子路由数据。

除了上述方式外,也可将工程的全部路由信息都定义在主路由文件中,子应用不再设置 urls.py。如:

from django.conf.urls import url

from django.contrib import admin

import users.views

 

urlpatterns = [

    url(r'^admin/', admin.site.urls),

    url(r'^users/index/$', users.views.index)

]

路由解析顺序

Django 在接收到一个请求时,从主路由文件中的 urlpatterns 列表中以由上至下的顺序查找对应路由规则,如果发现规则为 include 包含,则再进入被包含的 urls 中的 urlpatterns 列表由上至下进行查询。

值得关注的由上至下的顺序,有可能会使上面的路由屏蔽掉下面的路由,带来非预期结果。例如:

urlpatterns = [

    url(r'^say', views.say),

    url(r'^sayhello', views.sayhello),

]

即使访问 sayhello/ 路径,预期应该进入 sayhello 视图执行,但实际优先查找到了 say 路由规则也与 sayhello/ 路径匹配,实际进入了 say 视图执行。

提示:需要注意定义路由的顺序,避免出现屏蔽效应。

两种解决方法:

第一种:

  1. 调整书写顺序

from django.conf.urls import url

 

from . import views

 

urlpatterns = [

    # 1. 调整书写顺序

    url(r'^sayhello', views.sayhello),

    url(r'^say', views.say)

]

第二种:

2.调整正则书写方式:

from django.conf.urls import url

 

from . import views

 

urlpatterns = [

    # 2.调整正则:

    url(r'^say/$', views.say),

    url(r'^sayhello/$', views.sayhello)

]

总结:

  • 路由分为两种: 子路由 和 总路由
  • 如果两个路由都有, 则先匹配总路由, 然后匹配子路由
  • 两个路由都匹配成功, 则加载对应的视图函数
  • 子路由定义在 子应用/urls.py 文件中 , 总路由定义在 同名文件夹的 urls.py 文件中

路由命名

学习目标:

掌握 总路由与子路由的 命名方法

了解总路由与子路由命名的区别

路由命名

在定义路由的时候,可以为路由命名,方便查找特定视图的具体路径信息。

1) 在使用 include 函数定义路由时,可以使用 namespace 参数定义路由的命名空间,如

url(r'^users/', include('users.urls', namespace='users')),

命名空间表示,凡是 users.urls 中定义的路由,均属于 namespace 指明的 users 名下。

命名空间的作用:避免不同应用中的路由使用了相同的名字发生冲突,使用命名空间区别开。

2) 在定义普通路由时,可以使用 name 参数指明路由的名字,如

urlpatterns = [

    url(r'^index/$', views.index, name='index'),

    url(r'^say', views.say, name='say'),

]

总结:

  • 给总路由添加命名: include('子应用.urls', namespace="名称" )
  • 给子路由添加命名: url('正则', 视图函数, name="名称")
  • 总路由与子路由的命名区别: 添加的位置不同, 调用的属性不同: 一个是namespace, 一个是name

Reverse 反解析

学习目标:

知道 reverse 函数的用法, 能够通过 reverse 获取对应的路径

reverse 反解析

使用 reverse 函数,可以根据路由名称,返回具体的路径,如:

from django.urls import reverse  # 注意导包路径

 

def index(request):

    url = reverse('usersnamespace:say') 

    print(url)   # 返回 /users/say

    return HttpResponse("hello the world!")

 

def say(request):

    return HttpResponse('say')

  • 对于未指明 namespace 的,reverse ( 路由 name )

url = reverse(‘index’)

  • 对于指明 namespace 的,reverse ( 命名空间 namespace : 路由name )

url = reverse('usersnamespace:say') 

路径结尾斜线 / 的说明

Django 中定义路由时,通常以斜线 / 结尾,其好处是用户访问不以斜线 / 结尾的相同路径时,Django 会把用户重定向到以斜线 / 结尾的路径上,而不会返回 404 不存在。如

urlpatterns = [

    url(r'^index/$', views.index, name='index'),

]

用户访问 index 或者 index/ 网址,均能访问到 index 视图。

说明:

虽然路由结尾带 / 能带来上述好处,但是却违背了 HTTP URL 表示资源位置路径的设计理念。

是否结尾带 / 以所属公司定义风格为准。

总结:

  • reverse 函数的主要作用是: 在视图中获取某一个视图函数的完整路由
  • reverse 完成用法: reverse( '总路由名称 : 子路由名称' )
  • reverse 函数的另一种用法: reverse( '子路由名称' )
  • 路径中的 / 代表路径分隔符, 一般我们发请求时最好携带.
  • 如果发请求时, 没有在最后携带 / , 则浏览器会帮我们进行一次重定向, 再次访问携带 / 的路径

请求对象

Django 中的 QueryDict 对象

学习目标:

能够了解 Django 中的 QueryDict 对象

知道 QueryDict 对象的两个调用函数

QueryDict 对象

QueryDict 对象是 django 中一种特殊类型的字典

里面可以存储 一对一类型的数据, 也可以存储 一对多类型的数据

这个对象一般用来存储浏览器传递过来的参数

我们可以默认把他看成是一个字典

但是它和一般的字典的不同之处在于:

获取 QueryDict 中的数据:

  • 一键 ===> 一值: QueryDict 这个字典可以调用 get( ) 函数来获取.
  • 一键 ===> 多值: QueryDict 这个字典的获取方法:
    • 如果获取一个值: QueryDict.get( key ) 获取的是所有值的最后一个.
    • 如果获取多个值: QueryDict.getlist( key ) 获取这个键对应的所有值, 存放在列表中返回.

例如:

  • get( )

根据一个 key 获取一个值

如果一个键同时拥有多个值将获取最后一个值

  # 使用格式: 
  QueryDict.get('')
  # 或可写为: 
  QueryDict['']
 
  # 例如
  QueryDict.get('a'# 获取 a 所对应的一个值.
  • getlist( )

根据一个 key 获取多个值

根据键获取对应的值,值以列表返回

可以获取指定键的所有值, 如果键不存在则返回空列表 [ ]

  # 使用格式: 
  QueryDict.getlist('')
 
  # 例如
  QueryDict.getlist('a'# 获取 a 所对应的所有值.

总结:

  • 能够了解 Django 中的 QueryDict 对象
  • 知道 QueryDict 对象的两个调用函数
    • get( key ) 获取对应 key 的一个 value 值
    • getlist( key ) 获取对应 key 的多个 value 值, 以列表的形式返回

前端传参的四种方式

查询字符串传参 ( QueryString )

学习目标:

知道什么是查询字符串

能够获取查询字符串传递的参数

什么是查询字符串?

简单理解:

url : http://www.itcast.cn:80/users/index/?a=1&b=2&c=3#id=123

url 地址中以 ? 开始,直到 # 结束的部分, 我们统称为: 查询字符串( QueryString )

获取请求路径中的查询字符串参数(形如 ?k1=v1&k2=v2

获取查询字符串传递的参数

可以通过 request.GET 属性获取,这个方法返回 QueryDict 对象。

// 前端发送请求: 
$.ajax({
    url:'http://127.0.0.1:8000/reqresp/qs/?a=1&b=2&a=3',
    type:'get',
    dataType:'json'
})
.done(function(data){
    console.log(data)     // 打印: OK
})
.fail(function(error){
    console.log(error)
})
# python 部分接收发送的参数并打印: 
# 视图函数
def qs(request):
    # 获取查询字符串参数
    a = request.GET.get('a')
    b = request.GET.get('b')
    alist = request.GET.getlist('a')
    # 打印
    print(a)  # 3
    print(b)  # 2
    print(alist)  # ['1', '3']
    # 返回响应对象
    return HttpResponse('OK')

重要:

查询字符串不区分请求方式,即假使客户端进行 POST 方式的请求,要关闭CSRF后,依然可以通过 request.GET 获取请求中的查询字符串数据。

注意:

  • 这里的 request.GET 指的不是发送 ajax 用的 get 方法, 而是指从 url 的查询字符串中获取参数
  • 同理: request.POST 指的也不是 ajax 用的 post 方法,而是我们从请求体中获取的参数
  • 通过上面大家就能明白: GET 和 POST 这里指的都是获取参数的位置, 而不是我们以前说的 get 请求和 post 请求.

总结:

  • 如果前端传的参数是字符串类型, 可以通过 request.GET 来获取
  • 通过 request.GET 获取的是 QueryDict 类型
  • 我们可以通过 QueryDict 的 get( ) 和 getlist( ) 方法来获取对应的数据.

路径传参

学习目标:

了解路径传参的方式和获取方法

通过 URL 路径传参

在定义路由 URL 时,可以使用正则表达式提取参数的方法从 URL 中获取请求参数,Django 会将提取的参数直接传递到视图的传入参数中。

  • 未命名参数按定义顺序传递,
  •     url(r'^weather/([a-z]+)/(\d{4})/$', views.weather),
  •  
  •     def weather(request, city, year):
  •         print('city=%s' % city)
  •         print('year=%s' % year)
  •         return HttpResponse('OK')
  • 命名参数按名字传递,如
  •     url(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),
  •  
  •     def weather(request, year, city):
  •         print('city=%s' % city)
  •         print('year=%s' % year)
  •         return HttpResponse('OK')

总结:

  • 路径传参是前端发送参数的一种常用形式
  • 把参数伪装成路径, 传递到后端
  • 路径传参会在路径匹配的时候进行正则校验
  • 路径传参分为未命名参数和命名参数
  • 命名参数就是分别给参数起一个名字
  • 未命名参数就是不给参数起名字

请求体传参

学习目标:

了解表单类型传参的获取方法

能够通过对应的方法, 获取表单传递过来的参数

准备工作:

请求体数据格式不固定,可以是表单类型字符串,可以是 JSON 字符串,可以是 XML 字符串,应区别对待。可以发送请求体数据的请求方式有 POSTPUTPATCHDELETE

Django 默认开启了 CSRF 防护,会对上述请求方式进行 CSRF 防护验证,在测试时可以关闭 CSRF 防护机制,方法为在 settings.py 文件中注释掉 CSRF 中间件,如:

uploading.4e448015.gif转存失败重新上传取消

注释掉后,我们可以进行下面方法的验证, 否则不能成功.

表单类型类型参数 ( Form Data )

前端发送的表单类型的请求体数据,可以通过 request.POST 属性获取,返回 QueryDict 对象。

我们又知道: QueryDict 对象类似于一个字典, 所以我们可以通过 get( ) 来获取 key 值所对应的 value

def get_body(request):
    # 获取表单参数
    a = request.POST.get('a')
    b = request.POST.get('b')
    alist = request.POST.getlist('a')
    # 打印
    print(a)
    print(b)
    print(alist)
    # 返回
    return HttpResponse('OK')

例如:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 能够通过 request.POST 获取表单参数
  • 通过 request.POST 获取的值为 QueryDict 类型
  • 我们可以通过 QueryDict 的 get( ) 和 getlist( ) 函数, 获取数据

非表单类型传值 ( Non-Form Data )

学习目标:

了解非表单类型数据的获取方式

能够获取非表单类型数据

非表单类型传值的方式:

非表单类型的请求体数据,Django 无法自动解析

可以通过 request.body 属性获取最原始的请求体数据,自己按照请求体格式( JSONXML 等)进行解析。

其中: request.body 返回 bytes 类型。

# 获取方式: 
request.body   # 得到的是 bytes 类型数据
 
# 可以通过 decode() 函数:  bytes 转为 str
request.body.decode()

例如:

要获取请求体中的如下 JSON 数据

{"a": 1, "b": 2}

可以进行如下方法操作:

import json
 
def get_body_json(request):
    # 获取 json 类型数据: 
    json_bytes = request.body
    #  bytes 类型转为 str
    json_str = json_bytes.decode()
 
    # python3.6 及以上版本中, json.loads() 方法可以接收 str  bytes 类型
        #但是 python3.5 以及以下版本中, json.loads() 方法只能接收 str, 所以我们的版本如果是
        # 3.5 需要有上面的编码步骤.
 
    req_data = json.loads(json_str)
    print(req_data['a'])
    print(req_data['b'])
    return HttpResponse('OK')

演示效果:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 如果前端传递的是 json 类型的数据, 可以通过 request.body 类获取
  • 获取到的数据是 bytes 类型, 所以我们需要将其解码为 str 类型
  • 另外, 转为 str 后, 如果需要转为 dict, 则需要调用 json.loads( ) 函数

请求对象中的请求头信息

学习目标:

了解获取请求头信息的方法

获取请求头数据

可以通过 request.META 属性获取请求头中的数据 request.META 为字典类型

这里需要注意一点是: 我们平常见到的请求头是这样的:

POST /reqresp/req/ HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: dd531a45-7518-1e8f-63a5-be03ed593471
 
a=1&b=2&a=3

但是我们通过 request.META 获取的时候,需要使用如下所示的用法:

  • CONTENT_LENGTH – The length of the request body (as a string).
  • CONTENT_TYPE – The MIME type of the request body.
  • HTTP_ACCEPT – Acceptable content types for the response.
  • HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
  • HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
  • HTTP_HOST – The HTTP Host header sent by the client.
  • HTTP_REFERER – The referring page, if any.
  • HTTP_USER_AGENT – The client’s user-agent string.
  • QUERY_STRING – The query string, as a single (unparsed) string.
  • REMOTE_ADDR – The IP address of the client.
  • REMOTE_HOST – The hostname of the client.
  • REMOTE_USER – The user authenticated by the Web server, if any.
  • REQUEST_METHOD – A string such as "GET" or "POST".
  • SERVER_NAME – The hostname of the server.
  • SERVER_PORT – The port of the server (as a string).

具体使用如:

def get_headers(request):
    # 使用字典的方式获取请求头内部的数据
    print(request.META['CONTENT_TYPE'])
    # 返回
    return HttpResponse('OK')

演示:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 通过 request.META 属性我们可以获取请求对象的所有请求头信息
  • request.META 是一个字典
  • 从 request.META 中获取数据时, key 值需要大写

请求头对象中的其他信息

学习目标:

了解请求头对象 ( request ) 中的其他信息

其他信息

  • method:一个字符串,表示请求使用的 HTTP 方法,常用值包括:'GET'、'POST'。
  • user:请求的用户对象。
  • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
  • encoding:一个字符串,表示提交的数据的编码方式。
    • 如果为 None 则表示使用浏览器的默认设置,一般为 utf-8。
    • 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的 encoding 值。
  • FILES:一个类似于字典的对象,包含所有的上传文件。

演示:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 知道 request 对象中的 method 代表前端发送的请求方法
  • user 代表前端发送请求的用户
    • 如果是未登录用户: user 为 匿名用户
    • 如果是登录用户: user 为 登录用户
  • path 代表前端请求的路径
  • encoding 代表前端发送的请求中使用的编码方式

响应

HttpResponse

学习目标:

知道 HttpResponse 生成对象的三个参数

导入方式:

# 可以从 django.http 里面导入 HttpResponse
from django.http import HttpResponse

定义形式:

定义格式: 
 
HttpResponse(
    content=响应体, 
    content_type=响应体数据类型, 
    status=状态码
)

通过上式我们知道 HttpResponse 里面有对应的一些参数可以修改:

  • content:表示返回的内容。
  • status_code:返回的 HTTP 响应状态码。
  • content_type:指定返回数据的的 MIME 类型。

例如:

# 定义一个新的视图函数
def demo_response(request):
 
      # 返回一个 HttpResponse 响应对象
      return HttpResponse('{"name": "python"}', 
                          content_type="application/json", 
                          status=400)

效果演示:

uploading.4e448015.gif转存失败重新上传取消

我们会看到响应的内容我们已经获取了, 而且返回回来的状态码也是有的.

特别的使用方式:

我们如果需要在响应头添加自定义的键值对内容,

可以把 HttpResponse 对象当做字典进行响应头键值对的设置:

# 创建一个 response 对象
response = HttpResponse()
 
# 在对象中添加一个新的 键值对
response['Itcast'] = 'Python'

示例:

from django.http import HttpResponse
 
# 常规用法: 
def demo_view(request):
    return HttpResponse('itcast python', status=400)
 
# 或者想这样使用: 
def demo_view(request):
    # 创建一个 response 对象
    response = HttpResponse('itcast python', status=400)
 
    #  response 对象中添加一个新的键值对
    response['Itcast'] = 'Python'
 
    # 返回 response  
    return response

演示效果:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • Django 规定每个视图‘函数, 必须返回一个 HttpResponse( ) 对象
  • HttpResponse 可以从 django.http 中导入
  • HttpResponse 中有三个参数, 分别为 content(内容), content_type(内容类型), status_code(状态码)

 

HttpResponse 的子类

学习目标:

了解 Django HttpResponse 类的子类

知道 HttpResponse 子类的调用形式

HttpResponse 子类

Django 提供了一系列 HttpResponse 的子类,可以快速设置状态码

这个状态码可以从 Django.http 里面导入,例如:

# 导入方式:
from django.http import HttpResponseNotFound

子类有:

  • HttpResponseRedirect 301
  • HttpResponsePermanentRedirect 302
  • HttpResponseNotModified 304
  • HttpResponseBadRequest 400
  • HttpResponseNotFound 404
  • HttpResponseForbidden 403
  • HttpResponseNotAllowed 405
  • HttpResponseGone 410
  • HttpResponseServerError 500

使用的演示:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 有时候, 在写视图的时候, 我们会返回 HttpResponse 的子类的对象, 而不是 HttpResponse( ) 对象
  • HttpResponse 的子类很多, 我们可以酌情使用

JsonResponse

学习目标:

了解 JsonResponse 的调用方法和功能

JsonResponse

如果我们要返回 json 字符串, 那么我们可以使用 JsonResponse 来帮助我们快速的构建 json 字符串,进行返回.

JsonResponse 能够帮助我们自动把字典转成 json 字符串类型, 并且还不用自己设置响应头中 contentType 字段

所以总结一下, JsonResponse 能够帮助我们做到如下两点:

  • 帮助我们将数据转换为 json 字符串
  • 设置响应头 Content-Typeapplication/json

使用:

# 导入 JsonResponse
from django.http import JsonResponse
 
def demo_view(request):
        # 直接返回 JsonResponse 这个对象,并且里面可以直接传入参数
    return JsonResponse({'city': 'beijing', 'subject': 'python'})

显示效果:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • JsonResponse 能够帮助我们将字典快速的转为 Json.
  • 很多时候前端需要我们给他返回 Json 格式的数据. 所以我们就可以使用当前的 JsonResponse 类.

redirect 重定向

学习目标:

了解 redirect 函数的使用方法和作用

redirect

# 使用格式: 
 
redirect('想要跳转的路径')

例如:

from django.shortcuts import redirect
 
def demo_view1(request):
    # 第一种用法: 直接在 redirect 函数中添加路由字符串
    return redirect('/users/index/')
 
def demo_view2(request):
    # 第二种用法:  reverse  redirect 搭配使用
    url = reverse('users:index')
    return redirect(url)

演示效果:

uploading.4e448015.gif转存失败重新上传取消

说明:

  • 建议 redirect (重定向) 和我们前面学习的 reverse 搭配使用.
  • 尽量不要把路由写死. 有利于我们更改开发代码.

总结:

  • 能够正确使用 redirect 函数
  • 能够把 redirect 函数 和 reverse 函数, 搭配使用
  • 重定向就是指的重新跳转的意思

Cookie

学习目标:

掌握 Cookie 的定义和使用

Cookie 定义

Cookie,有时也用其复数形式 Cookies,指的是由服务端生成, 保存在客户端的一种数据存储形式, 内部以 key/value 键值对形式存储. 一般不存储敏感信息. 内容有时会被加密.

背景:

Cookie 最早是网景公司的前雇员 Lou Montulli 1993 3 月的发明。Cookie 是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将 Cookie key/value 保存到某个目录下的文本文件内,下次请求同一网站时就发送该 Cookie 给服务器(前提是浏览器设置为启用 cookie )。Cookie 名称和值可以由服务器端开发自己定义,这样服务器可以知道该用户是否是合法用户以及是否需要重新登录等。服务器可以利用 Cookies 包含信息的任意性来筛选并经常性维护这些信息,以判断在 HTTP 传输中的状态。Cookies 最典型记住用户名

建议:

Cookie 是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息如密码,因为电脑上的浏览器可能被其它人使用

Cookie 的特点

  • Cookie 以键值对 Key-Value 形势进行信息的存储
  • Cookie 基于域名安全,不同域名的 Cookie 是不能互相访问的

设置 Cookie

可以通过 HttpResponse 对象中的 set_cookie 方法来设置 cookie

# 使用方法:

 

# 创建 response 对象

response = HttpResponse()

 

# 调用对象的 set_cookie() 函数

response.set_cookie(key,  value,  max_age)

参数解析:

key: cookie 中保存信息的名称

value: cookie 中保存信息时, 名称对应的值部分

max_age: cookie 中保存信息的有效期, 超过有效期, key-value 失效

其中 max_age 单位为秒, 默认为 None. 如果设置 None , 则关闭浏览器失效.

例如:

response.set_cookie('itcast', 'python', max_age=3600)

读取 Cookie

可以通过 HttpRequest 对象( request ) COOKIES 属性来读取本次请求携带的 cookie 值。

 

# 使用方法:

# 其中: request.COOKIES 为字典类型

 

value = request.COOKIES.get('key')

request.COOKIES 为字典类型, 可以使用字典的 get( )

例如:

value = request.COOKIES.get('itcast')    # python

总结:

  • cookie 用于保持前后端状态
  • cookie 的设置为: response.set_cookie( key, value, max_age=时间(s))
  • cookie 的获取: request.COOKIES.get( key )

Session

学习目标:

了解和知道 session 的作用和特点

Session 了解

Session 是一种会话控制方式. 由服务端创建, 并且保存在服务端的数据存储形式. 内部以 key/value 键值对的形式存储. 可以存储敏感信息, 内容有些会被加密. 一般生成 session , 我们会把 sessionid 传递给 cookie 保存.

Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。

当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户信息。

Session 的作用

  • 在服务器上保存用户状态信息, 以供前端页面访问
  • 因为数据保存在服务器端, 所以可以保存敏感信息. 每次前端发送请求, 可以随时获取对应的信息. 保持会话状态

Session 的特点

  • 依赖 cookies
  • 存储敏感、重要的信息
  • 支持更多字节
  • Session 共享问题

总结:

  • session 可以保持会话状态
  • session 可以存储敏感信息
  • session 依赖 cookie

Session 配置和存储

学习目标:

知道和了解 session 的配置和存储

启用 Session

Django 项目默认启用 Session

可以在 settings.py 文件中查看,如图所示

uploading.4e448015.gif转存失败重新上传取消

如需禁用 session,将上图中的 session 中间件注释掉即可。

存储方式

settings.py 文件中,可以设置 session 数据的存储方式,可以保存在数据库、本地缓存等。

数据库

默认存储方式

存储在数据库中,如下设置可以写,也可以不写

SESSION_ENGINE='django.contrib.sessions.backends.db'

如果存储在数据库中,需要在项 INSTALLED_APPS 中安装 Session 应用。

uploading.4e448015.gif转存失败重新上传取消

数据库中的表如图所示

uploading.4e448015.gif转存失败重新上传取消

表结构如下

uploading.4e448015.gif转存失败重新上传取消

由表结构可知,操作 Session 包括三个数据:键,值,过期时间。

本地缓存

存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。

SESSION_ENGINE='django.contrib.sessions.backends.cache'

混合存储

优先从本机内存中存取,如果没有则从数据库中存取。

SESSION_ENGINE='django.contrib.sessions.backends.cached_db'

Redis

redis 中保存 session,需要引入第三方扩展,我们可以使用 django-redis 来解决。

1 安装扩展

pip install django-redis

2)配置

settings.py 文件中做如下设置

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

注意

如果 redis ip 地址不是本地回环 127.0.0.1 而是其他地址,访问 Django 时,可能出现 Redis 连接错误,如下:

uploading.4e448015.gif转存失败重新上传取消

解决方法:

修改 redis 的配置文件,添加特定 ip 地址。

打开 redis 的配置文件

sudo vim /etc/redis/redis.conf

在如下配置项进行修改(如要添加 10.211.55.5 地址)

uploading.4e448015.gif转存失败重新上传取消

重新启动 redis 服务

sudo service redis-server restart

总结:

  • session 存储在后端
  • 可以存储在 数据库, 本地内存, 混合存储, 甚至 redis 中.
  • 存储在 redis 需要安装 django-redis 扩展类
  • 还需要在 settings.py 文件中添加设置.
  • 修改 redis 的配置文件 redis.conf, 修改 bind 属性.

Session 相关操作

学习目标:

掌握 session 的储存和读取操作

Session 操作

通过 HttpRequest 对象( request ) session 属性进行会话的读写操作。

1)往 session 中写入键值对:

# 使用格式:

 

request.session[''] =

2)根据 key 读取 session 中的数据:

# 使用格式:

 

value = request.session.get('',默认值)

3)清除所有 session,在存储中删除值部分:

# 使用格式:

 

request.session.clear()

4)清除 session 数据,在存储中删除 session 的整条数据:

# 使用格式:

 

request.session.flush()

5)删除 session 中的指定键及值,在存储中只删除某个键及对应的值。

# 使用格式:

 

del request.session['']

6)设置 session 的有效期

# 使用格式:

 

request.session.set_expiry(value)

  • 如果 value 是一个整数,session 将在 value 秒没有活动后过期。
  • 如果 value 为 0,那么用户 session 的 Cookie 将在用户的浏览器关闭时过期。
  • 如果 value 为 None,那么 session 有效期将采用系统默认值,默认为两周,可以通过在 settings.py 中设置 SESSION_COOKIE_AGE 来设置全局默认值。

总结:

  • 往 session 中存储或者读取数据使用的对象都是 request
  • 存储时调用的格式是: ```request.session['key'] = 'value'```
  • 获取 session 中的数据格式是: ```value = request.session['key']```
  • 删除使用的格式: del request.session['key']
  • 设置有效期使用的格式: ```request.session.set_expiry( value )```

类视图

学习目标:

知道什么是类视图

能够调用类视图

类视图引入

Django , 以函数的方式定义的视图称为 函数视图 也可以使用类来定义一个视图,称为 类视图

函数视图遇到一个视图对应的路径提供了多种不同 HTTP 请求方式的支持时

便需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都不佳

例如:

 def register(request):

    """处理注册"""

 

    # 获取请求方法,判断是 GET/POST 请求

    if request.method == 'GET':

        # 处理 GET 请求,返回注册页面

        return render(request, 'register.html')

    else:

        # 处理 POST 请求,实现注册逻辑

        return HttpResponse('这里实现注册逻辑')

使用类视图可以将视图对应的不同请求方式以类中的不同方法来区别定义。如下所示

from django.views.generic import View

 

class RegisterView(View):

    """类视图:处理注册"""

 

    def get(self, request):

        """处理 GET 请求,返回注册页面"""

        return render(request, 'register.html')

 

    def post(self, request):

        """处理 POST 请求,实现注册逻辑"""

        return HttpResponse('这里实现注册逻辑')

类视图的好处:

  • 代码可读性好
  • 类视图相对于函数视图有更高的复用性 如果其他地方需要用到某个类视图的某个特定逻辑,直接继承该类视图即可

类视图使用

定义类视图需要继承自 Django 提供的父类 View ,可使用 from django.views.generic import View 或者 from django.views.generic.base import View 导入,定义方式如上所示。

注意 : 配置路由时,需要在类名后面增加 as_view( ) 函数

urlpatterns = [

    # 视图函数:路由添加

    # url(r'^register/$', views.register),

    # 类视图:路由添加

    url(r'^register/$', views.RegisterView.as_view()),

]

演示效果:

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 以类定义的视图, 我们成为类视图
  • 类视图能够包含多个函数视图
  • 类视图中的函数名称是规定死的请求方法名
  • 类视图调用的时候, 子路由部分需要在类名后面添加 as_view( ) 才可以

类视图原理

学习目标:

了解类视图的底层原理

类视图原理

为什么我们定义 url 的时候, 调用 as_view( ) 函数,就可以达到结果, 如果不调用就会报错.

到底 as_view( ) 帮助我们干了什么了?

我们下面来研究一下:

    @classonlymethod

    def as_view(cls, **initkwargs):

 

        ...省略代码...

 

        def view(request, *args, **kwargs):

            # 这里的clsas_view这个函数接收的第一个参数,也就是调用当前函数的类.

            # 得到调用的类了之后, 创建类的对象: self

            self = cls(**initkwargs)

            if hasattr(self, 'get') and not hasattr(self, 'head'):

                self.head = self.get

            # 给当前这个类,添加对应的属性, 如下所示:

            self.request = request

            self.args = args

            self.kwargs = kwargs

            # 调用dispatch方法,按照不同请求方式调用不同请求方法

            return self.dispatch(request, *args, **kwargs)

 

        ...省略代码...

 

        # 返回真正的函数视图

        return view

 

    # dispatch 帮我们判断了 前端发送的请求方法 ( get )是否在 django 的规定范围内,

    # 如果在, 则调用该方法.

    def dispatch(self, request, *args, **kwargs):

        # self.http_method_names 指的是我们的类视图中,对象方法的名字

        # 这里把所有方法的名字都存放在了 http_methods_names

        # 我们会把当前请求的方式转为小写,然后判断是否在列表中存在.

        if request.method.lower() in self.http_method_names:

            # 如果在里面, 则进入这里

            # 这里的 getattr 作用是获取当前对象的属性.

            # 下面的参数为:

            # self :  类视图对象

            # request.method.lower() : 请求方法的小写. 例如: 'get' 'post'

            # http_method_not_allowed : 默认值, 如果上面的值没有的话, 把该值给 handle

            # 下面代码整体的意思: 根据类视图对象, 获取当前类视图中对应名称的方法

            # 如果获取到, 则把方法返回给handle, 否则不允许访问.

            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

        else:

            # 如果类视图中如果没有的话, 则进入这里, 表明不允许进行请求.

            # 我们会把不允许请求这个字段返回给handle.

            handler = self.http_method_not_allowed

        # 最终返回handle(handle里面要么包含可以访问的方法, 要么就是不允许访问的字段)

        return handler(request, *args, **kwargs)

总结:

  • 了解 as_view( ) 这个函数是类视图调用时, 必须调用的一个函数
  • as_view( ) 这个函数中会判断前端的请求方法在类视图中是否添加的有
    • 有, 则直接访问该函数
    • 没有, 则会报找不到的错误 ( 405 )

类视图使用装饰器

学习目标:

能够给类视图中的函数增加装饰器

通过路由, 间接添加装饰器

准备工作:

定义一个装饰器函数, 以及我们将要访问的类视图函数:

目标: 给类视图的两个函数, 添加上定义的装饰器函数

# 我们自定义的装饰器:
def my_decorator(func):
    def wrapper(request, *args, **kwargs):
        print('自定义装饰器被调用了')
        print('请求路径%s' % request.path)
        return func(request, *args, **kwargs)
    return wrapper
 
# 自定义的类视图: 
class DemoView(View):
    def get(self, request):
        print('类视图中的 get 方法')
        return HttpResponse('demoview get')
 
    def post(self, request):
        print('类视图中的 post 方法')
        return HttpResponse('demoview post')

URL 配置, 间接给函数增加装饰器:

urlpatterns = [
    # 类视图对应的子路由: 
    url(r'^demo/$', my_decorate(DemoView.as_view()))
]

此种方式最简单,但因装饰行为被放置到了 url 配置中,单看视图的时候无法知道此视图还被添加了装饰器,不利于代码的有效阅读. . 此方法不建议使用.

此种方式会为类视图中的所有请求方法都加上装饰器行为 (因为是在视图入口处,分发请求方式前)

在类视图中装饰

在类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器

需要使用 method_decorator 将其转换为适用于类视图方法的装饰器.

from django.utils.decorators import method_decorator
 
# 为特定请求方法添加装饰器
class DemoView(View):
 
    @method_decorator(my_decorator)  #  get 方法添加了装饰器
    def get(self, request):
        print('类视图中的 get 方法')
        return HttpResponse('demoview get')
 
    @method_decorator(my_decorator)  #  post 方法添加了装饰器
    def post(self, request):
        print('类视图中的 post 方法')
        return HttpResponse('demoview post')
 
    def put(self, request):  # 没有为 put 方法添加装饰器
        print('类视图中的 put 方法')
        return HttpResponse('demoview put')

还可以这样用:

method_decorator装饰器使用 name 参数指明被装饰的方法

# 为特定请求方法添加装饰器
@method_decorator(my_decorator, name='get')
class DemoView(View):
    def get(self, request):
        print('类视图中的 get 方法')
        return HttpResponse('demoview get')
 
    def post(self, request):
        print('类视图中的 post 方法')
        return HttpResponse('demoview post')
 
 
 
 
 
# 为全部请求方法添加装饰器
@method_decorator(my_decorator, name='dispatch')
class DemoView(View):
    def get(self, request):
        print('类视图中的 get 方法')
        return HttpResponse('demoview get')
 
    def post(self, request):
        print('类视图中的 post 方法')
        return HttpResponse('demoview post')

总结:

  • 我们不能直接给类视图中的函数添加装饰器
  • 想要给类视图中的函数添加装饰器我们这里提供了两种方式:
    • 给子路由的类名, 添加装饰器( 不推荐 )
    • 使用 @method_decorator( ) 装饰器, 修饰别的装饰器. 达到目的

 

类视图 Mixin 扩展类

学习目标:

知道 Mixin 扩展类的定义和使用

Mixin 扩展类的使用

例如:

# 我们自定义的装饰器:

def my_decorator_1(func):

    def wrapper(request, *args, **kwargs):

        print('自定义装饰器被调用了')

        print('请求路径%s' % request.path)

        return func(request, *args, **kwargs)

    return wrapper

 

# 定义的 Mixin 扩展类:

class FirstMixin(object):

    @classmethod

    def as_view(cls, *args, **kwargs):

        view = super().as_view(*args, **kwargs)

        view = my_decorator_1(view)

        return view

 

# 定义的类视图, 继承自: 扩展类 + View

class DemoView(FirstMixin, View):

    def get(self, request):

        print('demoview get')

        return HttpResponse('demoview get')

 

    def post(self, request):

        print('demoview post')

        return HttpResponse('demoview post')

多个 Mixin 扩展类连用:

例如:

# 我们自定义的装饰器:

def my_decorator_1(func):

    def wrapper(request, *args, **kwargs):

        print('自定义装饰器被调用了')

        print('请求路径%s' % request.path)

        return func(request, *args, **kwargs)

    return wrapper

 

# 我们自定义的装饰器:

def my_decorator_2(func):

    def wrapper(request, *args, **kwargs):

        print('自定义装饰器被调用了')

        print('请求路径%s' % request.path)

        return func(request, *args, **kwargs)

    return wrapper

 

class FirstMixin(object):

    """ FirstMixin 扩展类 """

    @classmethod

    def as_view(cls, *args, **kwargs):

        view = super().as_view(*args, **kwargs)

        view = my_decorator_1(view)

        return view

 

class SecondMixin(object):

    """ SecondMixin 扩展类 """

     @classmethod

    def as_view(cls, *args, **kwargs):

        view = super().as_view(*args, **kwargs)

        view = my_decorator_2(view)

        return view

 

class DemoView(FirstMixin, SecondMixin, View):

    def get(self, request):

        print('demoview get')

        return HttpResponse('demoview get')

 

    def post(self, request):

        print('demoview post')

        return HttpResponse('demoview post')

定义的扩展父类名称通常以 Mixin 结尾

总结:

  • 使用 Mixin 扩展类时有两个注意点:
    • 扩展类需要继承自 object
    • 类视图调用时, 需要把 View 类添加到最后
  • 在 Mixin 扩展类中, 我们一般会重写 as_view( ) 函数. 在函数内添加过滤
  • 一个类视图可以继承多个扩展类, 每个扩展类中都可以添加装饰器.

中间件

学习目标:

知道什么是中间件

掌握中间件的调用顺序

什么是中间件:

  • Django 的中间件是一个轻量级、底层的插件系统,可以介入请求和响应处理过程,修改 Django 的输入或输出.
  • 中间件的设计为开发者提供了一种无侵入式的开发方式,增强了 Django 框架的健壮性。
  • 我们可以使用中间件,在 Django 视图的不同阶段对输入或输出进行处理.

中间件的定义方法

定义一个中间件工厂函数,然后返回一个可以被调用的中间件。

中间件工厂函数需要接收一个可以调用的 get_response 对象。

返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个 request 对象参数,返回一个 response 对象。

def simple_middleware(get_response):
    # 此处编写的代码仅在 Django 第一次配置和初始化的时候执行一次。
 
    def middleware(request):
 
        # 此处编写的代码会在每个请求处理视图前被调用。
 
        response = get_response(request)
 
        # 此处编写的代码会在每个请求处理视图之后被调用。
 
        return response
 
    return middleware

例如,在 users 应用中新建一个 middleware.py 文件,

def my_middleware(get_response):
 
    print('init 被调用')
 
    def middleware(request):
 
        print('before request 被调用')
 
        response = get_response(request)
 
        print('after response 被调用')
 
        return response
    return middleware

定义好中间件后,需要在 settings.py 文件中添加注册中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
     # 添加中间件
    'users.middleware.my_middleware'
]

定义一个视图进行测试

def demo_view(request):
    print('view 视图被调用')
    return HttpResponse('OK')

执行结果

uploading.4e448015.gif转存失败重新上传取消

注意:Django 运行在调试模式下,中间件 init 部分有可能被调用两次。

多个中间件的执行顺序

  • 在请求视图被处理,中间件由上至下依次执行
  • 在请求视图被处理,中间件由下至上依次执行

uploading.4e448015.gif转存失败重新上传取消

示例:

定义两个中间件

def my_middleware(get_response):
    print('init 被调用')
    def middleware(request):
        print('before request 被调用')
        response = get_response(request)
        print('after response 被调用')
        return response
    return middleware
 
def my_middleware2(get_response):
    print('init2 被调用')
    def middleware(request):
        print('before request 2 被调用')
        response = get_response(request)
        print('after response 2 被调用')
        return response
    return middleware

注册添加两个中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'users.middleware.my_middleware'# 添加
    'users.middleware.my_middleware2'# 添加
]

执行结果

init2 被调用
init 被调用
before request 被调用
before request 2 被调用
view 视图被调用
after response 2 被调用
after response 被调用

视图前后的执行流程

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 中间件一般会现在一个单独的文件之中
  • 中间件函数定义好后, 可以获取三个空间用于添加代码
    • 项目初始化的时候会调用的空间
    • 在调用视图函数之前会调用的空间
    • 在调用视图函数之后会调用的空间
  • 使用中间件之前需要在 settings.py 的 MIDDLEWARE 模块中注册.
  • 中间件调用的顺序需要注意.

Django 自带模板的使用

学习目标:

掌握 django 自带模板路径的添加方法

能够调用 django 中的模板

配置

在工程中创建模板目录 templates

settings.py 配置文件中修改 TEMPLATES 配置项的 DIRS 值:

由原来的代码:

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',
            ],
        },
    },
]

改为如下代码:

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',
            ],
        },
    },
]

定义模板

templates 目录中新建一个模板文件,如 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
 
</body>
</html>

渲染模板

Django 提供了一个实现模板渲染的函数 render( )

使用:

# 使用方式: 
 
render( request, '模板文件名称', 添加给模板的数据)

参数解释:

request 是需要要添加的一个参数, 这个参数规定死了就是 request

模板文件名称: 主要指我们在 templates 中添加的前端文件名称

第三个参数主要是: 传给模板的一些变量. 一般我们使用字典的格式

例如:

from django.shortcuts import render
 
def index(request):
    # 定义一个变量, 拼接为字典格式: 
    context={'city': '北京'}
    # 返回 render() 函数
    return render(request,'index.html',context)

模板中也可以添加变量:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--模板中可以定义变量-->
    <h1>{{ city }}</h1>
</body>
</html>

总结:

  • 第一步: 需要先创建 templates 模板文件夹
  • 第二步: 在 settings.py 文件中配置模板文件夹路径
  • 第三步: 在模板文件夹中添加模板文件
  • 第四步: 在视图函数中调用 render( ) 函数, 调用模板, 有需要可以传参数.

 

模板基本语法

学习目标:

了解模板变量和模板语句的书写格式

模板变量

变量名必须由字母、数字、下划线(不能以下划线开头)和点组成

# 语法如下:
 
{{变量}}

模板变量可以是 python 的内建类型

例如:

def demo(request):
    context = {
        'city': '北京',
        'adict': {
            'name': '西游记',
            'author': '吴承恩'
        },
        'alist': [1, 2, 3, 4, 5]
    }
    return render(request, 'index.html', context)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{ city }}</h1>
    <h1>{{ adict }}</h1>
    <h1>{{ adict.name }}</h1>  <!--注意字典的取值方法-->
    <h1>{{ alist }}</h1>  
    <h1>{{ alist.0 }}</h1>     <!--注意列表的取值方法-->
</body>
</html>

模板语句

for 循环:

{% for item in 列表 %}
 
循环逻辑
{{forloop.counter}}表示当前是第几次循环,从1开始
{%empty%} 列表为空或不存在时执行此逻辑
 
{% endfor %}

if 条件:

{% if ... %}
逻辑1
{% elif ... %}
逻辑2
{% else %}
逻辑3
{% endif %}

比较运算符如下:

==
!=
<
>
<=
>=

逻辑运算符如下:

用于连接比较运算符

and
or
not

例如:

后端代码:

def temp(request):
 
    context = {
        'item':[1,2,3,4]
    }
 
    return render(request, 'index.html', context)

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% for i in item %}
        {% if forloop.counter == 1 or forloop.counter == 2 %}
            {{i}}  if语句进入  <br>
        {% endif %}
 
        {% empty %}
            item值为空
    {% endfor %}
</body>
</html>

显示结果:

1 if语句进入 
2 if语句进入

注意:运算符左右两侧不能紧挨变量或常量,必须有空格.

{% if a == 1 %}  # 正确写法
{% if a==1 %}    # 错误写法

总结:

  • 模板语法主要分为三种: 变量, for循环, if语句
  • 变量和我们 python 语法差别不大
  • for 循环和 if 语句 注意在外面添加 %
  • for 循环和 if 语句 都需要添加结尾

过滤器

学习目标:

能够掌握过滤器对应的语法规则

过滤器语法:

# 语法如下:

 

变量 | 过滤器:参数

参数如下:

  • 使用管道符号 | 来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中.
  • 如果过滤器需要参数,则使用冒号:传递参数.

常见过滤器介绍:

列举自带过滤器几个如下:

  • safe : 禁用转义,告诉模板这个变量是安全的,可以解释执行
  • length : 长度,返回字符串包含字符的个数,或列表、元组、字典的元素个数.
  • default : 默认值,如果变量不存在时则返回默认值.
  • data | default:'默认值'
  • date : 日期,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
    • Y 表示年,格式为 4 位,y 表示两位的年。
    • m 表示月,格式为 01, 02, 12 等。
    • d 表示日, 格式为 01, 02 等。
    • j 表示日,格式为 1, 2 等。
    • H 表示时,24 进制,h 表示 12 进制的时。
    • i 表示分,为 0-59。
    • s 表示秒,为 0-59。
  • value | date:"Ymd  His"

总结:

  • 过滤器就是把数据进行过滤处理的一种方法
  • django 自带了一些过滤器, 我们常见的有: safe, length, default 等

自定义过滤器

学习目标:

掌握自定义过滤器的使用

自定义过滤器的创建

在自己的 app 里建一个 templatetags 包,在包里创建一个用于定义的 py 文件

  • 在 py 文件中
    • 先导入 from django import template
    • 实例化对象 register = template.Library( )
    • 创建一个 template 能认识的函数
    • 对创建的每一个过滤器,都要用加上装饰器

uploading.4e448015.gif转存失败重新上传取消

  • 在 HTML 文件中引用
    • load 过滤器文件名
    • 使用过滤器

uploading.4e448015.gif转存失败重新上传取消

注意点:

templatetags 文件夹 要在各自的应用内创建

当前子应用一定要在 settings.py INSTALL_APPS 模块中注册.

总结:

  • 能够按照课件, 自定义过滤器
  • 掌握自定义过滤器的流程

模板继承

学习目标:

掌握模板继承的特点和使用方式

父模板

如果发现在多个模板中某些内容相同,那就应该把这段内容抽取出来放到父模板中.

标签 block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。

为了更好的可读性,建议给 endblock 标签写上名字,这个名字与对应的 block 名字相同。

父模板中也可以使用上下文中传递过来的数据。

{% block 名称 %}

预留区域,可以编写默认内容,也可以没有默认内容

{% endblock  名称 %}

子模板

标签 extends:继承,写在子模板文件的第一行。

{% extends "父模板路径"%}

子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。

填充父模板中指定名称的预留区域。

{% block 名称 %}

实际填充内容

{{ block.super }}用于获取父模板中block的内容

{% endblock 名称 %}

总结:

  • 使用模板继承, 主要是为了提高代码重用,减轻开发人员的工作量.
  • 我们可以把子模板中的重复内容抽取到父膜板中作为默认值
  • 如果某个子模板中的内容有差异, 则可以继承过来重新更改. 否则直接沿用父模板的内容.

注释

学习目标:

掌握单行和多行注释的写法

单行注释:

单行注释语法如下:

# 语法如下

 

{# 注释内容 #}

多行注释:

多行注释使用 comment 标签,语法如下:

# 语法如下

 

{% comment %}

注释内容

{% endcomment %}

总结:

  • 明白单行注释和多行注释的写法
  • 模板注释需要写在模板中才能生效

 

 

 

 

Jinja2 模板在 Django 中使用

学习目标:

了解 jinja2 的使用方法

能够使用 jinja2 django 中渲染数据

jinja2 介绍

Jinja2:是 Python 下一个被广泛应用的模板引擎,是由 Python 实现的模板语言,他的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能,尤其是 Flask 框架内置的模板语言

由于 django 默认模板引擎功能不齐全,速度慢,所以我们也可以在 Django 中使用 jinja2, jinja2 宣称比 django 默认模板引擎快 10-20 倍。

Django 主流的第三方 APP 基本上也都同时支持 Django 默认模板及 jinja2,所以要用 jinja2 也不会有多少障碍。

安装 jinja2 模块

# 安装 jinja2 模板

pip install jinja2

Django 配置 jinja2

在项目文件中创建 jinja2_env.py 文件, 进行配置

from jinja2 import Environment

 

def environment(**options):

    env = Environment(**options)

    return env

添加配置文件后, settings.py 文件中添加, 告知 django 配置文件路径:

 

TEMPLATES = [

    {

        # 将默认的模板渲染引擎改为 jinja2 引擎

        'BACKEND': 'django.template.backends.jinja2.Jinja2',

        'DIRS': [os.path.join(BASE_DIR, 'templates')],

        'APP_DIRS':True,

        'OPTIONS':{

            # 添加配置文件路径:

            'environment': 'jinja2_env.environment',

            'context_processors':[

                'django.template.context_processors.debug',

                'django.template.context_processors.request',

                'django.contrib.auth.context_processors.auth',

                'django.contrib.messages.context_processors.messages',

            ],

        },

    },

]

jinja2 模板的使用绝大多数和 Django 自带模板一样

for 循环有差异

uploading.4e448015.gif转存失败重新上传取消

jinja2 自定义过滤器

jinja2_env.py 文件中自定义过滤器

from jinja2 import Environment

 

def environment(**options):

    env = Environment(**options)

 

    # 2.将自定义的过滤器添加到环境中

    env.filters['do_listreverse'] = do_listreverse

 

    return env

 

# 1.自定义过滤器

def do_listreverse(li):

    if li == "B":

        return "哈哈"

总结:

  • jinja2 模板引擎是一个外置的模板渲染引擎, 效率比 django 自带的引擎高
  • 配置 jinja2 模板引擎需要创建一个配置文件, 然后再 settings.py 中配置.
  • 可以自定义 jinja2 自定义的过滤器方法, 进行过滤操作

CSRF

学习目标:

掌握 CSRF 的攻击方式和防御方式

CSRF 定义

  • CSRF全拼为 Cross Site Request Forgery, 译为跨站请求伪造。
  • CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求。
    • 包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......
  • 造成的问题:个人隐私泄露以及财产安全。

CSRF 攻击示意图

  • 客户端访问服务器时没有同服务器做安全验证

uploading.4e448015.gif转存失败重新上传取消

防止 CSRF 攻击

步骤

  1. 在客户端向后端请求界面数据的时候,后端会往响应中的 cookie 中设置 csrf_token 的值
  2. 在 Form 表单中添加一个隐藏的的字段,值也是 csrf_token
  3. 在用户点击提交的时候,会带上这两个值向后台发起请求
  4. 后端接受到请求,以会以下几件事件:
    • 从 cookie 中取出 csrf_token
    • 从 表单数据中取出来隐藏的 csrf_token 的值
    • Django 进行对比 (这里的对比不要求一定一致, 有时候两个值不一致)
  5. 如果对比能够通过, 则是正常的请求
  6. 如果对比不能够通过,代表不是正常的请求,不执行下一步操作

uploading.4e448015.gif转存失败重新上传取消

CSRF_TOKEN 的设置过程

uploading.4e448015.gif转存失败重新上传取消

数据库映射

学习目标:

掌握 ORM 框架的概念和作用

ORM 框架

O object,也就类对象的意思

R relation,翻译成中文是关系, 也就是关系数据库中数据表的意思.

M mapping,是映射的意思.

ORM 框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据

ORM 框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。

django 中内嵌了 ORM 框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作。

使用 django 进行数据库开发的步骤如下:

  1. 配置数据库连接信息
  2. 在 models.py 中定义模型类
  3. 迁移
  4. 通过类和对象完成数据增删改查操作

ORM作用

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

数据库配置

学习目标:

掌握在 django 中使用数据库的配置

修改默认配置

settings.py 中保存了数据库的连接配置信息,Django 默认初始配置使用 sqlite 数据库

修改为 Mysql 数据库配置:

使用 MySQL 数据库首先需要安装驱动程序

pip install PyMySQL

Django 的工程同名子目录的 __init__.py 文件中添加如下语句

from pymysql import install_as_MySQLdb

 

install_as_MySQLdb()

作用是让 Django ORM 能以 mysqldb 的方式来调用 PyMySQL

  1. 修改 DATABASES 配置信息
  2. DATABASES = {
  3.     'default': {
  4.         'ENGINE': 'django.db.backends.mysql',
  5.         'HOST': '127.0.0.1',  # 数据库主机
  6.         'PORT': 3306,  # 数据库端口
  7.         'USER': 'root',  # 数据库用户名
  8.         'PASSWORD': 'mysql',  # 数据库用户密码
  9.         'NAME': 'django_demo'  # 数据库名字
  10.     }
  11. }
  12. 在 MySQL 中创建数据库
  13. create database django_demo default charset=utf8;

总结:

  • 使用 Mysql 替换 django 默认自带的 sqlite 数据库
  • 安装 PyMysql, 替换原有的数据库引擎
  • 配置数据库对应的参数

定义模型类

学习目标:

能够在项目中定义模型类

定义模型类的步骤:

  • 模型类被定义在 "应用 / models.py " 文件中。
  • 定义一个模型类
  • 该模型类必须继承自 Model 类,位于包 django.db.models 中.

接下来首先以"图书-英雄"管理为例进行演示.

演示:

创建子应用 booktest,在 models.py 文件中定义模型类.

from django.db import models

 

# 定义图书模型类 BookInfo

class BookInfo(models.Model):

    btitle = models.CharField(max_length=20, verbose_name='名称')

    bpub_date = models.DateField(verbose_name='发布日期')

    bread = models.IntegerField(default=0, verbose_name='阅读量')

    bcomment = models.IntegerField(default=0, verbose_name='评论量')

    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

 

    class Meta:

        db_table = 'tb_books'  # 指明数据库表名

        verbose_name = '图书'  # admin站点中显示的名称

        verbose_name_plural = verbose_name  # 显示的复数名称

 

    def __str__(self):

        """定义每个数据对象的显示信息"""

        return self.btitle

 

# 定义英雄模型类 HeroInfo

class HeroInfo(models.Model):

    GENDER_CHOICES = (

        (0, 'female'),

        (1, 'male')

    )

    hname = models.CharField(max_length=20, verbose_name='名称')

    hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别') 

    hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')

    hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书')  # 外键

    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

 

    class Meta:

        db_table = 'tb_heros'

        verbose_name = '英雄'

        verbose_name_plural = verbose_name

 

    def __str__(self):

        return self.hname

1 数据库表名

模型类如果未指明表名,Django 默认以 小写 app应用名_小写模型类名 为数据库表名。

可通过 db_table 指明数据库表名。

2 关于主键

django 会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后 django 不会再创建自动增长的主键列。

默认创建的主键列属性为 id,可以使用 pk 代替,pk 全拼为 primary key

3 属性命名限制

  • 不能是 python 的保留关键字。
  • 不允许使用连续的下划线,这是由django的查询方式决定的。
  • 定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
  • 属性=models.字段类型(选项)

4)字段类型

类型

说明

AutoField

自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性

BooleanField

布尔字段,值为True或False

NullBooleanField

支持Null、True、False三种值

CharField

字符串,参数max_length表示最大字符个数

TextField

大文本字段,一般超过4000个字符时使用

IntegerField

整数

DecimalField

十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数

FloatField

浮点数

DateField

日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误

TimeField

时间,参数同DateField

DateTimeField

日期时间,参数同DateField

FileField

上传文件字段

ImageField

继承于FileField,对上传的内容进行校验,确保是有效的图片

5 选项

选项

说明

null

如果为True,表示允许为空,默认值是False

blank

如果为True,则该字段允许为空白,默认值是False

db_column

字段的名称,如果未指定,则使用属性的名称

db_index

若值为True, 则在表中会为此字段创建索引,默认值是False

default

默认

primary_key

若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用

unique

如果为True, 这个字段在表中必须有唯一值,默认值是False

related_name

在关联查询中,代替单一对象查找多对象 对象名小写_set(book.heroinfo_set.all() 的写法

auto_now_add

只在数据添加的时候,记录时间

auto_now

数据添加和更新的时候,记录时间

null 是数据库范畴的概念,blank 是表单验证范畴的

6 外键

在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:

  • CASCADE 级联,删除主表数据时连通一起删除外键表中数据
  • PROTECT 保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
  • SET_NULL 设置为NULL,仅在该字段null=True允许为null时可用
  • SET_DEFAULT 设置为默认值,仅在该字段设置了默认值时可用
  • SET() 设置为特定值或者调用特定方法,如
  • from django.conf import settings
  • from django.contrib.auth import get_user_model
  • from django.db import models
  •  
  • def get_sentinel_user():
  •     return get_user_model().objects.get_or_create(username='deleted')[0]
  •  
  • class MyModel(models.Model):
  •     user = models.ForeignKey(
  •         settings.AUTH_USER_MODEL,
  •         on_delete=models.SET(get_sentinel_user),
  •     )
  • DO_NOTHING 不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError异常

迁移

将模型类同步到数据库中。

1)生成迁移文件

python manage.py makemigrations

2)同步到数据库中

python manage.py migrate

添加测试数据

insert into tb_books(btitle,bpub_data,bread,bcomment,is_delete) values

('射雕英雄传','1980-5-1',12,34,0),

('天龙八部','1986-7-24',36,40,0),

('笑傲江湖','1995-12-24',20,80,0),

('雪山飞狐','1987-11-11',58,24,0);

insert into tb_heros(hname,hgender,hbook_id,hcomment,is_delete) values

('郭靖',1,1,'降龙十八掌',0),

('黄蓉',0,1,'打狗棍法',0),

('黄药师',1,1,'弹指神通',0),

('欧阳锋',1,1,'蛤蟆功',0),

('梅超风',0,1,'九阴白骨爪',0),

('乔峰',1,2,'降龙十八掌',0),

('段誉',1,2,'六脉神剑',0),

('虚竹',1,2,'天山六阳掌',0),

('王语嫣',0,2,'神仙姐姐',0),

('令狐冲',1,3,'独孤九剑',0),

('任盈盈',0,3,'弹琴',0),

('岳不群',1,3,'华山剑法',0),

('东方不败',0,3,'葵花宝典',0),

('胡斐',1,4,'胡家刀法',0),

('苗若兰',0,4,'黄衣',0),

('程灵素',0,4,'医术',0),

('袁紫衣',0,4,'六合拳',0);

总结:

  • 我们可以定义模型类
  • 并且在模型类中定义对应的字段
  • 字段上可以添加对应的数据

Shell 演示工具使用

学习目标:

了解 shell 工具的使用方式

shell工具

Django manage 工具提供了 shell 命令,帮助我们配置好当前工程的运行环境(如连接好数据库等),以便可以直接在终端中执行测试 python 语句。

通过如下命令进入 shell

python manage.py shell

uploading.4e448015.gif转存失败重新上传取消

导入两个模型类,以便后续使用

from booktest.models import BookInfo, HeroInfo

查看 MySQL 数据库日志

查看 mysql 数据库日志可以查看对数据库的操作记录。 mysql 日志文件默认没有产生,需要做如下配置:

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

uploading.4e448015.gif转存失败重新上传取消

6869行前面的#去除,然后保存并使用如下命令重启mysql服务。

sudo service mysql restart

使用如下命令打开 mysql 日志文件。

tail  -f  /var/log/mysql/mysql.log  # 可以实时查看数据库的日志内容

# 如提示需要sudo权限,执行

# sudo tail -f /var/log/mysql/mysql.log

总结:

  • 知道我们可以使用 shell 工具来演示代码
  • 能够查看 mysql 数据库日志

增加

学习目标:

知道数据库操作中增加的两种方法

增加的第一种方法:

增加数据有两种方法

save

通过创建模型类对象,执行对象的save()方法保存到数据库中。

>>> from datetime import date
>>> book = BookInfo(
    btitle='西游记',
    bpub_date=date(1988,1,1),
    bread=10,
    bcomment=10
)
>>> book.save()
>>> hero = HeroInfo(
    hname='孙悟空',
    hgender=0,
    hbook=book
)
>>> hero.save()
>>> hero2 = HeroInfo(
    hname='猪八戒',
    hgender=0,
    hbook_id=book.id
)
>>> hero2.save()

增加的第二种方法:

create

通过 模型类.objects.create( ) 保存.

>>> HeroInfo.objects.create(
    hname='沙悟净',
    hgender=0,
    hbook=book
)
<HeroInfo: 沙悟净>

总结:

  • 增加数据库的方法一共有两种: create 和 save
  • create 方法需要通过 模型类 来调用
  • save 方法需要通过对象来调用

删除

学习目标:

掌握删除的两种方法

删除的第一种方法:

删除有两种方法

使用对象删除

# 使用模板:

 

对象.delete()

例如:

# 获取对象:

hero = HeroInfo.objects.get(id=13)

 

# 调用对象的删除方法:

hero.delete()

删除的第二种方法:

使用查询集删除

# 使用查询集删除:

模型类.objects.filter().delete( )

例如:

HeroInfo.objects.filter(id=14).delete()

总结:

  • 删除有两种方法:
  • 使用对象删除: 对象.delete()
  • 使用查询集删除: queryset.delete()

修改

学习目标:

掌握修改的两种方法

修改的第一种方法:

修改更新有两种方法

save

修改模型类对象的属性,然后执行 save() 方法

# 使用方式:
 
对象.save()

例如:

hero = HeroInfo.objects.get(hname='猪八戒')
hero.hname = '猪悟能'
hero.save()

修改的第二种方法:

update

# 使用方式:
 
查询集.update()

例如:

使用 模型类.objects.filter().update(),会返回受影响的行数

HeroInfo.objects.filter(hname='沙悟净').update(hname='沙僧')

总结:

  • 修改有两种方式:
  • 第一种是调用对象修改, 改完之后, save 保存
  • 第二种是获取查询集, 然后调用查询集的 update 修改操作, 进行修改

查询

学习目标:

掌握查询的相关操作

基本查询

get 查询单一结果,如果不存在会抛出 模型类.DoesNotExist 异常.

all 查询多个结果。

count 查询结果数量。

>>> BookInfo.objects.all()

<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 笑傲江湖>, <BookInfo: 雪山飞狐>, <BookInfo: 西游记>]>

>>> book = BookInfo.objects.get(btitle='西游记')

>>> book.id

5

 

>>> BookInfo.objects.get(id=3)

<BookInfo: 笑傲江湖>

>>> BookInfo.objects.get(pk=3)

<BookInfo: 笑傲江湖>

>>> BookInfo.objects.get(id=100)

Traceback (most recent call last):

  File "<console>", line 1, in <module>

  File "/Users/delron/.virtualenv/dj/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method

    return getattr(self.get_queryset(), name)(*args, **kwargs)

  File "/Users/delron/.virtualenv/dj/lib/python3.6/site-packages/django/db/models/query.py", line 380, in get

    self.model._meta.object_name

db.models.DoesNotExist: BookInfo matching query does not exist.

 

>>> BookInfo.objects.count()

6

总结:

  • 能够掌握基本的查询, 例如:
  • get : 获取单一结果
  • all : 获取所有结果
  • count : 获取所有的数量

过滤查询

学习目标:

掌握过滤查询的各种方法

获取过滤查询的方法:

实现 SQL 中的 where 功能,包括

  • filter 过滤出多个结果
  • exclude 排除掉符合条件剩下的结果
  • get 过滤单一结果

对于过滤条件的使用,上述三个方法相同,故仅以 filter 进行讲解。

过滤条件的表达语法如下:

# 属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线
 
属性名称__比较运算符 = 

相等

exact:表示判等。

例:查询编号为1的图书。

BookInfo.objects.filter(id__exact=1)
可简写为:
BookInfo.objects.filter(id=1)

模糊查询

contains:是否包含。

说明:如果要包含%无需转义,直接写即可。

例:查询书名包含''的图书。

BookInfo.objects.filter(btitle__contains='')

startswithendswith:以指定值开头或结尾。

例:查询书名以''结尾的图书

BookInfo.objects.filter(btitle__endswith='')

以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexacticontainsistartswithiendswith.

空查询

isnull:是否为null

例:查询书名不为空的图书。

BookInfo.objects.filter(btitle__isnull=False)

范围查询

in:是否包含在范围内

例:查询编号为135的图书

BookInfo.objects.filter(id__in=[1, 3, 5])

比较查询

  • gt 大于 (greater then)
  • gte 大于等于 (greater then equal)
  • lt 小于 (less then)
  • lte 小于等于 (less then equal)

例:查询编号大于3的图书

BookInfo.objects.filter(id__gt=3)

不等于的运算符,使用exclude()过滤器。

例:查询编号不等于3的图书

BookInfo.objects.exclude(id=3)

日期查询

yearmonthday

week_dayhourminutesecond

对日期时间类型的属性进行运算

例:查询1980年发表的图书。

BookInfo.objects.filter(bpub_date__year=1980)

例:查询198011日后发表的图书。

BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))

总结:

  • 我们可以通过 filter exclude get 进行过滤查询
  • 过滤查询的时候, 可以配置一些额外的参数

F 对象 Q 对象

学习目标:

知道 F 对象和 Q 对象的使用方式

F 对象

之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢?

答:使用 F对象,被定义在 django.db.models .

# 语法如下:
 
F(属性名)

例:查询阅读量大于等于评论量的图书.

# 导入: 
from django.db.models import F
 
# 查询时使用 F 对象
BookInfo.objects.filter(bread__gte=F('bcomment'))

可以在 F 对象 上使用算数运算.

例:查询阅读量大于2倍评论量的图书。

BookInfo.objects.filter(bread__gt=F('bcomment') * 2)

Q 对象

多个过滤器逐个调用表示 逻辑与 关系

sql 语句中 where 部分的 and 关键字.

例:查询阅读量大于20,并且编号小于3的图书。

BookInfo.objects.filter(bread__gt=20,id__lt=3)
BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)

使用 Q( ) 对象结合|运算符实现 逻辑或(or) 的查询

Q对象 被义在 django.db.models .

语法如下:

Q(属性名__运算符=)

例:查询阅读量大于 20的图书,改写为 Q对象 如下.

# 导入
from django.db.models import Q
 
# 获取数据
BookInfo.objects.filter(Q(bread__gt=20))

Q对象 可以使用 &|连接,&表示逻辑与,|表示逻辑或.

例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现

BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))

Q对象 前可以使用~操作符,表示非not.

例:查询编号不等于3的图书。

BookInfo.objects.filter(~Q(pk=3))

总结:

  • F 对象 是对比两列时使用的方法
  • Q 对象是对数据进行逻辑操作时进行的方法

聚合函数和排序

学习目标:

知道聚合函数和排序的使用方法

聚合函数

使用 aggregate( ) 过滤器调用聚合函数.

聚合函数包括:

Avg 平均,

Count 数量,

Max 最大,

Min 最小,

Sum 求和

被定义在 django.db.models .

例:查询图书的总阅读量.

from django.db.models import Sum

 

BookInfo.objects.aggregate(Sum('bread'))

注意 aggregate 的返回值是一个字典类型,格式如下:

  {'属性名__聚合类小写':}

  :{'bread__sum':3}

使用 count 时一般不使用 aggregate( ) 过滤器.

例:查询图书总数。

BookInfo.objects.count()

注意 count 函数的返回值是一个数字.

排序

使用 order_by 对结果进行排序

BookInfo.objects.all().order_by('bread')  # 升序

 

BookInfo.objects.all().order_by('-bread')  # 降序

总结:

  • 通过这节的学习, 我们知道了聚合函数的使用
  • 能够知道排序 order_by 的使用方法

关联查询

学习目标:

掌握关联查询的各种访问方法

由一到多的访问

使用格式:

一对应的模型类对象.多对应的模型类名小写_set

例:

b = BookInfo.objects.get(id=1)

# 套用上面的格式:

b.heroinfo_set.all()

 

# 如果在

# hbook = models.ForeignKey(BookInfo, related_name="heros")

# 可以替换成 b.heros.all()

由多到一的访问

使用格式:

多对应的模型类对象.外键名

例:

h = HeroInfo.objects.get(id=1)

# 套用上面的格式:

h.hbook

访问一对应的模型类关联对象的 id

使用格式:

多对应的模型类对象.关联类属性_id

例:

h = HeroInfo.objects.get(id=1)

# 套用上面的格式:

h.hbook_id

关联过滤查询

由多模型类条件查询一模型类数据:

语法如下:

关联模型类名小写__属性名__条件运算符=

注意:如果没有"__运算符"部分,表示等于.

例:

查询图书,要求图书英雄为"孙悟空"

BookInfo.objects.filter(heroinfo__hname='孙悟空')

查询图书,要求图书中英雄的描述包含""

BookInfo.objects.filter(heroinfo__hcomment__contains='')

由一模型类条件查询多模型类数据:

语法如下:

一模型类关联属性名__一模型类属性名__条件运算符=

注意:如果没有"__运算符"部分,表示等于。

例:

查询书名为天龙八部的所有英雄。

HeroInfo.objects.filter(hbook__btitle='天龙八部')

查询图书阅读量大于30的所有英雄

HeroInfo.objects.filter(hbook__bread__gt=30)

总结:

  • 能够知道关联查询中由一对多, 由多对一等查询方式
  • 知道关联过滤查询的方法

查询集 ( QuerySet )

学习目标:

知道查询集的概念和特点

概念

Django ORM 中存在查询集的概念。

查询集,也称查询结果集、QuerySet,表示从数据库中获取的对象集合。

当调用如下过滤器方法时,Django 会返回查询集(而不是简单的列表):

  • all( ):返回所有数据。
  • filter( ):返回满足条件的数据。
  • exclude( ):返回满足条件之外的数据。
  • order_by( ):对结果进行排序。

对查询集可以再次调用过滤器进行过滤,如

BookInfo.objects.filter(bread__gt=30).order_by('bpub_date')

也就意味着查询集可以含有零个、一个或多个过滤器。过滤器基于所给的参数限制查询的结果。

SQL 的角度讲,查询集与 select 语句等价,过滤器像 wherelimitorder by 子句。

判断某一个查询集中是否有数据

  • exists( ):判断查询集中是否有数据,如果有则返回 True,没有则返回 False。

两大特性

惰性执行

创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用

例如,当执行如下语句时,并未进行数据库查询,只是创建了一个查询集qs

qs = BookInfo.objects.all()

继续执行遍历迭代操作后,才真正的进行了数据库的查询

for book in qs:
    print(book.btitle)

缓存

使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。

情况一:如下是两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,增加了数据库的负载。

from booktest.models import BookInfo
[book.id for book in BookInfo.objects.all()]
[book.id for book in BookInfo.objects.all()]

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

情况二:经过存储后,可以重用查询集,第二次使用缓存中的数据。

qs=BookInfo.objects.all()
[book.id for book in qs]
[book.id for book in qs]

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

限制查询集

可以对查询集进行取下标或切片操作,等同于 sql 中的 limit offset 子句。

注意:不支持负数索引。

对查询集进行切片后返回一个新的查询集,不会立即执行查询。

如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发 IndexError 异常,[0:1].get() 如果没有数据引发 DoesNotExist 异常。

示例:获取第12项,运行查看。

qs = BookInfo.objects.all()[0:2]

总结:

  • 知道通过 all filter exclude order_by 获取的是查询集
  • 查询集有两大特性: 惰性 和 缓存执行
  • 限制查询机指的是可以对查询集进行切片处理

管理器 Manager

学习目标:

掌握管理器的相关知识

管理器简介

BookInfo.objects.get( id = 2)

管理器是 Django 的模型进行数据库操作的接口

Django 应用的每个模型类都拥有至少一个管理器。

我们在通过模型类的 objects 属性提供的方法操作数据库时,即是在使用一个管理器对象 objects

当没有为模型类定义管理器时,Django 会为每一个模型类生成一个名为 objects 的管理器,它是 models.Manager 类的对象。

自定义管理器

我们可以自定义管理器,并应用到我们的模型类上。

注意:一旦为模型类指明自定义的管理器后,Django 不再生成默认管理对象 objects.

自定义管理器类主要用于两种情况:

1. 修改原始查询集,重写 all() 方法。

a)打开 booktest / models.py 文件,定义类 BookInfoManager

#图书管理器

class BookInfoManager(models.Manager):

    def all(self):

        #默认查询未删除的图书信息

        #调用父类的成员语法为:super().方法名

        return super().filter(is_delete=False)

b)在模型类BookInfo中定义管理器

class BookInfo(models.Model):

    ...

    books = BookInfoManager()

c)使用方法

BookInfo.books.all()

2. 在管理器类中补充定义新的方法

a)打开 booktest / models.py 文件,定义方法 create

class BookInfoManager(models.Manager):

    #创建模型类,接收参数为属性赋值

    def create_book(self, title, pub_date):

        #创建模型类对象self.model可以获得模型类

        book = self.model()

        book.btitle = title

        book.bpub_date = pub_date

        book.bread=0

        book.bcommet=0

        book.is_delete = False

        # 将数据插入进数据表

        book.save()

        return book

b)为模型类 BookInfo 定义管理器 books 语法如下

class BookInfo(models.Model):

      ...

    books = BookInfoManager()

c)调用语法如下:

book=BookInfo.books.create_book("abc",date(1980,1,1))

总结:

  • 知道如何自定义管理器
  • 了解自定义管理器的方法

使用 Admin 站点

学习目标:

掌握 admin 管理站点的生成方式

Admin站点介绍

假设我们要设计一个新闻网站,我们需要编写展示给用户的页面,网页上展示的新闻信息是从哪里来的呢?是从数据库中查找到新闻的信息,然后把它展示在页面上。但是我们的网站上的新闻每天都要更新,这就意味着对数据库的增、删、改、查操作,那么我们需要每天写sql语句操作数据库吗? 如果这样的话,是不是非常繁琐,所以我们可以设计一个页面,通过对这个页面的操作来实现对新闻数据库的增删改查操作。那么问题来了,老板说我们需要在建立一个新网站,是不是还要设计一个页面来实现对新网站数据库的增删改查操作,但是这样的页面具有一个很大的重复性,那有没有一种方法能够让我们很快的生成管理数据库表的页面呢?有,那就是我们接下来要给大家讲的Django 的后台管理Django 能够根据定义的模型类自动地生成管理页面。

使用 Django 的管理模块,需要按照如下步骤操作:

  1. 管理界面本地化
  2. 创建管理员
  3. 注册模型类
  4. 自定义管理页面

管理界面本地化

settings.py 中设置语言和时区

LANGUAGE_CODE = 'zh-hans' # 使用中国语言

TIME_ZONE = 'Asia/Shanghai' # 使用中国上海时间

创建超级管理员

创建管理员的命令如下,按提示输入用户名、邮箱、密码。

python manage.py createsuperuser

uploading.4e448015.gif转存失败重新上传取消

打开浏览器,在地址栏中输入如下地址后回车。

http://127.0.0.1:8000/admin/

输入前面创建的用户名、密码完成登录。

uploading.4e448015.gif转存失败重新上传取消

登录成功后界面如下,但是并没有我们自己应用模型的入口,接下来进行第三步操作。

uploading.4e448015.gif转存失败重新上传取消

如果想要修改密码可以执行

python manage.py changepassword 用户名

App 应用配置

在每个应用目录中都包含了apps.py文件,用于保存该应用的相关信息。

在创建应用时,Django会向apps.py文件中写入一个该应用的配置类,如

from django.apps import AppConfig

 

class BooktestConfig(AppConfig):

    name = 'booktest'

我们将此类添加到工程settings.py中的INSTALLED_APPS列表中,表明注册安装具备此配置属性的应用。

  • AppConfig.name 属性表示这个配置类是加载到哪个应用的,每个配置类必须包含此属性,默认自动生成。
  • AppConfig.verbose_name 属性用于设置该应用的直观可读的名字,此名字在Django提供的Admin管理站点中会显示,如
  • from django.apps import AppConfig
  •  
  • class BooktestConfig(AppConfig):
  •     name = 'booktest'
  •     verbose_name = '图书管理'

注册模型类

登录后台管理后,默认没有我们创建的应用中定义的模型类,需要在自己应用中的 admin.py 文件中注册,才可以在后台管理中看到,并进行增删改查操作。

打开 booktest / admin.py 文件,编写如下代码:

from django.contrib import admin

from booktest.models import BookInfo,HeroInfo

 

admin.site.register(BookInfo)

admin.site.register(HeroInfo)

到浏览器中刷新页面,可以看到模型类BookInfoHeroInfo的管理了。

uploading.4e448015.gif转存失败重新上传取消

点击类名称"BookInfo"(图书)可以进入列表页,默认只有一列。

uploading.4e448015.gif转存失败重新上传取消

在列表页中点击"增加"可以进入增加页,Django会根据模型类的不同,生成不同的表单控件,按提示填写表单内容后点击"保存",完成数据创建,创建成功后返回列表页。

uploading.4e448015.gif转存失败重新上传取消

在列表页中点击某行的第一列可以进入修改页。

uploading.4e448015.gif转存失败重新上传取消

按照提示进行内容的修改,修改成功后进入列表页。在修改页点击删除可以删除一项。

uploading.4e448015.gif转存失败重新上传取消

删除:在列表页勾选想要删除的复选框,可以删除多项。

uploading.4e448015.gif转存失败重新上传取消

点击执行后进入确认页面,删除后回来列表页面。

uploading.4e448015.gif转存失败重新上传取消

调整站点信息

Admin 站点的名称信息也是可以自定义的。

未调整前如下图:

uploading.4e448015.gif转存失败重新上传取消

  • admin.site.site_header 设置网站页头
  • admin.site.site_title 设置页面标题
  • admin.site.index_title 设置首页标语

booktest / admin.py 文件中添加一下信息

from django.contrib import admin

 

admin.site.site_header = '传智书城'

admin.site.site_title = '传智书城MIS'

admin.site.index_title = '欢迎使用传智书城MIS'

刷新网站,效果如下

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 知道 admin 的配置步骤
  • 能够使用 admin 站点

调整列表页展示

学习目标:

能够调整列表页的展示效果

定义与使用 Admin 管理类

Django 提供的 Admin 站点的展示效果可以通过自定义 ModelAdmin 类来进行控制.

首先: 定义管理类需要继承自 admin.ModelAdmin 类,如下

# 导入

from django.contrib import admin

 

# 定义 admin 管理类

class BookInfoAdmin(admin.ModelAdmin):

    pass

然后: 注册后才能使用, 注册有两种方式.

如下所示:

  • 注册参数
  • # 直接注册参数
  • admin.site.register(BookInfo,BookInfoAdmin)
  • 装饰器
  • # 装饰器形式注册
  • @admin.register(BookInfo)
  • class BookInfoAdmin(admin.ModelAdmin):
  •     pass

每列展示内容设置

使用方式:

# 使用方式:

list_display=[模型字段1, 模型字段2,...]

例如:

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):

    # 每列展示内容设置

    list_display = ['id', 'btitle']

每页展示数量设置

使用方式:

# 使用方式:

list_per_page = 数量

例如:

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):

    # 每页展示数量设置

    list_per_page = 2

在浏览器中查看区域信息的列表页面,效果如下图:

uploading.4e448015.gif转存失败重新上传取消

"操作选项"的位置

使用方式:

顶部显示的属性,设置为 True 在顶部显示,设置为 False 不在顶部显示,默认为 True.

# 使用方式:

actions_on_top=True

底部显示的属性,设置为 True 在底部显示,设置为 False 不在底部显示,默认为 False.

# 使用方式:

actions_on_bottom=False

例如:

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):

    # "操作选项"的位置

    actions_on_top = True

    actions_on_bottom = True

在浏览器中刷新效果如下图:

uploading.4e448015.gif转存失败重新上传取消

在浏览器中刷新效果如下图:

uploading.4e448015.gif转存失败重新上传取消

点击列头可以进行升序或降序排列。

右侧过滤器栏

使用方式:

属性如下,只能接收字段,会将对应字段的值列出来,用于快速过滤。一般用于有重复值的字段。

# 使用方式:

list_filter=[]

例如:

打开 booktest / admin.py 文件,修改 HeroInfoAdmin 类如下:

class HeroInfoAdmin(admin.ModelAdmin):

    # 右侧过滤器栏

    list_filter = ['hbook', 'hgender']

在浏览器中刷新效果如下图:

uploading.4e448015.gif转存失败重新上传取消

搜索框

使用方式:

属性如下,用于对指定字段的值进行搜索,支持模糊查询。列表类型,表示在这些字段上进行搜索。

# 使用方式:

search_fields=[]

例如:

打开 booktest / admin.py 文件,修改 HeroInfoAdmin 类如下:

class HeroInfoAdmin(admin.ModelAdmin):

    # 搜索框

    search_fields = ['hname']

在浏览器中刷新效果如下图:

uploading.4e448015.gif转存失败重新上传取消

将方法作为列

列可以是模型字段,还可以是模型方法,要求方法有返回值。

通过设置 short_description 属性,可以设置在 admin 站点中显示的列名.

例如:

打开 booktest / models.py 文件,修改 BookInfo 类如下:

class BookInfo(models.Model):

    ...

    # 增加新的函数

    def haha(self):

        return self.bpub_date.strftime('%Y%m%d')

 

    # 设置方法字段在 admin 中显示的标题

    haha.short_description = '发布日期'

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):

    ...

    list_display = ['id','atitle','haha']

在浏览器中刷新效果如下图:

uploading.4e448015.gif转存失败重新上传取消

方法列是不能排序的,如果需要排序需要为方法指定排序依据。

admin_order_field=模型类字段

打开 booktest / models.py 文件,修改 BookInfo 类如下:

class BookInfo(models.Model):

    ...

    def haha(self):

        return self.bpub_date.strftime('%Y%m%d')

 

    haha.short_description = '发布日期'

    # 指定排序依据

    haha.admin_order_field = 'bpub_date'

在浏览器中刷新效果如下图:

uploading.4e448015.gif转存失败重新上传取消

关联对象

无法直接访问关联对象的属性或方法,可以在模型类中封装方法,访问关联对象的成员。

打开 booktest / models.py 文件,修改 HeroInfo 类如下:

class HeroInfo(models.Model):

    ...

    def read(self):

        return self.hbook.bread

 

    read.short_description = '图书阅读量'

打开 booktest / admin.py 文件,修改 HeroInfoAdmin 类如下:

class HeroInfoAdmin(admin.ModelAdmin):

    ...

    list_display = ['id', 'hname', 'hbook', 'read']

在浏览器中刷新效果如下图:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 掌握调整列表页展示的方式
  • 列表页展示各个属性简单掌握

调整编辑页展示

学习目标:

掌握调整编辑页的各方法

显示字段

属性如下:

fields=[]

点击某行 ID 的链接,可以转到修改页面,默认效果如下图:

uploading.4e448015.gif转存失败重新上传取消

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):
    # 展示的字段写入 [] 
    fields = ['btitle', 'bpub_date']

刷新浏览器效果如下图:

uploading.4e448015.gif转存失败重新上传取消

分组显示

属性如下:

fieldsets=(
    ('1标题',{'fields':('字段1','字段2')}),
    ('2标题',{'fields':('字段3','字段4')}),
)

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):
    ...
    # fields = ['btitle', 'bpub_date']
 
    # 分组展示: 
    fieldsets = (
        ('基本', {'fields': ['btitle', 'bpub_date']}),
        ('高级', {
            'fields': ['bread', 'bcomment'],
            'classes': ('collapse',)  # 是否折叠显示
        })
    )

刷新浏览器效果如下图:

uploading.4e448015.gif转存失败重新上传取消

说明:fields fieldsets 两者选一使用.

关联对象

一对多 的关系中,可以在 一端 的编辑页面中编辑 多端 的对象

嵌入多端对象的方式包括表格、块两种.

  • 类型 InlineModelAdmin:表示在模型的编辑页面嵌入关联模型的编辑。
  • 子类 TabularInline:以表格的形式嵌入。
  • 子类 StackedInline:以块的形式嵌入。

可以用块的形式嵌入:

打开 booktest / admin.py 文件,创建 HeroInfoStackInline .

class HeroInfoStackInline(admin.StackedInline):
    model = HeroInfo  # 要编辑的对象
    extra = 1  # 附加编辑的数量

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):
    ...
    inlines = [HeroInfoStackInline]

刷新浏览器效果如下图:

uploading.4e448015.gif转存失败重新上传取消

可以用表格的形式嵌入:

打开 booktest / admin.py 文件,创建 HeroInfoTabularInline .

class HeroInfoTabularInline(admin.TabularInline):
    model = HeroInfo
    extra = 1

打开 booktest / admin.py 文件,修改 BookInfoAdmin 类如下:

class BookInfoAdmin(admin.ModelAdmin):
    ...
    inlines = [HeroInfoTabularInline]

刷新浏览器效果如下图:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 修改编辑页面可以使用 fields 字段决定页面显示的内容
  • 可以通过 fieldsets 属性决定是否分组展示
  • 可以通过 inlines 属性决定是否关联加载

上传图片

学习目标:

掌握如何上传图片

准备工作

Django 有提供文件系统支持,在 Admin 站点中可以轻松上传图片。

使用 Admin 站点保存图片,需要安装 Python 的图片操作包

pip install Pillow

配置

默认情况下,Django 会将上传的图片保存在本地服务器上,需要配置保存的路径。

我们可以将上传的文件保存在静态文件目录中,如我们之前设置的 static_files 目录中在 settings.py 文件中添加如下上传保存目录信息

# 图片保存的根目录

MEDIA_ROOT=os.path.join(BASE_DIR,"static_files")

为模型类添加 ImageField 字段

我们为之前的 BookInfo 模型类添加一个 ImageFiled

class BookInfo(models.Model):

    ...

    image = models.ImageField(upload_to='booktest',

                              verbose_name='图片',

                              null=True)

upload_to 选项指明该字段的图片保存在 MEDIA_ROOT 目录中的哪个子目录

进行数据库迁移操作

# 生成迁移文件

python manage.py makemigrations

 

# 进行数据迁移

python manage.py migrate

使用 Admin 站点上传图片

进入 Admin 站点的图书管理页面,选择一个图书,能发现多出来一个上传图片的字段

uploading.4e448015.gif转存失败重新上传取消

选择一张图片并保存后,图片会被保存在 static_files / booktest/ 目录下。

在数据库中,我们能看到 image 字段被设置为图片的路径

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 掌握上传图片的步骤
  • 需要提前安装 Pillow 包
  • 在模型类中增加一个字段, 指定上传的路径

 

 

 

 

 

 

 

 

 

 

欢迎学习 Redis 课程

Redis 是一个高性能的 key-value 数据库。

学习目标

  • 能够描述出什么是 nosql
  • 能够说出 Redis 的特点
  • 能够根据参考资料修改常用 Redis 配置
  • 能够写出 Redis 中 string 类型数据的增删改查操作命令
  • 能够写出 Redis 中 hash 类型数据的增删改查相关命令
  • 能够说出 Redis 中 list 保存的数据类型
  • 能够使用 StrictRedis 对象对 string 类型数据进行增删改查
  • 能够参考课件步骤搭建 Redis 集群

 

  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

Redis 介绍

学习目标

  • 能够描述出什么是 nosql
  • 能够说出 Redis 的特点

nosql 介绍

NoSQL:一类新出现的数据库( not only sql )

  • 泛指非关系型的数据库
  • 不支持 SQL 语法
  • 存储结构跟传统关系型数据库中的那种关系表完全不同,nosql 中存储的数据都是KV形式
  • NoSQL 的世界中没有一种通用的语言,每种 nosql 数据库都有自己的 api 和语法,以及擅长的业务场景
  • NoSQL 中的产品种类相当多:
    • Redis
    • Mongodb
    • Hbase hadoop
    • Cassandra hadoop

NoSQL SQL 数据库的比较:

  • 适用场景不同:sql 数据库适合用于关系特别复杂的数据查询场景,nosql 反之
  • 事务 特性的支持:sql 对事务的支持非常完善,而 nosql 基本不支持事务
  • 两者在不断地取长补短,呈现融合趋势

Redis 简介

  • Redis 是一个开源的使用 ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从2010315日起,Redis 的开发工作由 VMware 主持。从20135月开始,Redis 的开发由 Pivotal 赞助。
  • Redis NoSQL 技术阵营中的一员,它通过多种键值数据类型来适应不同场景下的存储需求,借助一些高层级的接口使用其可以胜任,如缓存、队列系统的不同角色

Redis 特性

  • Redis 与其他 key - value 缓存产品有以下三个特点:
  • Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用.
  • Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储.
  • Redis 支持数据的备份,即 master-slave 模式的数据备份.

Redis 优势

  • 性能极高 – Redis 能读的速度是 110000次/s, 写的速度是 81000次/s .
  • 丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作.
  • 原子 – Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作全并后的原子性执行.
  • 丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性.

Redis 应用场景

  • 用来做缓存( ehcache / memcached )——redis 的所有数据是放在内存中的(内存数据库)
  • 可以在某些特定应用场景下替代传统数据库——比如社交类的应用
  • 在一些大型系统中,巧妙地实现一些特定的功能:session 共享、购物车
  • 只要你有丰富的想象力,redis 可以用在可以给你无限的惊喜…….

推荐阅读

总结:

  • 知道 nosql 的特点
  • 了解 redis 的特性和优势
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

 

 

Redis 安装

学习目标:

掌握 redis 的安装方法

安装步骤:

wget http://download.redis.io/releases/redis-x.x.x.tar.gz

uploading.4e448015.gif转存失败重新上传取消

  • step2: 解压

tar xzf redis-x.x.x.tar.gz

  • step3: 移动,放到 usr/local ⽬录下

sudo mv ./redis-x.x.x /usr/local/redis/

  • step4: 进⼊ redis ⽬录

cd /usr/local/redis/

  • step5: 生成

sudo make

uploading.4e448015.gif转存失败重新上传取消

  • step6: 测试,这段运⾏时间会较⻓

sudo make test

uploading.4e448015.gif转存失败重新上传取消

  • step7: 安装,将 redis 的命令安装到 /usr/local/bin/ ⽬录

sudo make install

  • step8: 安装完成后,我们进入目录 /usr/local/bin 中查看

cd /usr/local/bin
ls -all

uploading.4e448015.gif转存失败重新上传取消

    • redis-server redis 服务器
    • redis-cli redis 命令行客户端
    • redis-benchmark redis 性能测试工具
    • redis-check-aof AOF 文件修复工具
    • redis-check-rdb RDB 文件检索工具
  • step9: 配置⽂件,移动到 /etc/ ⽬录下
    • 配置⽂件⽬录为 /usr/local/redis/redis.conf

sudo cp /usr/local/redis/redis.conf /etc/redis/

其他补充

  • Mac 上安装 Redis:
    • 安装 Homebrew:

https://brew.sh/

    • 使用 brew 安装 Redis

https://www.cnblogs.com/cloudshadow/p/mac_brew_install_redis.html

总结:

  • 知道 ubuntu 安装 redis 的方法
  • 能够根据课件安装 redis
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

redis 配置

学习目标

能够根据参考资料修改常用 Redis 配置

配置

  • Redis 的配置信息在 /etc/redis/redis.conf 中
  • 查看

sudo vim /etc/redis/redis.conf

核心配置选项

  • 绑定 ip:如果需要远程访问,可将此⾏注释,或绑定⼀个真实 ip

bind 127.0.0.1

  • 端⼝,默认为: 6379

port 6379

  • 是否以守护进程运⾏
    • 如果以守护进程运⾏,则不会在命令⾏阻塞,类似于服务
    • 如果以⾮守护进程运⾏,则当前终端被阻塞
    • 设置为 yes 表示守护进程,设置为 no 表示⾮守护进程
    • 推荐设置为 yes

daemonize yes

  • 数据⽂件( 持久化时生成文件的名称 )

dbfilename dump.rdb

  • 数据⽂件存储路径

dir /var/lib/redis

  • ⽇志⽂件路径

logfile "/var/log/redis/redis-server.log"

  • 数据库,默认有16个

database 16

  • 主从复制,类似于双机备份. ( 配置主从服务器才用得上, 现在暂时不用 )

slaveof

参考资料

redis 配置信息http://blog.csdn.net/ljphilp/article/details/52934933

总结:

  • redis 的配置文件位于 /etc/redis/redis.conf 文件中
  • 常见的配置选项要认识
  • 常用接口为 6379
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

redis 中的服务器端和客户端

学习目标

了解 Redis 服务器端和客户端的命令

服务器端

  • 开启服务器端的命令为
  •   # 开启 redis 服务器的命令
  •   redis-server
  • 可以使⽤ help 查看帮助⽂档
  • redis-server  --help
  • 补充:

ps aux | grep redis 查看 redis 服务器进程
sudo kill -9 pid 杀死 redis 服务器
sudo redis-server /etc/redis/redis.conf 指定加载的配置文件

客户端

  • 进入 redis 客户端的命令为:
  •   # 进入 redis 客户端的命令:
  •   redis-cli
  • 可以使⽤ help 查看帮助⽂档
  • redis-cli  --help
  • 成功进入客户端后, 显示的效果:

uploading.4e448015.gif转存失败重新上传取消

  • 测试客户端是否能够连接服务端: ( 如果能够正常连接则返回: pong )

ping

uploading.4e448015.gif转存失败重新上传取消

  • 切换数据库
  •   # 选择 redis 中的数据库, num 可以从 0 - 15
  •   select  num
  • 数据库没有名称,默认有16个,通过 0-15 来标识,连接 redis 默认选择第一个数据库

select 10

uploading.4e448015.gif转存失败重新上传取消

总结:

  • redis 有一个服务端, 还有一个客户端
  • 我们需要先把服务端开启, 然后才能开启客户端.
  • 可以使用客户端连接服务端, 然后选择某一个数据库
  • redis 默认有 16个数据库, 从 0-15
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

Redis 的数据类型

学习目标

能够知道 redis 中常见的数据类型

数据结构

  • redis 是 key-value 的数据结构,每条数据都是⼀个键值对
  • 键的类型是字符串

注意:键不能重复

uploading.4e448015.gif转存失败重新上传取消

  • 值的类型分为五种:
    • 字符串 string
    • 哈希 hash
    • 列表 list
    • 集合 set
    • 有序集合 zset

数据操作行为

  • 保存
  • 修改
  • 获取
  • 删除

点击中查看命令 http://redis.cn/commands.html

重要文档

总结:

  • 知道 redis 中的五种数据类型
  • 这五种数据类型指的是: string, list, set, zset, hash
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

string 操作

学习目标:

掌握 string 类型对应的方法

string 类型简介:

  • 字符串类型是 Redis 中最为基础的数据存储类型,它在 Redis 中是以二进制存储的,这便意味着该类型可以接受任何格式的数据,如 JPEG 图像数据或 Json 对象描述信息等.
  • Redis 中字符串类型的 Value 最多可以容纳的数据长度是 512M.

添加或修改

如果设置的键不存在则为添加,如果设置的键已经存在则修改

  • 设置键值

set key value

  • 例1:设置键为 name 值为 itcast 的数据

set name itcast

uploading.4e448015.gif转存失败重新上传取消

  • 设置键值及过期时间,以秒为单位

setex key seconds value

  • 例2:设置键为 aa 值为 aa 过期时间为 3秒 的数据

setex aa 3 aa

uploading.4e448015.gif转存失败重新上传取消

  • 设置多个键值

mset key1 value1 key2 value2 ...

  • 例3:设置键为 a1 值为 python、 键为 a2 值为 java、 键为 a3 值为 c

mset a1 python a2 java a3 c

uploading.4e448015.gif转存失败重新上传取消

  • 追加值

append key value

  • 例4:向键为 a1 中追加值 haha

append a1 haha

uploading.4e448015.gif转存失败重新上传取消

获取

  • 获取:根据键获取值,如果不存在此键则返回nil

get key

  • 例5:获取键name的值

get name

  • 根据多个键获取多个值

mget key1 key2 ...

  • 例6:获取键a1、a2、a3的值

mget a1 a2 a3

uploading.4e448015.gif转存失败重新上传取消

删除

下节键的操作,删除键时会将值删除

总结:

  • 对 string 类型增加数据可以使用: set setex mset append
  • 获取 string 类型的数据可以使用: get mget
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

Redis 中和键有关的命令

学习目标:

能够知道删键的相关命令

键命令

查找键,参数持正则表达式

  • keys pattern
  • 例1:查看所有键

keys *

uploading.4e448015.gif转存失败重新上传取消

  • 例2:查看名称中包含a的键

keys a*

uploading.4e448015.gif转存失败重新上传取消

  • 判断键是否存在,如果存在返回1,不存在返回0

exists key

  • 例3:判断键a1是否存在

exists a1

uploading.4e448015.gif转存失败重新上传取消

  • 查看键对应的 value 的类型

type key

  • 例4:查看键 a1 的值类型,为 redis ⽀持的五种类型中的⼀种

type a1

uploading.4e448015.gif转存失败重新上传取消

  • 删除键及对应的值

del key1 key2 ...

  • 例5:删除键a2、a3

del a2 a3

uploading.4e448015.gif转存失败重新上传取消

  • 设置过期时间,以秒为单位
  • 如果没有指定过期时间则⼀直存在,直到使⽤DEL移除

expire key seconds

  • 例6:设置键a1的过期时间为3秒

expire a1 3

uploading.4e448015.gif转存失败重新上传取消

  • 查看有效时间,以秒为单位

ttl key

  • 例7:查看键bb的有效时间

ttl bb

uploading.4e448015.gif转存失败重新上传取消

总结:

  • redis 中键都是字符串类型, 它的相关操作很多, 这里简单列举了一部分
  • 常见的有:
    • 查看所有键: keys *
    • 判断键是否存在: exists key
    • 查看 value 的类型: type key
    • 删除键: del key
    • 设置 key : value 键值对过期: expire key 时间
    • 查看剩余时间: ttl key
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

hash 存储类型

学习目标

掌握 Redis hash 类型数据的增删改查相关命令

hash 类型简介

  • hash ⽤于存储对象,对象的结构为属性、值
  • 的类型为 string

增加、修改

  • 设置单个属性

hset key field value

  • 1:设置键 user 的属性 name itheima

hset user name itheima

  • 设置多个属性

hmset key field1 value1 field2 value2 ...

  • 2:设置键 u2 的属性 name itcast 、属性 age 11

hmset u2 name itcast age 11

uploading.4e448015.gif转存失败重新上传取消

获取

  • 获取指定键所有的属性

hkeys key

  • 3:获取键u2的所有属性

hkeys u2

uploading.4e448015.gif转存失败重新上传取消

  • 获取个属性的值

hget key field

  • 4:获取键u2属性name的值

hget u2 name

uploading.4e448015.gif转存失败重新上传取消

  • 获取多个属性的值

hmget key field1 field2 ...

  • 5:获取键 u2 属性 name age 的值

hmget u2 name age

uploading.4e448015.gif转存失败重新上传取消

  • 获取所有属性的值

hvals key

  • 6:获取键 u2 所有属性的值

hvals u2

uploading.4e448015.gif转存失败重新上传取消

删除

  • 删除整个 hash 键及值,使 del 命令
  • 删除属性,属性对应的值会被起删除

hdel key field1 field2 ...

  • 7:删除键 u2 的属性 age

hdel u2 age

uploading.4e448015.gif转存失败重新上传取消

补充:

可能出现的错误

uploading.4e448015.gif转存失败重新上传取消

MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

Redis被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用

  • 原因:
    • 强制关闭 Redis 快照导致不能持久化。
  • 解决方案:
    • 运行 config set stop-writes-on-bgsave-error no 命令后,关闭配置项 stop-writes-on-bgsave-error解决该问题。

总结:

  • hash 是 redis 中常见的数据存储类型,
  • 保存值可以使用 hset hmset
  • 获取值可以使用 hkeys hget hmget hvals
  • 删除可以使用: hdel
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

list 的相关操作

学习目标

能够说出 Redis list 操作数据的方法

list 类型

  • 列表的元素类型为 string
  • 按照插⼊顺序排序

增加

  • 在左侧插⼊数据

lpush key value1 value2 ...

  • 例1:从键为a1的列表左侧加⼊数据a 、 b 、c

lpush a1 a b c

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

  • 在右侧插⼊数据

rpush key value1 value2 ...

  • 例2:从键为a1的列表右侧加⼊数据0、1

rpush a1 0 1

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

  • 在指定元素的前或后插⼊新元素

linsert key beforeafter 现有元素 新元素

  • 例3:在键为a1的列表中元素b前加⼊3

linsert a1 before b 3

uploading.4e448015.gif转存失败重新上传取消

获取

  • 返回列表⾥指定范围内的元素
    • start、stop为元素的下标索引
    • 索引从左侧开始,第⼀个元素为0
    • 索引可以是负数,表示从尾部开始计数,如-1表示最后⼀个元素

lrange key start stop

  • 例4:获取键为a1的列表所有元素

lrange a1 0 -1

uploading.4e448015.gif转存失败重新上传取消

修改索引位置的值

  • 索引从左侧开始,第⼀个元素为0
  • 索引可以是负数,表示尾部开始计数,如-1表示最后⼀个元素

lset key index value

  • 例5:修改键为a1的列表中下标为1的元素值为z

lset a1 1 z

uploading.4e448015.gif转存失败重新上传取消

删除

  • 删除指定元素
    • 将列表中前 count 次出现的值为 value 的元素移除
    • count > 0: 从头往尾移除
    • count < 0: 从尾往头移除
    • count = 0: 移除所有

lrem key count value

  • 例6.1:向列表a2中加⼊元素a、b、a、b、a、b

lpush a2 a b a b a b

uploading.4e448015.gif转存失败重新上传取消

  • 例6.2:从a2列表右侧开始删除2个b

lrem a2 -2 b

  • 例6.3:查看列表a2的所有元素

lrange a2 0 -1

uploading.4e448015.gif转存失败重新上传取消

截取

  • 截取 在[ start stop ]区间内的元素,区间外的元素全部删除

ltrim key start stop

总结:

  • list 插入数据的方法主要有: lpush rpush linsert
  • 获取数据主要有 lrange
  • 修改元素数据使用 lset
  • 删除元素数据: lrem
  • 截取元素: ltrim
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

Set 集合类型

学习目标:

掌握 set 类型的操作方法

set 集合特点:

  • ⽆序集合
  • 元素为 string 类型
  • 元素具有唯⼀性,不重复
  • 说明:对于集合没有修改操作

增加

  • 添加元素

sadd key member1 member2 ...

  • 例1:向键a3的集合中添加元素zhangsan、lisi、wangwu

sadd a3 zhangsan sili wangwu

uploading.4e448015.gif转存失败重新上传取消

获取

  • 返回所有的元素

smembers key

  • 例2:获取键a3的集合中所有元素

smembers a3

uploading.4e448015.gif转存失败重新上传取消

删除

  • 删除指定元素

srem key

  • 例3:删除键a3的集合中元素wangwu

srem a3 wangwu

uploading.4e448015.gif转存失败重新上传取消

总结:

  • set 集合增加元素的方法是: sadd
  • set 集合获取元素的方法是: smembers
  • set 集合删除元素的方法是: srem
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

zset 类型

学习目标:

掌握 zset 类型的操作方法

zset 类型特点

  • sorted set,有序集合
  • 元素为 string 类型
  • 元素具有唯⼀性,不重复
  • 每个元素都会关联⼀个 double 类型的 score,表示权重,通过权重将元素从⼩到⼤排序
  • 说明:没有修改操作

增加

  • 添加

zadd key score1 member1 score2 member2 ...

  • 例1:向键 a4 的集合中添加元素 lisi、wangwu、zhaoliu、zhangsan,权重分别为4、5、6、3

zadd a4 4 lisi 5 wangwu 6 zhaoliu 3 zhangsan

获取

  • 返回指定范围内的元素
  • start、stop 为元素的下标索引
  • 索引从左侧开始,第⼀个元素为 0
  • 索引可以是负数,表示从尾部开始计数,如-1表示最后⼀个元素

zrange key start stop

  • 例2:获取键 a4的集合中所有元素

zrange a4 0 -1

uploading.4e448015.gif转存失败重新上传取消

  • 返回 score值在 min和 max之间的成员

zrangebyscore key min max

  • 例3:获取键 a4的集合中权限值在5和6之间的成员

zrangebyscore a4 5 6

uploading.4e448015.gif转存失败重新上传取消

  • 返回成员member的score值

zscore key member

  • 例4:获取键a4的集合中元素zhangsan的权重

zscore a4 zhangsan

uploading.4e448015.gif转存失败重新上传取消

删除

  • 删除指定元素

zrem key member1 member2 ...

  • 例5:删除集合a4中元素zhangsan

zrem a4 zhangsan

uploading.4e448015.gif转存失败重新上传取消

  • 删除权重在指定范围的元素

zremrangebyscore key min max

  • 例6:删除集合a4中权限在5、6之间的元素

zremrangebyscore a4 5 6

uploading.4e448015.gif转存失败重新上传取消

总结:

  • zset 类型是有序集合
  • 增加数据使用: zadd
  • 获取数据使用: zrange zrangebyscore zscore
  • 删除数据使用: zrem zremrangebyscore
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

Python redis 的交互

学习目标:

掌握 redis python 的交互方式

安装包

安装 Redis 的有3种方式https://github.com/andymccurdy/redis-py

  • 第一种:进⼊虚拟环境,联⽹安装包redis

pip install redis

  • 第二种:进⼊虚拟环境,联⽹安装包 redis

easy_install redis

  • 第三种:到中⽂官⽹-客户端下载 redis 包的源码,使⽤源码安装

一步步执行:

wget https://github.com/andymccurdy/redis-py/archive/master.zip
unzip master.zip
cd redis-py-master
sudo python setup.py install

模块

模块

# 模块

 

from  redis  import  StrictRedis

这个模块中提供了 StrictRedis 对象于连接 redis 服务器

并按照不同类型提供 了不同法,进交互操作

准备

在桌面上创建 redis 目录

使用 pycharm 打开 redis 目录

创建 redis_string.py 文件

# 模块

from redis import StrictRedis

 

if __name__=="__main__":

    try:

        # 创建 StrictRedis 对象,与 redis 服务器建连接

        sr = StrictRedis()

 

    except Exception as e:

        print(e)

string-增加

set,添加键、值,如果添加成功则返回 True,如果添加失败则返回 False

编写代码如下:

# 模块

from redis import StrictRedis

 

if __name__=="__main__":

    try:

        # 创建 StrictRedis 对象,与 redis 服务器建连接

        sr = StrictRedis()

 

        # 添加键 name,值为 itheima

        result = sr.set('name','黑马')

 

        #输出响应结果,如果添加成功则返回 True,否则返回 False

        print(result)

 

    except Exception as e:

        print(e)

string-获取

get,添加键对应的值,如果键存在则返回对应的值,如果键不存在则返回 None

编写代码如下:

# 模块

from redis import StrictRedis

 

if __name__=="__main__":

    try:

        # 创建 StrictRedis 对象,与 redis 服务器建连接

        sr = StrictRedis()

 

        # 获取键 name 的值

        result = sr.get('name')

 

        # 输出键的值,如果键不存在则返回 None

        print(result)

 

    except Exception as e:

        print(e)

string-修改

set,如果键已经存在则进修改,如果键不存在则进添加

编写代码如下:

# 模块

from redis import StrictRedis

 

if __name__=="__main__":

    try:

        # 创建 StrictRedis 对象,与 redis 服务器建连接

        sr = StrictRedis()

 

        # 设置键 name 的值,如果键已经存在则进修改,如果键不存在则进添加

        result = sr.set('name', '传智')

 

        # 输出响应结果,如果操作成功则返回 True,否则返回 False

        print(result)

 

    except Exception as e:

        print(e)

string-删除

delete,删除键及对应的值,如果删除成功则返回受影响的键数,否则则返回 0

编写代码如下:

# 模块

from redis import StrictRedis

 

if __name__=="__main__":

    try:

        # 创建 StrictRedis 对象,与 redis 服务器建连接

        sr = StrictRedis()

 

        # 设置键 name 的值,如果键已经存在则进修改,如果键不存在则进添加

        result = sr.delete('name')

 

        # 输出响应结果,如果删除成功则返回受影响的键数,否则则返回 0

        print(result)

 

    except Exception as e:

        print(e)

获取键

keys,根据正则表达式获取键

编写代码如下

# 模块

from redis import StrictRedis

 

if __name__=="__main__":

    try:

        # 创建 StrictRedis 对象,与 redis 服务器建连接

        sr = StrictRedis()

 

        # 获取所有的键

        result = sr.keys()

 

        # 输出响应结果,所有的键构成个列表,如果没有键则返回 []

        print(result)

 

    except Exception as e:

        print(e)

总结:

  • 项目中想要使用 redis 我们需要安装: 三种安装方式
  • 使用之前, 需要导入模块: from redis import StrictRedis
  • 创建 redis 对象: obj = StrictRedis( )
  • 使用对象增加数据: obj.set( 'key', 'value' )
  • 使用对象获取数据: obj.get( 'key' )
  • 使用对象修改数据: obj.set( 'key' , 'value' )
  • 使用对象删除数据: obj.delete( 'key' )
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

StrictRedis 对象

学习目标:

掌握 StrictRedis 对象的相关方法

StrictRedis 对象补充

  • 通过 init 创建对象,指定参数 host、port 与指定的服务器和端⼝连接
  • host 默认为 localhost,port 默认为 6379,db 默认为 0
# 创建对象
sr = StrictRedis( host='localhost', port=6379,  db=0 )
 
# 简写
sr=StrictRedis()

StrictRedis 对象函数说明

根据不同的类型,拥有不同的实例法可以调

与前学的 redis 命令对应,法需要的参数与命令的参数

string

  • set
  • setex
  • mset
  • append
  • get
  • mget
  • key

keys

  • exists
  • type
  • delete
  • expire
  • getrange
  • ttl

hash

  • hset
  • hmset
  • hkeys
  • hget
  • hmget
  • hvals
  • hdel

list

  • lpush
  • rpush
  • linsert
  • lrange
  • lset
  • lrem

set

  • sadd
  • smembers
  • srem

zset

  • zadd
  • zrange
  • zrangebyscore
  • zscore
  • zrem
  • zremrangebyscore

总结:

  • 知道我们使用 StrictRedis 创建对象的时候, 可以指定一些参数
  • 我们之前讲解的 redis 命令, 在代码部分也可以同步实现
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

redis 主从

学习目标

能够根据课件中的步骤搭建 Redis 的主从

主从概念

  • ⼀个 master 可以拥有多个 slave,⼀个 slave ⼜可以拥有多个 slave,如此下去,形成了强⼤的多级服务器集群架构
  • master 用来写数据,slave 用来读数据,经统计:网站的读写比率是10:1
  • 通过主从配置可以实现读写分离

uploading.4e448015.gif转存失败重新上传取消

  • master slave 都是一个 redis 实例( redis 服务)

主从配置

配置主

  • 查看当前主机的 ip 地址

ifconfig

uploading.4e448015.gif转存失败重新上传取消

  • 修改 /etc/redis/redis.conf 文件

cd /etc/redis/

sudo vi redis.conf

bind 172.16.238.128

  • 重启 redis.conf这个配置文件对应的 redis 服务

sudo service redis stop
sudo redis-server redis.conf

配置从

  • 复制 /etc/redis/redis.conf 文件

/etc/redis/ 目录下复制:

sudo cp redis.conf ./slave.conf

  • 修改 redis/slave.conf 文件

sudo vi slave.conf

  • 编辑内容

bind 172.16.238.128

port 6378

slaveof 172.16.238.128 6379

  • 重启 slave.conf 这个配置文件对应的 redis 服务

sudo redis-server slave.conf

  • 查看主从关系

redis-cli -h 172.16.238.128 info Replication

uploading.4e448015.gif转存失败重新上传取消

数据操作

  • master slave 分别执 info 命令,查看输出信息 进入主客户端

redis-cli -h 172.16.238.128 -p 6379

  • 进入从的客户端

redis-cli -h 172.16.238.128 -p 6378

  • master 上写数据

set aa aa

uploading.4e448015.gif转存失败重新上传取消

  • slave 读数据

get aa

总结:

  • redis 可以搭建主从数据库, 从而实现读写分离
  • 搭建主从数据库的方法, 要能够根据上面的步骤实现
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

集群

学习目标:

了解集群的概念

为什么要有集群

  • 之前我们已经讲了主从的概念,一主可以多从,如果同时的访问量过大( 1000w ),主服务肯定就会挂掉,数据服务就挂掉了或者发生自然灾难
  • 大公司都会有很多的服务器(华东地区、华南地区、华中地区、华北地区、西北地区、西南地区、东北地区、台港澳地区机房)

集群的概念

  • 集群是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。 uploading.4e448015.gif转存失败重新上传取消

当请求到来首先由负载均衡服务器处理,把请求转发到另外的一台服务器上。

redis 集群

  • 分类
    • 软件层面
    • 硬件层面
  • 软件层面:只有一台电脑,在这一台电脑上启动了多个 redis 服务。

uploading.4e448015.gif转存失败重新上传取消

  • 硬件层面:存在多台实体的电脑,每台电脑上都启动了一个redis或者多个redis服务。

uploading.4e448015.gif转存失败重新上传取消

搭建集群

  • 当前拥有两台主机 172.16.238.128、 172.16.238.129,这⾥的 IP 在使⽤时要改为实际值

参考阅读

总结:

  • 掌握集群的概念
  • 了解搭建集群的方式以及集群的分类
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

集群中机器的配置

学习目标:

掌握集群中机器的配置方法

  • 在演示中,172.16.238.128 为当前 ubuntu 机器的 ip
  • 在 172.16.238.128 上进⼊ Desktop ⽬录,创建 redis集群 ⽬录
  • 0.conf 编辑内容如下
  • port 7000
  • bind 172.16.238.128
  • daemonize yes
  • pidfile 7000.pid
  • cluster-enabled yes
  • cluster-config-file 7000_node.conf
  • cluster-node-timeout 15000
  • appendonly yes
  • 1.conf 编辑内容如下
  • port 7001
  • bind 172.16.238.128
  • daemonize yes
  • pidfile 7001.pid
  • cluster-enabled yes
  • cluster-config-file 7001_node.conf
  • cluster-node-timeout 15000
  • appendonly yes
  • 2.conf 编辑内容如下
  • port 7002
  • bind 172.16.238.128
  • daemonize yes
  • pidfile 7002.pid
  • cluster-enabled yes
  • cluster-config-file 7002_node.conf
  • cluster-node-timeout 15000
  • appendonly yes
  • 3.conf :
  • port 7003
  • bind 172.16.238.128
  • daemonize yes
  • pidfile 7003.pid
  • cluster-enabled yes
  • cluster-config-file 7003_node.conf
  • cluster-node-timeout 15000
  • appendonly yes
  • 4.conf :
  • port 7004
  • bind 172.16.238.128
  • daemonize yes
  • pidfile 7004.pid
  • cluster-enabled yes
  • cluster-config-file 7004_node.conf
  • cluster-node-timeout 15000
  • appendonly yes
  • 5.conf :
  • port 7005
  • bind 172.16.238.128
  • daemonize yes
  • pidfile 7005.pid
  • cluster-enabled yes
  • cluster-config-file 7005_node.conf
  • cluster-node-timeout 15000
appendonly yes

总结:三个件的配置区别在 portpidfilecluster-config-file 三项

  • 使⽤配置⽂件启动 redis 服务
  • redis-server 0.conf
  • redis-server 1.conf
  • redis-server 2.conf
  • redis-server 3.conf
  • redis-server 4.conf
  • redis-server 5.conf

 

总结:

  • 能够配置机器
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

创建集群

学习目标:

掌握创建集群的方法

创建集群

  • redis 的安装包中包含了 redis-trib.rb,⽤于创建集群
  • 将命令复制,这样可以在任何⽬录下调⽤此命令
  • sudo  cp  /usr/share/doc/redis-tools/examples/redis-trib.rb  /usr/local/bin/
  • 安装 ruby 环境,因为 redis-trib.rb 是⽤ ruby 开发的

sudo apt-get install ruby

  • 在提示信息处输⼊ y,然后回⻋继续安装 uploading.4e448015.gif转存失败重新上传取消
  • 运⾏如下命令创建集群
  • redis-trib.rb create --replicas 1 172.16.238.128:7000 172.16.238.128:7001 172.16.238.128:7002 172.16.238.128:7003 172.16.238.128:7004 172.16.238.128:7005
  • 执⾏上⾯这个指令在某些机器上可能会报错,主要原因是由于安装的 ruby 不是最 新版本!
  • 天朝的防⽕墙导致⽆法下载最新版本,所以需要设置 gem 的源
  • 解决办法如下
  • -- 先查看⾃⼰ gem 源是什么地址
  • gem source -l -- 如果是https://rubygems.org/ 就需要更换
  • -- 更换指令为
  • gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
  • -- 通过 gem 安装 redis 的相关依赖
  • sudo gem install redis
  • -- 然后重新执指令

uploading.4e448015.gif转存失败重新上传取消

redis-trib.rb create --replicas 1 172.16.238.128:7000 172.16.238.128:7001 172.16.238.128:7002 172.16.238.128:7003 172.16.238.128:7004 172.16.238.128:7005

  • 提示如下主从信息,输⼊ yes 后回⻋ uploading.4e448015.gif转存失败重新上传取消
  • 提示完成,集群搭建成功

数据验证

  • 根据上图可以看出,当前搭建的主服务器为7000、7001、7003,对应的从服务器是7004、7005、7002
  • 在172.16.179.131机器上连接7002,加参数-c表示连接到集群

redis-cli -h 172.16.238.128 -c -p 7002

  • 写⼊数据

set name itheima

  • ⾃动跳到了7003服务器,并写⼊数据成功 uploading.4e448015.gif转存失败重新上传取消
  • 在7003可以获取数据,如果写入数据又重定向到7000(负载均衡) uploading.4e448015.gif转存失败重新上传取消

服务器写数据的判断

CRC16

  • redis cluster 在设计的时候,就考虑到了去中⼼化,去中间件,也就是说,集群中 的每个节点都是平等的关系,都是对等的,每个节点都保存各⾃的数据和整个集 群的状态。每个节点都和其他所有节点连接,⽽且这些连接保持活跃,这样就保 证了我们只需要连接集群中的任意⼀个节点,就可以获取到其他节点的数据
  • Redis 集群没有并使⽤传统的⼀致性哈希来分配数据,⽽是采⽤另外⼀种叫做哈希槽 (hash slot)的⽅式来分配的。redis cluster 默认分配了 16384 个 slot,当我们 set ⼀个 key 时,会⽤ CRC16 算法来取模得到所属的 slot,然后将这个 key 分到哈 希槽区间的节点上,具体算法就是:CRC16 ( key ) % 16384。所以我们在测试的 时候看到set 和 get 的时候,直接跳转到了7000端⼝的节点
  • Redis 集群会把数据存在⼀个 master 节点,然后在这个 master 和其对应的salve 之间进⾏数据同步。当读取数据时,也根据⼀致性哈希算法到对应的 master 节 点获取数据。只有当⼀个master 挂掉之后,才会启动⼀个对应的 salve 节点,充 当 master
  • 需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当 活的主节点数于总节点数的⼀半时,整个集群就法提供服务了

总结:

  • 掌握创建集群的方法, 另外知道保存数据的判断依据
  • 课程介绍
  • 1. Redis
    • 1.1. 安装
    • 1.2. 配置
    • 1.3. 服务端和客户端命令
    • 1.4. 数据操作
      • 1.4.1. string
      • 1.4.2. 键命令
      • 1.4.3. hash
      • 1.4.4. list
      • 1.4.5. set
      • 1.4.6. zset
    • 1.5. Python交互
      • 1.5.1. StrictRedis
    • 1.6. 搭建主从
    • 1.7. 搭建集群
      • 1.7.1. 配置机器1
      • 1.7.2. 配置机器2
      • 1.7.3. 创建集群
      • 1.7.4. Python交互

Python 交互

学习目标:

能够使用集群与 python 进行交互

  • 安装包如下

pip install redis-py-cluster

from rediscluster import StrictRedisCluster

if __name__ == '__main__':

  try:

    # 构建所有的节点,Redis会使CRC16算法,将键和值写到某个节点上

    startup_nodes = [

        {'host': '172.16.238.128', 'port': '7000'},

        {'host': '172.16.238.128', 'port': '7003'},

        {'host': '172.16.238.128', 'port': '7001'},

    ]

    # 构建StrictRedisCluster对象

    src=StrictRedisCluster(startup_nodes=startup_nodes,decode_responses=True)

    # 设置键为name、值为itheima的数据

    result=src.set('name','itheima')

    print(result)

    # 获取键为name

    name = src.get('name')

    print(name)

  except Exception as e:

    print(e)

总结:

  • 掌握与 python 的交互方法

 

 

 

 

Git 引入

学习目标:

知道我们引入 git 的目的

以及能够知道 git 可以使用的场景

场景

如果遇到文本需要修改很多次, 并且都需要做备份和记录的时候怎么办呢?

我们可以使用 git

它能够帮助我们记录各个不同的版本. 并且可以实时的把各个不同的版本进行整合记录.

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 我们使用 git 可以做版本的控制
  • 也可以使用 git 记录每次修改的内容. 并且进行整合

Git 简介

学习目标:

知道 git 的定义以及大概流程

定义

Git 是目前世界上最先进的分布式版本控制系统(没有之一)

源代码管理的目的

  • 方便多人协同开发
  • 方便版本控制

Git 的诞生历史( 了解 )

  • 作者是 Linux 之父:Linus Benedict Torvalds
  • 当初开发 Git 仅仅是为了辅助 Linux 内核的开发(管理源代码)

uploading.4e448015.gif转存失败重新上传取消

git 开发时间表

  • git 的产生是 Linux Torvals 在无奈被逼的情况下创造的,我看了一下时间历程:
    • 2005 4 3 日开始开发 git
    • 2005 4 6 日项目发布
    • 2005 4 7 Git 开始作为自身的版本控制工具
    • 2005 4 18 日发生第一个多分支合并
    • 2005 4 29 Git 的性能达到 Linux 预期
    • 2005 7 26 Linux 功成身退,将 Git 维护权交给 Git 另一个主要贡献者 Junio C Hamano,直到现在

Git 迅速成为最流行的分布式版本控制系统,尤其是 2008 年,GitHub 网站上线了,它为开源项目免费提供 Git 存储,无数开源项目开始迁移至 GitHub,包括 jQueryPHPRuby 等等

Git 管理源代码特点

  • Git是分布式管理.服务器和客户端都有版本控制能力,都能进行代码的提交、合并、...

uploading.4e448015.gif转存失败重新上传取消

  • .Git会在根目录下创建一个.git隐藏文件夹,作为本地代码仓库

uploading.4e448015.gif转存失败重新上传取消

Git 操作流程图解

Git服务器 --> 本地仓库 --> 客户端 --> 本地仓库 --> Git服务器

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 使用 git 可以实现源代码的管理
  • git 的特点是分布式管理系统
  • git 可以实现多人协同开发, 并且能够方便管理各个版本

Git 中的模块

学习目标:

掌握 git 中的三个区域以及各自的特点

工作区

git 中的工作区指的就是我们平时写代码的区域,

例如:

编译器中( pycharm, vscode ).

作用:

工作区的主要作用就是对文件进行 添加修改删除等操作

暂存区

git 中临时存储数据的一个区域, 我们成为暂存区.

特点:

这个区域我们一般看不到. 但他实际存在. 我们可以把代码临时保存在这里. 也可以撤销

主要作用是:

为了让用户能够把数据进行长久存储前, 可以进行筛查, 反悔等操作, 而创建的区域

仓库区

git 中本地进行长久存储的一个区域

特点:

主要存储一个小阶段的成果. 防止丢失

我们一般把暂存区的内容存储到这里. 以方便以后查看.

暂存区的内容存储到本地仓库区后, 暂存区的内容将会销毁.

我们可以在本地仓库区存放多个版本的信息. 并且可以在不同的版本中进行跳转.

提示:本地仓库是个 .git 隐藏文件

关联关系

上面三个区的关系, 我们可以通过如下的图片查看:

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 知道 git 在本地有三个区域, 分别为: 工作区, 暂存区, 仓库区
  • 工作区是写代码的区域
  • 暂存区是临时储存数据的区域
  • 仓库区是在本地长久保存数据的区域

Git 单人操作---准备阶段

学习目标:

知道 git 的安装和配置

git 安装

安装 git

# 安装 git 
sudo apt-get install git
 
# 密码:chuanzhi

参数解读:

sudo : 超级管理员权限, 如果使用该权限, 需要添加密码

apt-get : 包管理工具

install : 安装的意思

uploading.4e448015.gif转存失败重新上传取消

查看安装结果

想要查看 git 是否安装成功, 需要我们调用 git 命令:

git

调用该命令后, 如果出现大篇幅的命令, 代表安装 git 成功.

如果出现 'git 不是内部或外部命令' 字样. git 安装失败

创建项目

在桌面创建 test 文件夹, 作为项目文件

mkdir Desktop/test

创建本地仓库

进入到刚刚创建的文件中 : cd Desktop/test/

初始化 git , 从而创建本地仓库

# 初始化 git 得到本地仓库
 
git init

补充:

进入到 test,并创建本地仓库 .git

新创建的本地仓库.git是个空仓库

uploading.4e448015.gif转存失败重新上传取消

创建本地仓库.git

uploading.4e448015.gif转存失败重新上传取消

配置个人信息

# 配置个人的用户名: 
git config user.name '张三'
# 配置个人的邮箱地址: 
git config user.email 'zhangsan@163.com'

uploading.4e448015.gif转存失败重新上传取消

配置个人信息后

uploading.4e448015.gif转存失败重新上传取消

默认不配置的话,会使用全局配置里面的用户名和邮箱 全局 git 配置文件路径:~/.gitconfig

总结:

  • git 的安装使用的命令是: sudo apt-get install git
  • 查看 git 是否安装成功也可以调用 git 命令
  • 安装完 git 之后会生成一个 .git 文件
  • 我们可以配置当前用户的对应信息, 配置的时候使用 config 命令

Git 单人操作第一部分

学习目标:

能够掌握 git 的相关常见操作

增加文件

  • 在项目文件 test里面创建 login.py 文件,用于版本控制演示

uploading.4e448015.gif转存失败重新上传取消

查看文件状态

# 使用方式:
 
git status

敲这个命令后:

  • 如果为红色, 表示新建的文件或者修改的文件, 在工作区.
  • 如果为绿色, 表示文件在暂存区

uploading.4e448015.gif转存失败重新上传取消

工作区提交到暂存区

# 使用方式: 
# 第一种提交方式: 
git add .
 
 
# 第二种提交方式:
git  add  login.py

uploading.4e448015.gif转存失败重新上传取消

暂存区提交到仓库区

# 使用方式: 
 
git commit -m  '描述信息'
  • commit 会进行一次本地仓库提交
  • -m 后面是添加的是本次提交的描述信息

uploading.4e448015.gif转存失败重新上传取消

修改工作区, 再提交

# 提交到暂存区: 
git add .
 
# 提交到本地仓库区: 
git commit -m "版本描述"
  • 代码编辑完成后即可进行 addcommit 操作

uploading.4e448015.gif转存失败重新上传取消

查看提交的历史记录

# 使用方式: 
# 第一种: 
git log
 
# 第二种: 
git reflog

uploading.4e448015.gif转存失败重新上传取消

git reflog 可以查看所有分支的所有操作记录(包括 commit reset 的操作),包括已经被删除的commit 记录,git log 则不能察看已经删除了的 commit 记录

总结:

  • 无论对工作区的文件进行了增加, 删除, 还是修改操作. 都可以使用 git 提交到暂存区
  • 提交到暂存区使用: git add .
  • 提交到本地仓库区使用: git commit -m '信息'
  • 查看 git 的状态可以使用: git status
  • 查看历史提交记录可以使用: git log 或是 git reflog

Git 单人操作第二部分

学习目标:

掌握 git 版本回退和代码撤销的方法

回退版本

方案一:

# 使用方式: 
 
git reset --hard 版本
  • HEAD 表示当前最新版本
  • HEAD^表示当前最新版本的前一个版本
  • HEAD^^ 表示当前最新版本的前两个版本,以此类推...
  • HEAD~1 表示当前最新版本的前一个版本
  • HEAD~10表示当前最新版本的前10个版本,以此类推...

例如:

git  reset  --hard  HEAD^

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

方案二:

当版本非常多时可选择的方案

通过每个版本的版本号回退到指定版本

git reset --hard 版本号

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

工作区代码撤销

# 使用方式: 
 
git checkout 文件名
  • 只能撤销工作区、暂存区的代码, 不能撤销仓库区的代码
  • 撤销仓库区的代码就相当于回退版本操作

例如:

新加代码 num3 = 30 ,不 add 到暂存区,保留在工作区

git checkout 文件名

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

暂存区代码撤销

新加代码 num3 = 30,并 add 到暂存区

# 第一步:将暂存区代码撤销到工作区
git reset HEAD  文件名
 
# 第二步:撤销工作区代码
git checkout 文件名

uploading.4e448015.gif转存失败重新上传取消

总结:

  • 回退到别的版本使用: git reset --hard 版本/版本号
  • 撤销工作区的代码: git checkout 文件名
  • 撤销暂存区的代码: git reset HEAD 文件名git checkout 文件名

Git 远程仓库

学习目标:

掌握远端仓库的创建和克隆方式

准备工作:

Github 网站上创建远程仓库

  • 注册 Github 账号 https://github.com/
  • 准备经理的文件夹 Desktop/manager/
  • 准备张三的文件夹 Desktop/zhangsan/

创建远程仓库

提示:

Github 网站作为远程代码仓库时的操作和本地代码仓库一样的.

只是仓库位置不同而已!

uploading.4e448015.gif转存失败重新上传取消

编辑仓库信息

uploading.4e448015.gif转存失败重新上传取消

查看远端仓库

uploading.4e448015.gif转存失败重新上传取消

将远程仓库拷贝到本地

远程仓库地址 https://github.com/zhangxiaochuZXC/test007.git

uploading.4e448015.gif转存失败重新上传取消

总结:

  • Github 是世界上最大的源代码开放平台
  • 我们可以在 Github 或者是码云上创建远程仓库
  • 创建远程仓库需要添加一些信息, 如上图所示
  • 创建好远程仓库后, 可以使用 git clone 地址 命令拷贝到本地

使用 SSH 克隆项目

学习目标:

掌握 SSH 克隆项目的配置和方法

了解 SSH 登录方式

我们之前已经可以通过 https 的方式, Github 获取远端仓库了:

git clone https://地址

除此以外, 我们还可以使用 SSH 的方式从 Github 上获取远端仓库.

如果想要使用该功能, 我们需要把 SSH 的公钥添加到 Github .

那么就要把这台电脑的 SSH 公钥添加到这个 Github 账户上

Github 上配置 SSH 公钥

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

修改电脑端 git 配置

在电脑上配置 Github 的注册邮箱和用户名

# 在命令行调用如下命令:

 

vim .gitconfig

# 修改下列字段:

 

[user]

    email = 邮箱@163.com

    name = 注册的 github 名称

uploading.4e448015.gif转存失败重新上传取消

生成 SSH 公钥

# 调用该命令, 生成 SSH 公钥

 

ssh-keygen -t rsa -C "hujunkai-creator@qq.com"

 

uploading.4e448015.gif转存失败重新上传取消

查看生成的公钥信息:

# 使用该命令查看公钥文件:

cat ~/.ssh/id_rsa.pub

完善 Github SSH 公钥信息

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

补充:删除旧的秘钥

删除~/.ssh目录,这里存储了旧的密钥

rm -r .ssh

使用 SSH 克隆远端项目到本地

复制 Github SSH 的对应地址, 使用 git clone 的命令克隆到本地:

# 使用方法:

 

git  clone  git@github.com:hjokerkevin/kevin.git

总结:

  • 知道从 Github 网站克隆项目的两种方式: https 和 SSH
  • 使用 SSH 需要把生成的公钥内容拷贝到 Github 中
  • 无论是 https 还是 SSH 克隆项目使用的命令都是 git clone 地址

给不同用户克隆项目

学习目标:

掌握如何给不同的用户克隆同一个项目

给经理克隆远端项目

立项:克隆远程仓库+配置身份信息+创建项目+推送项目到远程仓库

克隆远程仓库的命令

# 克隆远端的项目到本地
# 可以使用 HTTPS
cd Desktop/manager/
git clone https://github.com/zhangxiaochuZXC/test007.git
 
# 也使用 SSH
cd Desktop/manager/
git clone git@github.com:Fly744055970/test002.git

克隆远程仓库到本地

uploading.4e448015.gif转存失败重新上传取消

克隆成功后查看经理的文件

uploading.4e448015.gif转存失败重新上传取消

配置经理身份信息

# 进入经理的工程中
cd Desktop/manager/test007/
 
# 配置经理的身份信息
git config user.name '经理'
git config user.email 'manager@163.com'

uploading.4e448015.gif转存失败重新上传取消

给张三克隆远端项目

获取项目:克隆项目到本地、配置身份信息

克隆项目到本地

# 进入张三的文件夹中
cd Desktop/zhangsan/
 
# 克隆远端的项目到本地
git clone https://github.com/zhangxiaochuZXC/test007.git

uploading.4e448015.gif转存失败重新上传取消

克隆成功后查看张三的文件

uploading.4e448015.gif转存失败重新上传取消

配置张三身份信息

# 进入张三的工程中
cd Desktop/zhangsan/test007/
 
# 配置张三的身份信息
git config user.name '张三'
git config user.email 'zhangsan@163.com'

张三身份信息配置成功后即可跟经理协同开发同一个项目

经理修改工程

经理在工程中增加了新的文件, 并在其中添加了代码

uploading.4e448015.gif转存失败重新上传取消

推送项目到远程仓库

# 工作区添加到暂存区
git add .
 
# 暂存区提交到仓库区
git commit -m '立项'
 
# 推送到远程仓库
git push

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

  • push 的时候需要设置账号与密码,该密码则是 github 的账号与密码
    • 如果在每次 push 都需要设置账号与密码,那么可以设置记住密码
    • # 设置记住密码(默认15分钟):
    • git cnfig --glbal credential.helper cache
    •  
    • # 如果想自己设置时间,可以这样做(1小时后失效)
    • git cnfig credential.helper 'cache --timeut=3600'
    •  
    • # 长期存储密码:
    • git cnfig --glbal credential.helper stre

在以后的项目开发过程中,Pycharm 可以自动记住密码

张三获取修改后的工程

经理已经修改了远端的工程, 所以张三可以拉取远端最新的工程到本地

# 调用该命令可以拉取远端工程: 
git  pull

总结:

  • 我们可以在不同用户的电脑上克隆同一份远端项目
  • 克隆的远端项目可以进行修改, 修改完成后, 我们也可以进行推送. 推送到远端
  • 可以使用多人共同开发一个项目

多人协同开发

学习目标:

掌握多人协同开发的方法

修改张三的代码并推送到远端

  • 进入张三本地仓库:cd Desktop/zhangsan/test007
  • 编辑代码:num1 = 10
  • 本地仓库记录版本:

git add .

git commit -m '第一个变量'

  • git commit -am '第一个变量'`
  • 推送到远程仓库:git push

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

经理拉取远端代码到本地

经理想要获得张三提供的内容, 需要调用拉取的命令:

# 拉取远端代码到本地:

 

git pull

修改经理的代码并推送到远端

进入经理本地仓库: cd Desktop/manager/test007/

编辑代码: num2 = 20

本地仓库记录版本:

git add .

git commit -m '第二个变量'

推送到远程仓库:git push

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消.

uploading.4e448015.gif转存失败重新上传取消

张三拉取远端代码到本地

本次可以把 num2 同步到张三的本地仓库

uploading.4e448015.gif转存失败重新上传取消

按照以上步骤循环操作,即可实现基本的协同开发

总结:

  • 要使用 git 命令操作仓库,需要进入到仓库内部
  • 要同步远端代码执行: git pull
  • 本地仓库记录版本执行: git commit -am '版本描述'
  • 推送代码到服务器执行:git push
  • 编辑代码前要先 pull,编辑完再 commit,最后推送是 push

代码冲突

学习目标:

掌握冲突产生的原因和解决方法

代码冲突产生的原因

设想一下:

如果张三经理都修改了同一行代码, 并且都进行了提交, 那么服务端应该保存谁的代码呢?

这时就会产生冲突

  • 提示:多人协同开发时,避免不了会出现代码冲突的情况
  • 原因:多人同时修改了同一个文件
  • 危害:会影响正常的开发进度
  • 注意:一旦出现代码冲突,必须先解决再做后续开发

演示冲突

张三先编辑文件中的代码

  • 进入张三本地仓库:cd Desktop/zhangsan/test007
  • 拉取服务器最新代码:git pull
  • 编辑代码:num3 = 30
  • 本地仓库记录版本:

git add .

git commit -m '第三个变量'

  • 推送到服务器仓库:git push
  • 张三本地仓库和远程仓库代码如下:

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

经理后编辑文件中的代码

  • 进入经理本地仓库:cd Desktop/manager/test007/
  • 编辑代码:num3 = 300
  • 本地仓库记录版本:

git add .

git commit -m '第三个变量'

  • 推送到服务器仓库:git push
  • 以上操作会出现代码冲突:
    • 提示需要先 pull

uploading.4e448015.gif转存失败重新上传取消

  • 提示冲突文件

uploading.4e448015.gif转存失败重新上传取消

  • 冲突代码表现

uploading.4e448015.gif转存失败重新上传取消

  • 解决冲突
    • 原则:谁冲突谁解决,并且一定要协商解决
    • 方案:保留所有代码 或者 保留某一人代码
    • 解决完冲突代码后,依然需要addcommitpush

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

    • 提示:如果张三执行pull没有影响,就算真正解决了冲突代码

补充:

  • 容易冲突的操作方式
    • 多个人同时操作了同一个文件
    • 一个人一直写不提交
    • 修改之前不更新最新代码
    • 提交之前不更新最新代码
    • 擅自修改同事代码
  • 减少冲突的操作方式
    • 养成良好的操作习惯,先pull在修改,修改完立即commitpush
    • 一定要确保自己正在修改的文件是最新版本的
    • 各自开发各自的模块
    • 如果要修改公共文件,一定要先确认有没有人正在修改
    • 下班前一定要提交代码,上班第一件事拉取最新代码
    • 一定不要擅自修改同事的代码

总结:

  • 明确冲突产生的原因
  • 知道解决冲突的方法

 

标签

学习目标:

知道标签的作用和设置方法

标签的作用

当某一个大版本完成之后,需要打一个标签

作用:

  • 记录大版本
  • 备份大版本代码

uploading.4e448015.gif转存失败重新上传取消

模拟设置标签

  • 1.进入到经理的本地仓库 test007
  •  cd  Desktop/manager/test007/
  • 2.经理在本地打标签
  •  # 使用方式:
  •  
  •  git tag -a 标签名 -m '标签描述'

例如:

 #  标签名为 v1.0 

 #  标签描述为: version 1.0

 git tag -a v1.0 -m 'version 1.0'

uploading.4e448015.gif转存失败重新上传取消

  • 3.经理推送标签到远程仓库
  •  # 使用方式:
  •  
  •  git push origin 标签名

例如:

 # 将标签推送到远端:

 git push origin v1.0

这里的 origin 代表远端的意思

uploading.4e448015.gif转存失败重新上传取消

  • 4.查看打标签结果

uploading.4e448015.gif转存失败重新上传取消

补充:删除本地和远程标签

  # 删除本地标签

  git tag -d 标签名

 

  # 删除远程仓库标签

  git push origin --delete tag 标签名

总结:

  • 标签是在某一个大版本完成之后, 设置的标记
  • 添加标签使用: git tag -a v1.0 -m '信息'

VUE课程介绍

Vue.js 入门,介绍 Vue.js 里面的一些通用概念和用法。

Vue.js 是前端三大新框架:Angular.js React.js Vue.js 之一,Vue.js 目前的使用和关注程度在三大框架中稍微胜出,并且它的热度还在递增。

Vue.js 可以作为一个 js 库来使用,也可以用它全套的工具来构建系统界面,这些可以根据项目的需要灵活选择,所以说,Vue.js 是一套构建用户界面的渐进式框架。

Vue 的核心库只关注视图层,Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定,在这一点上 Vue.js 类似于后台的模板语言。

Vue 也可以将界面拆分成一个个的组件,通过组件来构建界面,然后用自动化工具来生成单页面( SPA - single page application ) 系统。

Vue 的作者

uploading.4e448015.gif转存失败重新上传取消

vue 作者: 尤玉溪

毕业于上海复旦附中, 在美国完成大学学业, 现任职于纽约 Google Creative Lab

前后研发了 Clear 开源软件和 Vue.js 框架.

201693日,在南京的 JSConf 上,Vue 作者尤雨溪正式宣布加盟阿里巴巴 Weex 团队,尤雨溪称他将以技术顾问的身份加入 Weex 团队来做 Vue Weex JavaScript runtime 整合,目标是让大家能用 Vue 的语法跨三端

Vue.js 的概述

Vue.js 读音 /vjuː/, 类似于 view

Vue.js 是一个轻巧、高性能、可组件化的 MVVM 库,同时拥有非常容易上手的 API

uploading.4e448015.gif转存失败重新上传取消

Vue.js 是一个构建数据驱动的 Web 界面的库

Vue.js 是一套构建用户界面的 渐进式框架

uploading.4e448015.gif转存失败重新上传取消

通俗的说:

  • Vue.js 是一个构建数据驱动的 web 界面的渐进式框架
  • Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件
  • 核心是一个响应的数据绑定系统

Vue.js 官网说明

Vue.js 使用文档已经写的很完备和详细了

通过以下地址可以查看: https://cn.vuejs.org/v2/guide/

vue.js 如果当成一个库来使用

可以通过下面地址下载: https://cn.vuejs.org/v2/guide/installation.html

  •  

Vue 的基本使用

学习目标:

介绍 Vue 的基本使用步骤

Vue 的基本使用步骤

第一步:导包

官方提供了两个包

开发包:

vue.js

生产包:

vue.min.js

<!-- 基本使用 --> 
 
<!-- 导入 vue.js : -->  
<script src="./js/vue.js"></script>

第二步: 创建 Vue 对象

window.onload = function () {
    // 创建一个 vue 对象
    var vm = new Vue({
        el:'#box',
        data: {
 
        }
    });
}

第三步: 创建一个容器

创建一个容器和上面的对象关联.

<div id="box">  </div>

示例:

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>Vue的基本使用</title>
    <!-- 01.导包 -->
    <script src="./js/vue.js"></script>
    <script>
        window.onload = function () {
            // 02: 创建 vue 对象
            var vm = new Vue({
                // 绑定操作对象
                el:'#box',
                data: {
                    content: 'Vue的基本使用'
                }
            });
        }
    </script>
</head>
<body>
    <!-- 03:设置容器 div 标签, 用于展示 vue对象数据 -->
    <div id="box">
        {{content}}
    </div>
 
</body>
</html>

总结:

  • 使用 vue 时, 有三步: 导入, 创建 vue 对象, 设置容器关联 vue 对象
  • 导入的时候我们平时开发使用不压缩版本, 上线时使用压缩版本, 减少体积
  • 如果 js 代码在上面, 需要写到 window.onload 中, 如果写在下面, 则不用
  • 逗号不要多加,否则出问题。

Vue 的基本语法一

学习目标

学会操作数据, 修改属性, 调用方法

增加标签数据

<!--使用形式:-->
 
{{变量名}}

示例

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>操作数据</title>
    <script src="./js/vue.js"></script>
    <script>
        window.onload = function () {
            // 创建 vue 对象
//var是定义局部变量,不写是定义全局变量
            var vm = new Vue({
                el:'#box',
                data:{
                    name:'张三'
                }
            });
        }
    </script>
</head>
<body>
    <div id="box">
        {{name}}
 
        <p>{{name}}</p>
    </div> 
</body>
</html>

修改标签属性

<!--使用形式:-->
 
<标签 v-bind:属性="属性值"></标签>

示例

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>02-操作数据</title>
    <script src="./js/vue.js"></script>
    <script>
        window.onload = function () {
            // vue 对象
            var vm = new Vue({
                el:'#box',
                data:{
                    url:'http://www.baidu.com'
                }
            });
        }
    </script>
</head>
<body>
    <div id="box">
        <a href="http://www.baidu.com">百度</a>
 
        <!-- 第一种正常书写: v-bind: -->
        <a v-bind:href="url">百度</a>
 
        <!-- 第二种缩写形式: : -->
        <a :href="url">百度</a>
    </div> 
</body>
</html>

给标签增加方法

<!--使用形式:-->
 
<标签 v-on:事件名="调用的函数名"></标签>

示例

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>操作数据</title>
    <script src="./js/vue.js"></script>
    <script>
        window.onload = function () {
            // uve对象
            var vm = new Vue({
                el:'#box',
                data:{
                    count: 1
                },
                // 在这里定义方法: 
                methods: {
                    fnAddClick:function () {
                        this.count += 1
                    }
                }
 
            });
        }
    </script>
</head>
<body>
    <div id="box">
       {{count}}
 
        <!-- 第一种正常形式: v-on: -->
        <button v-on:click='fnAddClick'>按钮</button>
 
        <!-- 第二种缩写形式: @ -->
        <button @click='fnAddClick'>按钮</button>
    </div> 
</body>
</html>

总结:

  • 我们使用 vue 可以给标签增加数据
  • 也可以使用 v-bind 给标签修改属性
  • v-bind 的缩写形式是 :
  • 给标签增加事件使用 v-on: 的形式
  • v-on: 的缩写形式是: @

条件渲染

学习目标:

掌握 v-if, v-else-if, v-else, v-show 的使用

条件指令

通过条件指令可以控制元素的创建(显示)或者销毁(隐藏)

<!DOCTYPE html>

<head>

    <meta charset="UTF-8">

    <title>条件渲染</title>

    <!--1.导入-->

    <script src="./js/vue.js"></script>

    <script>

        <!--2.创建对象-->

        window.onload = function () {

            var vm = new Vue({

                el:'#box',

                data:{

                    isOk:true,

                    isTrue:true,

                }

            });

        }

    </script>

</head>

<body>

    <!--设置容器-->

    <div id="box">

        <!-- 01:v-if -->

        <p v-if='isOk'>第一个p标签</p>

 

 

        <!-- 02:v-else-if -->

        <p v-if='isOk'>第一个p标签</p>

        <p v-else-if='isTrue'>第二个p标签</p>

 

 

        <!-- 03:v-else -->

        <p v-if='isOk'>第一个p标签</p>

        <p v-else>第二个p标签</p>

 

 

        <!-- 04:v-show -->

        <p v-show='isOk'>V-SHOW</p>

    </div>

</body>

</html>

总结:

  • V-if 可以搭配 bool 类型的值, 根据值决定是否创建或者销毁
  • v-if 后面可以跟 v-else-if 和 v-else 用户和我们平时接触的 if 语句类似
  • v-show 和 v-if 后面都可以接 bool 类型的值, 但是 v-show 是以样式的形式展示显隐, v-if 是以创建与销毁的形式决定显隐的.

v-for 指令介绍

学习目标

掌握 v-for 指令遍历列表和字典的方法

列表渲染

<script>
    window.onload = function () {
    var vm = new Vue({
        el:'#box',
        data:{
            // 列表:
            list:['a', 'b', 'c', 'd']
            // 对象: 
            objData:{
                name:'小明',
                age:19
            }
        }
    });
}
</script>

获取列表元素

<!--遍历列表元素-->
<li v-for='value in list'>{{value}}</li>

获取列表下标

<!--遍历列表元素的下标-->
<li v-for='(value,index) in indexList'>{{index}}=={{value}}</li>

字典( 对象 )渲染

获取字典元素中的键值对

<!--只获取value:-->
<li v-for='value in objData'>{{value}}</li>
 
<!--获取key:value键值对-->
<li v-for='(value,key) in objData'>{{value}}-----{{key}}</li>

获取字典下标

<!--前端的字典可以获取下标值-->
<li v-for='(value, key, index) in objData'>{{value}}----{{key}}---{{index}}</li>

总结:

  • 使用 v-for 指令可以对列表和字典进行遍历
  • v-for 可以单独遍历某一个字典, 或者是某一个列表. 也可以对于混合的列表字典进行遍历
  • v-for 和我们正常使用的 for 循环基本类似

双向绑定

学习目标

掌握 input, select, textarea 标签与 vue 对象的绑定方法

v-model 指令的使用

可以用 v-model 指令在表单 <input> , <textarea> , <select> 元素上创建双向数据绑定。

它会根据控件类型自动选取正确的方法来更新元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- 1. 导入 -->
    <script src="./vue.js"></script>
 
    <!-- 2. 创建对象 -->
    <script>
        window.onload = function(){
            var vm = new Vue({
                el:'#app',
                data:{
                    inputvalue:'',
                    textvalue:'',
                    sexvalue:'',
                    like: [],
                    address:'北京'
                }
            })
        }
    </script>
</head>
<body>
<!-- 3. 设置容器 -->
<div id="app">
       <!-- 01.单行文本框 -->
       {{inputvalue}}
       <input type="text" v-model='inputvalue'>
 
       <!-- 02.多行文本框 -->
       {{textvalue}}
       <textarea v-model='textvalue'></textarea>
 
       <!-- 03.单选框 -->
       {{sexvalue}}
       <input type="radio" name="sex" value="" v-model='sexvalue'>
       <input type="radio" name="sex" value=""  v-model='sexvalue'>
 
        <!-- 04.多选框 -->
        {{like}}
        <input type="checkbox" name="lk" value="吃饭" v-model='like'>吃饭
        <input type="checkbox" name="lk" value="睡觉" v-model='like'>睡觉
        <input type="checkbox" name="lk" value="打豆豆" v-model='like'>打豆豆
 
        <!-- 05.下拉框 -->
        {{address}}
        <select name="addr" v-model='address'>
            <option value="北京">北京</option>
            <option value="上海">上海</option>
            <option value="广州">广州</option>
            <option value="深圳">深圳</option>
        </select> 
    </div>
</body>
</html>

总结:

  • 我们针对表单元素, 可以集体使用 v-model 指令进行双向数据绑定
  • v-model 能够将 data 中数据赋值给标签(例如 input ), v-model 也可以把标签( input ) 的数据赋值给data的变量

Todolist案例

学习目标

使用 Vue 完成 Todolist 案例

效果演示:

uploading.4e448015.gif转存失败重新上传取消

代码实现:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

    <style type="text/css">

        .list_con{

            width:600px;

            margin:50px auto 0;

        }

        .inputtxt{

            width:550px;

            height:30px;

            border:1px solid #ccc;

            padding:0px;

            text-indent:10px;           

        }

        .inputbtn{

            width:40px;

            height:32px;

            padding:0px;

            border:1px solid #ccc;

        }

        .list{

            margin:0;

            padding:0;

            list-style:none;

            margin-top:20px;

        }

        .list li{

            height:40px;

            line-height:40px;

            border-bottom:1px solid #ccc;

        }

 

        .list li span{

            float:left;

        }

 

        .list li a{

            float:right;

            text-decoration:none;

            margin:0 10px;

        }

    </style>

    <!--1.导入 js 文件-->

    <script src="js/vue.js"></script>

    <script>

        window.onload = function () {

            // 2.创建对象

            var vm = new Vue({

                el: '#box',

                data: {

                    inputvalue: "",

                    list: ['学习html', '学习javascript', '学习css']

                },

                methods: {

                    // 增加事件

                    fnAdd: function () {

                        // 判断内容是否为空, 为空则返回

                        if (this.inputvalue == '') {

                            alert('输入内容不能空!')

                            return

                        }

                        // 如果内容不为空, 则增加到list

                        this.list.push(this.inputvalue)

                        // 增加完成之后, 删除输入的数据

                        this.inputvalue = ""

 

                    },

                    // 删除事件

                    // splice(下标,个数,插入的内容)

                    fnDelete: function (index) {

                        this.list.splice(index, 1)

                    },

 

                    // 向上排序

                    fnUp: function (index) {

                        // 根据下标获取对应的数据

                        oldData = this.list[index]

 

                        // 删除对应位置的数据

                        this.list.splice(index, 1)

 

                        // 在上一个位置 插入

                        this.list.splice(index - 1, 0, oldData)

 

                    },

                    // 向下排序

                    fnDown: function (index) {

                        // 根据下标获取对应的数据

                        oldData = this.list[index]

 

                        // 删除对应位置的数据

                        this.list.splice(index, 1)

 

                        // 在下一个位置 插入

                        this.list.splice(index + 1, 0, oldData)

 

                    }

                }

            })

        }

    </script>

</head>

 

<body>

    <!--3.设置容器-->

    <div id="box">

        <h2>To do list</h2>

        <input v-model="inputvalue" type="text" name="" id="txt1" class="inputtxt">

        <input @click="fnAdd" type="button" name="" value="增加" id="btn1" class="inputbtn">

 

        <ul id="list" class="list">

            <li v-for="(item,index) in list">

                <span>{{item}}</span>

                <a @click="fnUp(index)" href="javascript:;" class="up"> ↑ </a>

                <a @click="fnDown(index)" href="javascript:;" class="down"> ↓ </a>

                <a @click="fnDelete(index)" href="javascript:;" class="del">删除</a>

            </li>

        </ul>

        <!-- <ul>

            <li><span>学习html</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>

            <li><span>学习css</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>

            <li><span>学习javascript</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>

        </ul> -->

    </div>

</body>

总结:

  • 通过 todolist 案例, 我们能够把上面的知识点进行整合.
  • 这里主要应用了 v-model 的双向数据绑定, 给标签添加事件的方法, v-for 遍历循环的方式等

ES6 语法

学习目标

掌握 ES6 的简单介绍, 变量声明方式 对象的简写等内容

ES6 语法介绍

ES6 JavaScript 语言的新版本,它也可以叫做 ES2015.

之前学习的 JavaScript 属于 ES5ES6 在它的基础上增加了一些语法,ES6 是未来 JavaScript 的趋势,而且 vue 组件开发中会使用很多的 ES6 的语法,所以掌握这些常用的 ES6 语法是必须的.

变量声明

let const 是新增的声明变量的开头的关键字

let const var 的区别是: var 声明的是变量, 有预解析功能 let 声明的是变量, 但是没有预解析功能 const 声明的是常量, 一旦赋值, 不能够再更改

var

console.log(iNum1);
//  ES5  声明变量使用 var
var iNum1 = 10;

结果为 :undefined

因为使用 var 声明的变量, 有预解析

let

console.log(iNum1);
//  ES6  声明变量可以使用 let
let iNum1 = 10;

查看后会发现报错 :iNum1 is not defined

因为使用 let 声明的变量, 没有了预解析

const

const iNum1 = 10;
iNum1 = 20;

查看后会发现报错:Assignment to constant variable

因为使用 const 声明的变量, 不允许重新赋值

ES6 中对象的简写

ES5 的写法:

var name = '小明'
var age = 20
 
// ES5 中对象写法:
var oObj = {
    name: name
    age: age,
};

ES6 的写法:

需要注意的是, 实现简写,有一个前提,必须变量名属性名一致

// 定义两个变量
var name = '小明';
var age = 20;
 
// 创建对象
var oObj = {
    name,
    age,
};

总结:

  • ES6 是 JS 最新的版本, 推出了新的定义变量的方法: let 和 const
  • ES6 中的 key : value 键值对, 如果 key 和 value 的名称一致, 则可以省略 value 部分

ES6 箭头函数

学习目标

掌握 ES6 中箭头函数的内容

ES6 箭头函数作用

作用:

  • 函数书写格式简化
  • 不绑定 this

定义格式:

(参数1, 参数2, …, 参数N) => { 函数声明 }
 
//相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
(参数1, 参数2, …, 参数N) => 表达式(单一)
 
// 当只有一个参数时,圆括号是可选的:
(单一参数) => {函数声明}
单一参数 => {函数声明}
 
// 没有参数的函数应该写成一对圆括号。
() => {函数声明}

常见的几种方式:

// 无参数无返回值
var fnTest1 =()=> {
    alert('无参数无返回值');
}
 
// 一个参数无返回值 
// (有一个参数的时候, 可以省略小括号)
var fnTest2 = a => {
    alert(a + 1);
}
 
// 一个参数有返回值 
// (有一个参数的时候, 可以省略小括号)
// 如果函数体只是一个返回语句, return  {} 可以省略
var fnTest3 = a => a;
 
// 有多个参数有返回值
var fnTest4 =(a,b)=> {
    return a + b;
}

不绑定 this

var obj1 = {
    name: 'zs',
    func: function (){
        setTimeout(function(){
            alert(this.name)
        }, 1000)
 
    }
}
obj1.func() // 结果为空
 
 
var obj2 = {
    name: 'zs',
    func: function(){
        setTimeout(()=>{
            alert(this.name)
        }, 1000)
    }
}   
obj2.func()  // 结果为 zs

总结:

  • 知道 ES6 中箭头函数的主要作用是为了简写函数的定义
  • 另外箭头函数中没有绑定 this. 即: 在箭头函数中 this 不存在, 所以我们在箭头函数中看到 this 需要去外围寻找对应的对象.

实例生命周期( 了解 )

学习目标

  • 各个生命周期函数的作用

uploading.4e448015.gif转存失败重新上传取消

各个生命周期函数的作用

  • beforeCreate
    • vm对象实例化之前
  • created
    • vm对象实例化之后
  • beforeMount
    • vm将作用标签之前
  • mounted(重要时机初始化数据使用)
    • vm将作用标签之后
  • beforeUpdate
    • 数据或者属性更新之前
  • updated
    • 数据或者属性更新之后
  • beforeDestroy
    • 数据或者属性销毁之前
  • Destroyed
    • 数据或者属性销毁之后

总结:

  • 了解 vue 中各个声明周期的函数
  • 大概了解各个函数调用的时间

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值