- 通过简单示例,使用django完成基本流程的开发,学习django的主要的知识点,在后续课程中会逐个知识点进行深入讲解
- 以“图书-英雄”管理为示例
- 正则表达式非命名组,通过位置参数传递给视图
- 参数:视图会收到来自父URLconf、当前URLconf捕获的所有参数
- 如果在视图、模板中使用硬编码的链接,在urlconf发生改变时,维护是一件非常麻烦的事情
- 解决:在做链接时,通过指向urlconf的名称,动态生成链接地址
- 模板:使用url模板标签
- 通过正则表达式组获取的位置参数
- 通过正则表达式组获得的关键字参数
- 在应用目录下默认有views.py文件,一般视图都定义在这个文件中
- 如果处理功能过多,可以将函数定义到不同的py文件中
- Django原生自带几个默认视图用于处理HTTP错误
- 默认的404视图将传递一个变量给模板:request_path,它是导致错误的URL
- 如果Django在检测URLconf中的每个正则表达式后没有找到匹配的内容也将调用404视图
- 如果在settings中DEBUG设置为True,那么将永远不会调用404视图,而是显示URLconf 并带有一些调试信息
- 在视图代码中出现运行时错误
- 默认的500视图不会传递变量给500.html模板
- 如果在settings中DEBUG设置为True,那么将永远不会调用505视图,而是显示URLconf 并带有一些调试信息
- 当用户进行的操作在安全方面可疑的时候,例如篡改会话cookie
- 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象
- 视图函数的第一个参数是HttpRequest对象
- 下面除非特别说明,属性都是只读的
- path:一个字符串,表示请求的页面的完整路径,不包含域名
- method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'
- encoding:一个字符串,表示提交的数据的编码方式
- 如果为None则表示使用浏览器的默认设置,一般为utf-8
- 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值
- GET:一个类似于字典的对象,包含get请求方式的所有参数
- POST:一个类似于字典的对象,包含post请求方式的所有参数
- FILES:一个类似于字典的对象,包含所有的上传文件
- COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串
- session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见“状态保持”
- 与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
- 方法get():根据键获取值
- 如果一个键同时拥有多个值,获取最后一个值
- 包含get请求方式的所有参数
- 与url请求地址中的参数对应,位于?后面
- 键是开发人员定下来的,值是可变的
- 创建视图getTest1用于定义链接,getTest2用于接收一键一值,getTest3用于接收一键多值
- 包含post请求方式的所有参数
- 与form表单中的控件对应
- 问:表单中哪些控件会被提交?
- 答:控件要有name属性,则name属性的值为键,value属性的值为键,构成键值对提交
- 对于checkbox控件,name属性一样为一组,当控件被选中后会被提交,存在一键多值的情况
- 键是开发人员定下来的,值是可变的
- 创建视图postTest2接收请求的数据
- 注意:使用表单提交,注释掉settings.py中的中间件crsf
- 不调用模板,直接返回数据
- content:表示返回的内容,字符串类型
- charset:表示response采用的编码字符集,字符串类型
- flush():以文件的方式输出缓存区
- max_age是一个整数,表示在指定秒数后过期
- 如果不指定过期时间,则两个星期后过期
- 构造函数的第一个参数用来指定重定向的地址
请求结果的地址栏如图:
- 返回json数据,一般用于异步请求
- 帮助用户创建JSON编码的响应
- 参数data是字典对象
- 结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象
- context:添加到模板上下文的一个字典,视图将在渲染模板之前调用它
- 通过模型管理器或查询集调用get()方法,如果没找到对象,不引发模型的DoesNotExist异常,而是引发Http404异常
- http协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态
- 客户端与服务器端的一次通信,就是一次会话
- 实现状态保持的方式:在客户端或服务器端存储与会话有关的数据
- 使用cookie,所有数据存储在客户端,注意不要存储敏感信息
- 推荐使用sesison方式,所有数据存储在服务器端,在客户端cookie中存储session_id
- 状态保持的目的是在一段时间内跟踪请求者的状态,可以实现跨页面访问当前请求者的数据
- 注意:不同的请求者之间不会共享这个数据,与请求者一一对应
- 禁用会话:删除上面指定的两个值,禁用会话将节省一些性能消耗
- 启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象
- flush():删除当前的会话数据并删除会话的Cookie
- 如果没有指定,则两个星期后过期
- 如果value是一个整数,会话将在values秒没有活动后过期
- 若果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期
- 如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
- 如果value为None,那么会话永不过期
- 修改settings中的配置,增加如下项
- 作为Web框架,Django提供了模板,可以很便利的动态生成HTML
- 模版系统致力于表达外观,而不是程序逻辑
- 模板的设计实现了业务逻辑(view)与显示内容(template)的分离,一个视图可以使用任意一个模板,一个模板可以供多个视图使用
- DIRS定义了一个目录列表,模板引擎按列表顺序搜索这些目录以查找模板源文件
- APP_DIRS告诉模板引擎是否应该在每个已安装的应用中查找模板
- Django处理模板分为两个阶段
- 为了减少加载模板、渲染模板的重复代码,django提供了快捷函数
- 当模版引擎遇到一个变量,将计算这个变量,然后将结果输出
- 变量名必须由字母、数字、下划线(不能以下划线开头)和点组成
- 当模版引擎遇到点("."),会按照下列顺序查询:
- 属性或方法查询,例如:foo.bar
- 数字索引查询,例如:foo[bar]
- 如果变量不存在, 模版系统将插入'' (空字符串)
- 在模板中调用方法时不能传递参数
在模板中调用对象的方法
- 加载外部信息到模板中供以后的变量使用
- 布尔标签:and、or,and比or的优先级高
- 使用管道符号 (|)来应用过滤器
- 通过使用过滤器来改变变量的计算结果
- 过滤器能够被“串联”,构成过滤器链
- 过滤器可以传递参数,参数使用引号包起来
- default:如果一个变量没有被提供,或者值为false或空,则使用默认值,否则使用变量的值
- 使用comment标签注释模版中的多行内容
- 查询所有英雄信息显示出来,要求奇数行显示为红色,偶数行显示为蓝色
- 模板继承可以减少页面内容的重复定义,实现页面内容的重用
- 典型应用:网站的头部、尾部是一样的,这些内容可以定义在父模板中,子模板不需要重复定义
- block标签:在父模板中预留区域,在子模板中填充
- extends继承:继承,写在模板文件的第一行
- 在子模板中使用block填充预留区域
- 如果在模版中使用extends标签,它必须是模版中的第一个标签
- 不能在一个模版中定义多个相同名字的block标签
- 子模版不必定义全部父模版中的blocks,如果子模版没有定义block,则使用了父模版中的默认值
- 如果发现在模板中大量的复制内容,那就应该把内容移动到父模板中
- 使用可以获取父模板中block的内容
- 为了更好的可读性,可以给endblock标签一个名字
- 三层继承结构使代码得到最大程度的复用,并且使得添加内容更加简单
- 如下图为常见的电商页面
- 存放整个站点共用的内容
- 定义特定分支共用的内容
3.为具体页面创建模板,继承自分支模板
4.视图调用具体页面,并传递模板中需要的数据
- Django对字符串进行自动HTML转义,如在模板中输出如下值:
- html转义,就是将包含的html标签输出,而不被解释执行,原因是当显示用户提交字符串时,可能包含一些攻击性的代码,如js脚本
- Django会将如下字符自动转义:
- 当显示不被信任的变量时使用escape过滤器,一般省略,因为Django自动转义
- 自动转义标签在base模板中关闭,在child模板中也是关闭的
- 某些恶意网站上包含链接、表单按钮或者JavaScript,它们会利用登录过的用户在浏览器中的认证信息试图在你的网站上完成某些操作,这就是跨站攻击
- 创建视图csrf1用于展示表单,csrf2用于接收post请求
- 创建模板csrf2用于展示接收的结果
- 在浏览器中访问,查看效果,报错如下:
- 查看csrf1的源代码,复制,在自己的网站内建一个html文件,粘贴源码,访问查看效果
- 在django的模板中,提供了防止跨站攻击的方法,使用步骤如下:
- step3:测试刚才的两个请求,发现跨站的请求被拒绝了,效果如下图
- 如果某些视图不需要保护,可以使用装饰器csrf_exempt,模板中也不需要写标签,修改csrf2的视图如下
- 运行上面的两个请求,发现都可以请求
- 在浏览器的调试工具中,通过network标签可以查看cookie信息
- 本站中自动添加了cookie信息,如下图
- 查看跨站的信息,并没有cookie信息,即使加入上面的隐藏域代码,发现又可以访问了
- 结论:django的csrf不是完全的安全
- 在用户注册、登录页面,为了防止暴力请求,可以加入验证码功能,如果验证码错误,则不需要继续处理,可以减轻一些服务器的压力
- 使用验证码也是一种有效的防止crsf的方法
- Image表示画布对象
- 在urls.py中定义请求验证码视图的url
- 在模板中使用img标签,src指向验证码视图
- 启动服务器,查看显示成功
- 扩展:点击“看不清,换一个”时,可以换一个新的验证码
- 为了能够实现提交功能,需要增加form和input标签
- 接收请求的信息,与session中的内容对比
- 可以在网上搜索“验证码”,找到一些第三方验证码提供网站,阅读文档,使用到项目中
- 项目中的CSS、图片、js都是静态文件
- 在settings 文件中定义静态内容
-
是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出
-
每个中间件组件是一个独立的Python类,可以定义下面方法中的一个或多个
-
init :无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件
-
使用中间件,可以干扰整个处理过程,每次请求中都会执行中间件的这个方法
- 定义视图,并发生一个异常信息,则会运行自定义的异常处理
-
当Django在处理文件上传的时候,文件数据被保存在request.FILES
-
注意:FILES只有在请求的方法为POST 且提交的带有enctype="multipart/form-data"的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象
-
在项目根目录下创建media文件夹
-
使用django后台管理,遇到ImageField类型的属性会出现一个file框,完成文件上传
- 通过使用startproject创建的项目模版中,默认Admin被启用
- 2.在应用内admin.py文件完成注册,就可以在后台管理中维护模型的数据
- 定义:定义一个类,继承于admin.ModelAdmin,注册模型时使用这个类
- 通常定义在应用的admin.py文件里
- 通过重写admin.ModelAdmin的属性规定显示效果,属性主要分为列表页、增加修改页两部分
- 在列表中,可以是字段名称,也可以是方法名称,但是方法名称默认不能排序
- 标题栏名称:将字段封装成方法,为方法设置short_description属性
- 右侧栏过滤器,对哪些属性的值进行过滤
- 每页中显示多少项,默认设置为100
- 列表类型,表示在这些字段上进行搜索
- fields:显示字段的顺序,如果使用元组表示显示到一行上
- 类型InlineModelAdmin:表示在模型的添加或修改页面嵌入关联模型的添加或修改
- 在项目所在目录中创建templates目录,再创建一个admin目录
- 刷新页面,发现以刚才编辑的页面效果显示
- 其它管理后台的模板可以按照相同的方式进行修改
- Paginator(列表,int):返回分页对象,参数为列表数据,每面数据的条数
- page(num):下标以1开始,如果提供的页码不存在,抛出InvalidPage异常
- EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出
- object_list:当前页上所有对象的列表
- number:当前页的序号,从1开始
- len():返回当前页面对象的个数
- 迭代页面对象:访问当前页面中的每个对象
- 使用视图通过上下文向模板中传递数据,需要先加载完成模板的静态页面,再执行模型代码,生成最张的html,返回给浏览器,这个过程将页面与数据集成到了一起,扩展性差
- 改进方案:通过ajax的方式获取数据,通过dom操作将数据呈现到界面上
- 推荐使用框架的ajax相关方法,不要使用XMLHttpRequest对象,因为操作麻烦且不容易查错
- 由于csrf的约束,推荐使用
$.get
- 示例:实现省市区的选择
- js文件属于静态文件,创建目录结构如图:
- 参见“省市区.sql”
- 注意将表的名称完成替换
- index用于展示页面
- getArea2用于根据省、市编号返回市、区信息,格式都为字典对象
- 在项目中的目录结构如图:
- 定义模板文件:包含三个select标签,分别存放省市区的信息
- 借助富文本编辑器,管理员能够编辑出来一个包含html的页面,从而页面的显示效果,可以由管理员定义,而不用完全依赖于前期开发人员
- 此处以tinymce为例,其它富文本编辑器的使用可以自行学习
- 使用编辑器的显示效果为:
- 进入解压后的目录,工作在虚拟环境,安装
- 在应用中定义模型的属性
- 在后台管理界面中,就会显示为富文本编辑器,而不是多行文本框
- 定义视图editor,用于显示编辑器并完成提交
- 对于中等流量的网站来说,尽可能地减少开销是必要的。缓存数据就是为了保存那些需要很多计算资源的结果,这样的话就不必在下次重复消耗计算资源
- Django自带了一个健壮的缓存系统来保存动态页面,避免对于每次请求都重新计算
- Django提供了不同级别的缓存粒度:可以缓存特定视图的输出、可以仅仅缓存那些很难生产出来的部分、或者可以缓存整个网站
- 通过设置决定把数据缓存在哪里,是数据库中、文件系统还是在内存中
- 参数TIMEOUT:缓存的默认过期时间,以秒为单位,这个参数默认是300秒,即5分钟;设置TIMEOUT为None表示永远不会过期,值设置成0造成缓存立即失效
- 可以将cache存到redis中,默认采用1数据库,需要安装包并配置如下:
- 可以连接redis查看存的数据
- cache_page接受一个参数:timeout,秒为单位,上例中缓存了15分钟
- 视图缓存与URL无关,如果多个URL指向同一视图,每个URL将会分别缓存
- 使用cache模板标签来缓存模板的一个片段
- 全文检索不同于特定字段的模糊查询,使用全文检索的效率更高,并且能够对于中文进行分词处理
- haystack:django的一个包,可以方便地对model里面的内容进行索引、搜索,设计为支持whoosh,solr,Xapian,Elasticsearc四种全文检索引擎后端,属于一种全文检索的框架
- whoosh:纯Python编写的全文搜索引擎,虽然性能比不上sphinx、xapian、Elasticsearc等,但是无二进制包,程序不会莫名其妙的崩溃,对于小型的站点,whoosh已经足够使用
- jieba:一款免费的中文分词包,如果觉得不好用可以使用一些收费产品
1.在虚拟环境中依次安装包
- 注意:复制出来的文件名,末尾会有一个空格,记得要删除这个空格
- 示例一:用户发起request,并等待response返回。在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验
- 示例二:网站每小时需要同步一次天气预报信息,但是http是请求触发的,难道要一小时请求一次吗?
- 使用celery后,情况就不一样了
- 示例一的解决:将耗时的程序放到celery中执行
- 示例二的解决:使用celery定时执行
- 队列queue:将需要执行的任务加入到队列中
- 工人worker:在一个新进程中,负责执行队列中的任务
- 代理人broker:负责调度,在布置环境中使用redis
- 在应用目录下创建task.py文件
- 从uwsgi、nginx、静态文件三个方面处理
- 服务器:私有服务器、公有服务器
- 私有服务器:公司自己购买、自己维护,只布署自己的应用,可供公司内部或外网访问
- 公有服务器:集成好运营环境,销售空间或主机,供其布署自己的应用
- 私有服务器成本高,需要专业人员维护,适合大公司使用
- 公有服务器适合初创公司使用,成本低
- 常用的公有服务器,如阿里云、青云等,可根据需要,按流量收费或按时间收费
- 此处的服务器是物理上的一台非常高、线路全、运行稳定的机器
- 在本地的虚拟环境中,项目根目录下,执行命令收集所有包
- 通过ftp软件将开发好的项目上传到此服务器的某个目录
- 安装并创建虚拟环境,如果已有则跳过此步
- 在虚拟环境上工作,安装所有需要的包
- 启动服务器,运行正常,但是静态文件无法加载
- python manage.py runserver:这是一款适合开发阶段使用的服务器,不适合运行在真实的生产环境中
- 在生产环境中使用WSGI
- WSGI没有官方的实现,
因为WSGI更像一个协议,只要遵照这些协议,WSGI应用(Application)都可以在任何服务器(Server)上运行 - 此处的服务器是一个软件,可以监听网卡端口、遵从网络层传输协议,收发http协议级别的数据
- uWSGI实现了WSGI的所有接口,是一个快速、自我修复、开发人员和系统管理员友好的服务器
- uWSGI代码完全用C编写
- 配置uWSGI,在项目中新建文件uwsgi.ini,编写如下配置
- 使用http协议查看网站运行情况,运行正常,但是静态文件无法加载
- 负载均衡:多台服务器轮流处理请求
- 反射代理:隐藏真实服务器
- 这里以下载压缩文件为例演示
- 默认安装到/usr/local/nginx目录,进入此目录执行命令
- 通过浏览器查看nginx运行结果
- 在浏览器中查看项目,发现静态文件加载不正常,接下来解决静态文件的问题
- 静态文件一直都找不到,现在终于可以解决了
- 所有的静态文件都会由nginx处理,不会将请求转到uwsgi
- 创建static目录,注意顺序是先分配权限,再创建目录
- 这是一个垂直电商,只针对生鲜水果的一个电商平台
- 实现功能:首页、列表页、展示页、购物车、订单、用户登录注册、用户中心
- 分组完成开发,一组人员为4-5人
- 将现有页面进行整理,划分出template、static目录下的内容
- 找出模板页面的继承关系