知了课堂-Django学习笔记
2021-06-24 11:57:29 0 举报
AI智能生成
知了课堂-Django学习笔记
作者其他创作
大纲/内容
Basic-Python开发环境准备
视图高级部分
as_view()方法
两个缓存框架
Redis
Memcached
项目实战
XFZ
前端
Front
后端
Backend
运维部署
Linux+Shell
Docker
K8S
未来的趋势
1、B/S;
2、Docker;
3、前后端分离;
前端开发
HTML+CSS+JavaScript+前端模板框架(AdminLTE-2.4.10(Bootstrap、jQuery、Echarts))
LayUI
iFrame
不推荐使用了
std
LayUI
后端开发
Python3.7.4+Django2.2.4+Nginx1.16.0+uWSGI2.0.18(Gunicorn)
Ueditor富文本编辑器
百度
不推荐了,不再更新维护;
Django-ueditor
Django-CKEditor
CKEditor
七牛云存储
亦或是考虑阿里云存储
我觉得应该优先考虑大公司的产品
ajax
异步的JavaScript和XML
小饭桌实战项目
微博、微信分享开发
在线播放加密视频的功能开发
七牛云
阿里云
CC视频
支付宝及微信支付开发
支付宝沙箱环境测试
付费内容开发
付费课程
haystack搜索开发
CMS管理系统开发
AdminLTE2.4.10版本框架使用
删除和发布文章
百度Ueditor内容富文本发布
缩略图的使用
全网最有深度的一门Django课程
Django开发简直So Easy!
1、Windows下的Python双版本安装(Python2.7&Python3.6)
https://www.luffycity.com/courses/38/details-introduce
2、全宇宙最强大的Python IDE工具——PyCharm工具的使用
https://www.luffycity.com/courses/39/details-introduce
章节01-Django预热
001-【虚拟环境】为什么需要虚拟环境
1、为什么需要虚拟环境
默认操作是pip install Django==2.2.3
指定版本进行安装
pip install django==2.2.3
安装最新版本
是否是稳定版呢?
默认直接安装到系统环境中,致使全局环境(Global)越来越大,且不能并行多个版本的项目
Python2.7+Django1.11
Python3.7+Django2.2
pip install django
默认安装最新的版本;
2、虚拟环境的原理
系统级别的Python开发环境
virtualenv级别的开发环境
Django1.11.15
Django2.0.2
Django2.1.7
PS:一定要使用虚拟环境进行开发!
多个项目使用的依赖包版本、内容不相同!
导致系统级别的Python开发环境越来越大,不好维护!
生产环境也建议使用虚拟开发环境
002-【虚拟环境】virtualenv创建虚拟环境
1、安装virtualenv
pip install virtualenv
pip3 install virtualenv
2、创建虚拟环境
virtualenv 虚拟环境的名称
3、进入虚拟环境
Windows
activate
在Scripts目录下
*nix
source xxxx/activate
在bin目录下
思想:不同平台有不同的配置
4、退出虚拟环境
deactivate
5、创建虚拟环境的时候指定Python解释器版本
PyCharm 是全宇宙最优秀的Python IDE工具!
没有之一呀!
virtualenv - p C:\python36\python.exe 虚拟环境的名称
virtualenv -p /usr/bin/python3 NQMP
阶段性正确的最佳实践!
查看所有的虚拟环境
lsvirtualenv
003-【虚拟环境】virtualenvwrapper使用
virtualenv的缺点
进入目录不方便!
创建路径不方便!
virtualenvwrapper管理器是基于virtualenv实现的!
pip install virtualenvwrapper,会同步安装virtualenv
virtualenvwrapper管理工具的使用
1、virtualenvwrapper的安装
Windows
pip install virtualenvwrapper-win
*nix
pip install virtualenvwrapper
2、创建虚拟环境
virtualenvwrapper的使用
mkvirtualenv 虚拟环境的名称
全部存在于Envs目录下
C:\Users\TQTL\Envs
3、进入虚拟环境
workon 虚拟环境的名称
4、退出虚拟环境
deactivate
5、删除虚拟环境
rmvirtualenv 虚拟环境的名称
6、列出虚拟环境
lsvirtualenv
workon 也可以
7、快速进入虚拟环境所在的目录
cdvirtualenv 虚拟环境的名称
8、修改mkvirtualenv的默认目录
在Windows的系统环境变量中,添加WORKON_HOME变量并指定目录
9、创建虚拟环境的时候指定Python的版本
mkvirtualenv --python==C:\Python36\python.exe 虚拟环境的版本
进退创列改
PS:其实两个工具都不必使用,使用PyCharm自带的virtualenv即可
004-【Django预热】URL组成部分详解
URL-统一资源定位符
Uniform Resource Locator,URL
URL和URI的区别
基本格式:schema://host:port/path/?query-string(可添加多个查询字符串)=xxx&query-string=xxx#anchor
使用&连接查询字符串
schema
协议
http
https
ftp
host
port
0~65535
path
query-string
可存在多个,通过&符号连接
根据参数来获取一些信息
anchor
前端页面用于定位使用
域名和DNS的关系
电话和电话簿的关系!
微信ID和手机号码绑定的关系
根DNS服务器,全球最大的电话簿|通讯录
注意:URL中的所有字符都是ASCII字符集,如果出现“非ASCII”字符,比如中文,浏览器会进行转码再传输!
深有体会
005-【Django预热】课程准备工作
1、Python3.7.3解释器安装
安装过程配置环境变量
2、pip安装virtualenvwrapper虚拟环境管理器
Windows
*nix
3、虚拟环境相关操作
创建
删除
进入
退出
指定解释器路径创建
4、进入虚拟环境,pip install django==2.2.3
5、安装PyCharm Professional版本软件
专注于Python Web开发的全宇宙顶级IDE,没有之一!
Professional版本
付费
Community版本
免费
比较耗费计算机性能
尤其是内存
6、安装最新版本MySQL5.7.26
Windows .MSI安装包
CentOS7.X中安装
yum安装MySQL
推荐使用MySQL8.0了
还是会有一些问题存在。
7、安装pymysql(Django操作MySQL中间件)
pip install pymysql
pip install cymysql
pip install *.whl文件
使用mysqlclient==1.4.2.post1保持一致
yum install python36 python36-devel -y
yum install gcc mariadb-devel -y
export PATH=$PATH:/usr/local/mysql/bin
pip3 install mysqlclient
8、Win10操作系统
开发还是应该使用MacOS系统,底层类Unix
如果没有Mac环境,个人建议统一使用虚拟机,安装Ubuntu图形化界面,再安装PyCharm
006-【Django预热】Django介绍
1、Django介绍
注意Django的发音!
https://docs.djangoproject.com/zh-hans/2.2/
诞生于2003年秋天,2005正式,目的节省开发时间!
CMS
DJANGO-CMS
其他CMS管理系统
子主题
Python 语言进行Web开发的首选框架!
大而全,内置了许许多多我们需要的组件
想做任何可以做的事情;
RBAC
适应新闻媒体平台的快速开发需求
Python商业网站
豆瓣网
知乎
简书
Sohu邮箱
大量使用了Web.py框架以及Django等框架
web.py
海报网
果壳网
Python+Django如何撑起7亿月活用户的instagram?!
可以解决大流量问题,只不过业内高并发系统还是以Java为主!
无需担心Django能否支撑大流量,大并发
关心的应该是,如何把Django玩的特别熟练!
2、Django版本和Python版本
Django2.0不支持Python2.7!!!敬请注意
https://docs.djangoproject.com/zh-hans/2.2/faq/install/#faq-python-version-support
我应该使用哪个版本的 Python 来配合 Django?¶
Django 版本 Python 版本
1.11 2.7, 3.4, 3.5, 3.6, 3.7 (1.11.17 添加)
2.0 3.4,3.5,3.6,3.7
2.1,2.2 3.5,3.6,3.7
Django 版本 Python 版本
1.11 2.7, 3.4, 3.5, 3.6, 3.7 (1.11.17 添加)
2.0 3.4,3.5,3.6,3.7
2.1,2.2 3.5,3.6,3.7
3、Web服务器和应用服务器以及Web应用框架(重点)
1、Web服务器
处理http请求,比如Apache、Nginx、IIS;
2、应用服务器
负责处理逻辑的服务器,比如PHP、Python、Java代码不能通过Nginx等来处理,只能通过应用服务器来处理,常见的应用服务器uWSGI、Tomcat、Jboss、Resin、Weblogic;
3、Web应用框架
Python中的Flask、Tornado、Bottle、Django、Web.py;
以及Java中的SSH(Struts2、Spring3、Hibernate3)
4、HTTP的完整请求流程
5、Django和MTV设计模式(MVC)
Model
模型
M
Model
View
模板
T
Templates
Controller
控制器
V
View
章节02-DjangoURL
007-【Django URL】第一个Django项目剖析(1)
1、创建Django项目
1、命令行方式创建Django项目
django-admin startproject NQMP【项目的名称】
避免使用LOW的命名方式
比如MyProject
MyFirstProject
CMDBProject
MyWeb
2、命令行方式创建应用
python manage.py startapp users
3、命令行运行项目
python manage.py runserver 0.0.0.0:19939
0.0.0.0 可以使用0代替
尽可能使用PyCharmIDE进行程序的运行
远程开发环境配置
远程开发环境连接并配置
底层是基于SSH协议
SFTP
PS:以上的前提是进入虚拟环境中venv
pip安装第三方包之前,一定要检查是否存在哦!
2、PyCharm创建Django项目
指定Django项目的创建路径
指定Python解释器版本
Python2.7
Python3.7
PS:还可以创建DjangoProject的时候顺便创建一个Django App
此刻的App无需在INSTALLED_APPS中配置
使用PyCharm运行Django项目,要避免一个项目运行多次(设置单一实例运行)
出现端口冲突如何处理呢?
关机,重启
笨办法
使用其他端口代替
较优解
杀死被占用端口,再启动现有服务
PyCharm创建空项目
使用pip安装Django
调整venv的目录
修改DjangoServer的目录
删除旧的解释器venv目录,重新新增新的虚拟环境并指定解释器目录
注意虚拟环境可能有重名的时候,注意排查!
008-【Django URL】第一个Django项目剖析(2)
1、运行Django项目
1、通过命令行方式运行
python manage.py runserver 19939
python manage.py 192.168.1.11:19939
python manage.py runserver 0.0.0.0:19939
Python manage.py runserver 0:19939
推荐使用!
2、通过PyCharm运行
PyCharm修改端口号的值
点击启动按钮
PyCharm设置只允许单一实例运行
3、虚拟机的网络设置
桥接(局域网)
Windows下的虚拟机
Mac下的虚拟机
Ubuntu中的虚拟机
IE浏览器不智能,输入ip和端口不会自动添加http://
settings.py中的ALLOWED_HOSTS = ['*']的设置
DEBUG=False
生产环境必须设置为该参数
部署到生产环境下,使用supervisor工具+uWSGI工具配合使用
防火墙是否关闭或者允许某个端口通过
Windows
*nix
云防火墙
阿里云ECS
安全组配置
云产品有其特殊的使用需求,比如为了安全,关闭25端口,防止垃圾邮件泛滥!
数据库授权访问
数据开放白名单
iptables也同时开发白名单
2、项目结构介绍
1、python mange.py help
(venv) (base) cuixiaozhaodeMacBook-Pro:NQMP cuixiaozhao$ python manage.py help
Type 'manage.py help <subcommand>' for help on a specific subcommand.
Available subcommands:
[auth]
changepassword
createsuperuser
[contenttypes]
remove_stale_contenttypes
[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver
[django_crontab]
crontab
[sessions]
clearsessions
[staticfiles]
collectstatic
findstatic
runserver
(venv) (base) cuixiaozhaodeMacBook-Pro:NQMP cuixiaozhao$
Type 'manage.py help <subcommand>' for help on a specific subcommand.
Available subcommands:
[auth]
changepassword
createsuperuser
[contenttypes]
remove_stale_contenttypes
[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver
[django_crontab]
crontab
[sessions]
clearsessions
[staticfiles]
collectstatic
findstatic
runserver
(venv) (base) cuixiaozhaodeMacBook-Pro:NQMP cuixiaozhao$
2、settings.py
保存项目所有的配置信息
迁移是非常强大的功能,它能让你在开发过程中持续的改变数据库结构而不需要重新删除和创建表 - 它专注于使数据库平滑升级而不会丢失数据。
所有的配置,都写在setting.py里面
打开structure结构,便于查看目录结构;
3、urls.py
URL与视图函数映射
当包括其它 URL 模式时你应该总是使用 include() , admin.site.urls 是唯一例外。
主要的urls目录和从urls.py相互拼接形成URL
拼接的思想
4、wsgi.py
不需要进行任何的修改,用于做部署关联!
uWSGI应用服务器
Django内置的
前后端,沟通的桥梁!
009-【Django URL】Django的项目规范
Django推荐的项目规范
1、如果没有配置URL,默认返回Django2.0内置的欢迎页面!
2、代码放在N个函数中,就叫做视图函数;
FBV
CBV
3、按照功能或者模块进行分层,即django app;
使用include方法对URL分发处理
Django与Flask
Flask随便写
写的其他人(菜鸟级别)都看不懂,个人理解哈!
安装大量的第三方依赖包,缺什么安装什么
不如Django正规
最后的本质跟Django一样了,所以新手还是选择Django!大而全,该有的都有!
而且使用起来规范
Django已经定义好规范
遵循规范和自定义部分目录,新手容易看懂
Django与Flask的区别
海军和海盗的区别!
自由和规范的区别
010-【Django URL】DEBUG模式详解
1、如果开启了DEBUG模式,修改了Django项目代码,按下Ctrl+S键,那么Django就会自动的给我们重启项目,无需手动重启
MacOS是command+R
也有不自动重启的时候,不能过分依赖Django框架本身
2、如果开启了DEBUG模式,Django项目出现代码,浏览器和控制台会出现报错信息
具体到某行代码出错
生产环境禁用!!!
3、生产环境中禁止DEBUG模式开启
不然有很大的安全隐患
4、DEBUG设置为False,必须要设置ALLOWED_HOSTS
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
PS
ALLOWED_HOSTS这个变量用来设置限制IP或者域名访问
011-【Django URL】视图函数介绍
1、视图一般写在app的views.py中但不绝对,第一个参数永远是request!!
不能少
book() takes 0 positional arguments but 1 was given
可以添加多个参数,但在URL中要一一对应;
2、视图中一般完成业务逻辑(即功能)的操作
FBV
CBV
3、视图函数的返回结果必须是HttpResponseBase对象或者其子类的对象
类🈶继承关系,所以是类或者子类
012-【Django URL】URL映射补充
为什么会去urls.py中寻找映射呢?!
settings.py中的ROOT_URLCONF = 'VIEW_FUNC_DEMO.urls'
URLCONF
1、urls.py中的映射都应该放在urlpatterns中
path+转换器
re_path
即正则path
2、所有的映射应该使用path或者re_path进行包装
Django规范的地方,体现的淋漓尽致
013-【Django URL】url中传递参数给视图函数
1、采用在url中使用变量的方式,path的第一个参数,使用<参数名>的方式传递参数
视图函数中与url中变量名称及数量保持一致
2、采用“查询字符串”的方式,在url中,不需要单独的匹配查询字符串,只需要在试图函数中使用request.GET.get('参数名','')方式来获取
因为查询字符串使用的是GET请求,request.GET对象的本质是字典,所以使用get方法
015-【Django URL】urls分层模块化
1、如果项目变得越来越大,url会变得很多,都放在主urls中不太好管理,所以进行url的分发处理
任何事情不是绝对的,分发也不是,可以在主url中定义view.index等函数
2、每个app中自行创建urls.py并在主urls.py进行include引用,分发处理;
3、主urls.py和app中的urls.py进行拼接,注意不要多加斜杠!
会进行urls的拼接
4、无论主urls还是app的urls,都放在urlpattern列表中
主urls.py与其他urls.py进行配合使用
014-【Django URL】Django内置的URL转换器
Django内置URL转换器
默认是str转换器
默认值,其他值
str
除了斜杠以外所有的字符都是可以的
int
一个或多个阿拉伯数字
path
所有字符都满足
uuid
格式需要符合uuid.uuid4()
django-shortuuid,第三方依赖包
>>> import uuid
>>> uuid.uuid4()
UUID('4f5ae9b8-3b85-4cf0-b093-947a52628431')
>>>
>>> uuid.uuid4()
UUID('4f5ae9b8-3b85-4cf0-b093-947a52628431')
>>>
slug
英文中的横杠或者英文字符或阿拉伯数字等
自定义URL转换器(Conventers)
DEFAULT_CONVERTERS = {
'int': IntConverter(),
'path': PathConverter(),
'slug': SlugConverter(),
'str': StringConverter(),
'uuid': UUIDConverter(),
}
'int': IntConverter(),
'path': PathConverter(),
'slug': SlugConverter(),
'str': StringConverter(),
'uuid': UUIDConverter(),
}
from django.urls import converters
import uuid
uuid.uuid4()
UUID('586a6e86-3e60-4bb5-9ef7-2a943ff7859c')
uuid.uuid4()
UUID('586a6e86-3e60-4bb5-9ef7-2a943ff7859c')
uuid.uuid4()
UUID('1d19dfc2-b913-47ce-b780-0057ad237674')
UUID('1d19dfc2-b913-47ce-b780-0057ad237674')
查看源代码的方法
自定义开发URL转换器的大体步骤
regex
to_python
to_url
016-【Django URL】urls命名与反转url
1、为什么需要给url命名?
以后无论(产品经理的)需求如何变化,url都不受影响
使用到了Django的url反转reverse
from django.shortcuts import render,redirect,reverse
3R原则
render
redirect
reverse
因为url是经常变化的,如果在代码中写死可能会经常改动代码,给url取个名字,以后使用url的时候使用它的名字进行反转就OK了,就不需要写死url了。
2、如何给第一个url指定名称
在path函数中,传递一个name参数就可以指定了
3、应用命名空间
应用命名空间的变量
app_name = "users"
不同的应用可能出现相同的name值
在多个app之间,可能产生同名的url,为了避免反转url时候产生混淆,可以使用应用命名空间来做区分
加大了一个区分维度。
定义应用空间的方式,在app的urls.py中定义app_name变量即可
PS:推荐使用app_name=“”的应用命名空间形式
4、应用命名空间和实例命名空间
app_name
name
创建front和cms Django App
017-【Django URL】应用命名空间和实例命名空间
应用命名空间也就是app命名空间
为什么还要使用实例命名空间呢?
多个URL映射到同一个App下,反转的时候,使用应用命名空间,会出现窜位的现象
为了解决这个问题,使用实例命令空间来解决
current_namespace = request.resolver_match.namespace
return redirect(reverse("%s:login"%current_namespace))
return redirect(reverse("%s:login"%current_namespace))
reverse(“应用命名空间:URL别名”)的形式
include中指定namespace
不推荐使用该方法
018-【Django URL】include函数详解
指定了namespace就必须在子url中配置app_name
'Specifying a namespace in include() without providing an app_name '
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
两者相辅相成出现
2、include函数的用法
1、include(module,namespace=None)
这种形式用的最多
在子urls中指定app_name
2、include((pattern_list,app_namespace),namespace=None)
path('book/', include(('book.urls','book'), namespace='book')),
将include中写成元组的形式
3、include(pattern_list)一般不会用,闲得无聊,别人也看不懂
path('movie/', include([
path('', views.movie),
path('list/', views.movie_list),
])),
path('', views.movie),
path('list/', views.movie_list),
])),
019-【Django URL】re_path函数详解
re_path就是re+path
1、re_path和path的作用是一致的,只不过re_path在书写的时候可以使用正则表达式,功能更加强大!
普通的urls使用过滤器即可完成效果!
2、写正则表达式都推荐使用原生字符串,也就是以r开头的字符串
3、正则表达式中定义变量,需要使用圆括号括起来,便于Django识别(?P<参数的名字>)
一般需求使用Path,除非特别的需求才使用re_path来处理,比如年月日
PyCharm快捷键-Alt+数字1
开、合左侧目录
Mac也可以
020-【Django URL】reverse函数补充
1、如果在反转url时候,需要添加参数,那么可以传递kwargs参数到reverse函数中
kwargs=
keyword
arguments
2、如果想要添加查询字符串的参数,则必须手动拼接
reverse函数无法直接处理查询字符串
021-【Django URL】自定义path转换器
1、/articles/python/
2、/articles/python+django/
3、/articles/python+flask+django/
自定义URL转换器的几大步骤
1、定义一个类
2、定义属性regex
3、to_python
4、to_url
5、注册
6、添加至__init__.py中被加载过程中就已经执行
7、使用转换器名称
022-【Django URL】URL映射时指定默认参数
1、自定义默认参数
2、在试图函数中指定默认参数,比如page=1
章节03-Django模板
023-【Django模板】模板介绍
什么是模板?
templates
就是特殊的html文件
1、视图函数返回文本或者HTML标签语言
2、知名的模板系统DTL、Jinja2
含有特定的语法
3、Django框架默认使用DTL、Flask使用Jinja2;
什么是框架默认的就使用什么
Django-DTL
Flask-Jinja2
官方推荐的,肯定是耦合性比较好的!
如果不是专业搞底层的,应用开发程序员还是使用成型的内容来推动业务的进行,没必要讲究刻意追求技术!
4、DTL与普通的HTML文件的区别
DTL模板是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化,在编译完成后,生成一个普通的HTML文件,最后发送给客户端。
Django Template View,本质就是动态的HTML文件!
5、使用render来代替render_to_string
Django1.11的语法
Django2.0的语法
024-【Django模板】模板的查找路径
1、DIRS
将templates目录添加到项目中
2、APP_DIRS
在app中寻找模板文件
True或者False
模板在Django项目中的查找顺序
1、DIRS中
2、APP_DIRS
3、其他位置
4、抛出异常
思想
所有一切的配置,都是写在settings.py配置文件中的
025-【Django模板】模板变量使用详解
1、DTL中避免使用keys、values、items作为键名,避免调用过程产生歧义
使用频率比较高的单词,避免使用作为变量名称
2、在模板中使用变量,需要将变量放置到{{ 变量 }},注意左右两侧空格,等号=两侧不能有空格
3、访问对象的属性,可以通过对象名.属性名来进行访问
4、访问列表或者元组,不能使用中括号[],应该使用persons.1形式获取数据
一定要注意
DTL语言和Python还是有区别的
思想
尽可能在视图函数中写逻辑操作
在模板系统中调用
026-【Django模板】if标签使用详解
1、常用的模板标签
if与endif
连在一起使用!
for与endfor
with与endwith
2、所有的标签都是在{% xxx %}之间
3、if标签有闭合标签,endif
027-【Django模板】for标签使用详解
forloop.counter
forloop.counter0
forloop.revcounter
forloop.revcounter0
forloop.parentloop
for循环中嵌套for循环
forloop.first
forloop.last
for in empty
实际应用场景:这里没有任何评论
for中没有continue和break
028-【Django模板】with标签的使用
with给变量定义别名
with persons.0 as zs
endwith
endwith
as起个别名
DTL中左右两侧不能有空格
小结:
with语句的两种使用形式
定义的变量只能在with语句中使用,在with外部使用取不到这个变量
029-【Django模板】url标签详解
{% url 'book' %}
{% url 'detail' book_id='1' %}
查询字符串的方式,同reverse函数一样,只能手工去添加{% url 'login' %}?next=/
030-【Django模板】autoescape标签使用详解
移除html标签中的空白字符,包括空格、tab键、换行符等;
默认autoescape是开启了自动转义的,特殊需求的话,手工off掉
031-【Django模板】verbatim标签使用详解
不需要渲染的标签,使用verbatim
GitHub上art-template的使用
https://github.com
类似于html中的pre标签
032-【Django模板】DTL常用过滤器(1)
1、什么是过滤器
本质是函数,最多接收2个参数
2、为什么需要过滤器
因为在DTL中,不支持函数的调用形式,因此不能给函数传递参数,这将有很大的局限性
3、add过滤器
value1|add:value2
4、cut过滤器
切除空白字符
033-【Django模板】DTL常用过滤器(2)
1、国内与国外的年月份表示顺序不同
月日年、日月年
2、{{ birthday|date:"Y/m/d G:i:s" }}
Django Template 过滤器
034-【Django模板】DTL常用过滤器(3)
1、default
[]、""、{}、None
2、default_if_none
{{ value4|default:"我是默认值啦~~!!" }}
<hr>
{{ value5|default_if_none:"我是default_if_none啦~~!!" }}
<hr>
{{ value5|default_if_none:"我是default_if_none啦~~!!" }}
3、first&last
{{ last_value|last }}
4、floatformat
{{ value4|floatformat:3 }}
035-【Django模板】DTL常用过滤器(4)
1、join
拼接
2、length
长度查看
3、lower
小写字母
4、upper
大写字母
5、random
产生随机数
6、safe
标记为安全!
js中用到
036-【Django模板】DTL常用过滤器(5)
1、slice
类似于Python中的列表切片操作
2、stringtags
清除html的默认样式
3、truncatechars
北京...显示点点点的效果
{{ value|truncatechars:"5" }}
4、truncatechars_html
037-【Django模板】自定义过滤器步骤详解
1、为什么需要自定义过滤器
满足业务需求
2、主要步骤
1、创建package-templatetags
一定是该命名!
2、在templatetags下创建my_filter.py文件
3、将过滤器所在的app进行INSTALLED_APPS注册
4、在my_filter.py中定义过滤器,也就是函数
5、写完过滤去后(函数)使用django.template.Library.filter进行注册
6、在模板文件中使用load标签,进行过滤器的加载
7、可以使用过滤器了
小结:
1、过滤器最多只能有两个参数
2、过滤器的第一个参数永远都是被过滤的那个参数,竖线|左边的值
038-【Django模板】自定义过滤器实战
1、自定义时间计算过滤器
2、实战代码
@register.filter()
def time_since(value):
"""
time距离当前时间的时间规则:
1、小于1分钟,显示“刚刚”;
2、1分钟到1小时,“xxx分钟前”;
3、大于1小时小于24小时,显示“xx小时前”
4、大于24小时,小于30天内,显示“xx天前”;
5、否则显示其具体时间!
:param value:
:return:
"""
if not isinstance(value, datetime):
return value
now = datetime.now()
timestamp = (now - value).total_seconds()
if timestamp < 60:
return "刚刚"
elif 60 <= timestamp < 60 * 60:
minutes = int(timestamp / 60)
return "%s分钟前" % minutes
elif 60 * 60 <= timestamp < 24 * 60 * 60:
hours = int(timestamp / 60 / 60)
return "%s小时前" % hours
elif 24 * 60 * 60 <= timestamp < 30 * 24 * 60 * 60:
days = int(timestamp / 60 / 60 / 24)
return "%s天前" % days
else:
return value.strftime("%Y/%m/%d %H:%M")
def time_since(value):
"""
time距离当前时间的时间规则:
1、小于1分钟,显示“刚刚”;
2、1分钟到1小时,“xxx分钟前”;
3、大于1小时小于24小时,显示“xx小时前”
4、大于24小时,小于30天内,显示“xx天前”;
5、否则显示其具体时间!
:param value:
:return:
"""
if not isinstance(value, datetime):
return value
now = datetime.now()
timestamp = (now - value).total_seconds()
if timestamp < 60:
return "刚刚"
elif 60 <= timestamp < 60 * 60:
minutes = int(timestamp / 60)
return "%s分钟前" % minutes
elif 60 * 60 <= timestamp < 24 * 60 * 60:
hours = int(timestamp / 60 / 60)
return "%s小时前" % hours
elif 24 * 60 * 60 <= timestamp < 30 * 24 * 60 * 60:
days = int(timestamp / 60 / 60 / 24)
return "%s天前" % days
else:
return value.strftime("%Y/%m/%d %H:%M")
函数是一定要有返回值的
039- 【Django模版】模版结构优化之include标签详解
通过include方法进行模板的引入
header部分
content部分
footer部分
{% include 'header.html' %}
这里是内容
{% include 'footer.html' %}
这里是内容
{% include 'footer.html' %}
子模板可以使用父模板中的变量
如果想要在include子模板的时候,传递一些参数,可以使用with username='cuixiaozhao'的方式引入
模板的继承,这里是重点
类似于Python的类继承!
1、部分模板的代码重复,可以单独抽取出来,哪里需要用到,就直接使用include 进行引入即可。
2、include子模板传递一些参数,可以使用with username = "cuixiaozhao"。
思想
extends和include联合使用
先继承父模板
include引入多次被调用的地方的代码
040- 【Django模版】模版结构优化之继承详解
{% extends 'BASE.html' %}
子模板使用父模板中的内容
{{ block.super }}
子模板中可以重写父模板内容
extends 必须放在第一行中
下方可以添加{% load static %}
不再使用load staticfiles
Django1.X的语法
子模板中自定义的内容必须放在block区块中,否则不会显示
父模板中的变量可以在子模板中使用!
041-【Django模板】模板中加载静态文件详解
1、加载静态文件的步骤
1、django.contrib.staticfiles已经添加至INSTALLED_APSS
2、settings.py中,配置了STATIC_URL
3、应用下新建cms/static/cms/logo.png
4、settings.py中添加STATICFILES_DIRS
5、STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'STATIC')
]
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'STATIC')
]
6、配置'builtins': ['django.templatetags.static'],无需每次在模板中{% load static %}
弊端是PyCharm无法进行语法检测
有利有弊!
2、一些使用技巧
Ctrl+Shift+R不使用缓存加载文件
配置'builtins': ['django.templatetags.static'],无需每次在模板中load static
章节04-Django数据库
042-【Django数据库】数据操作和相关软件包介绍
MySQL数据库
只有提供数据,数据才能动态展示
数据来源于数据库,通过ODBC或者JDBC协议进行连接
MySQL数据库安装
配置用户名和密码
Navicat For MySQL工具的使用
Navicat For Premium无法使用数据传输功能
优缺并存
MySQL command Line Client
便于学习使用
不好用呀!
MySQL驱动的安装
常见MySQL驱动
1、MySQL-python
2、mysqlclient
3、pymysql
5、cymysql
4、MySQL Connector Python
import pymysql
pymysql.install_as_MySQLdb()
pymysql.install_as_MySQLdb()
或者修改Django.db中的文件,将判断语句注释掉!
043-【Django数据库】Django使用原生SQL语句来创建数据库
Navicat For MySQL 图形化工具的使用
修改Django默认数据库连接
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎;
'NAME': 'DB_OPERATION_DEMO', # 数据库实例名称;
'USER': 'root', # 用户名;
'PASSWORD': '', # 密码;
'HOST': 'mysql.cuixiaozhao.com', # 数据库主机名或者IP;
'PORT': '3306', # 数据库端口号;
}
}
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎;
'NAME': 'DB_OPERATION_DEMO', # 数据库实例名称;
'USER': 'root', # 用户名;
'PASSWORD': '', # 密码;
'HOST': 'mysql.cuixiaozhao.com', # 数据库主机名或者IP;
'PORT': '3306', # 数据库端口号;
}
}
RDS数据库,就是通过域名的方式来提供连接的!
Python DB API 规范下cursor对象常用接口
fetchone
fetchmany
fetchall
PS:思想:一多全!
一个
多个
全部
建议使用web.py-dev1
来执行原生数据库语句查询操作!
044-【Django数据库】图书管理系统案例(1)
index
add_book
book_detail
delele_book
增删改查操作
应用程序员的日常工作就是基本的增删改查!
045-【Django数据库】图书管理系统案例(2)
图书管理系统的增加和删除操作
一个完整的Django请求流程
MTV
即著名的设计模式,MVC
总计有很多种设计模式
046-【Django数据库】ORM模型介绍
ORM介绍
原生的SQL的缺点
1、SQL语句重复利用率不高
2、很多SQL语句是业务逻辑拼接出来的,业务变化,语句就要进行大量变化
3、写原生SQL语句容易遇到Web安全问题,给未来造成隐患
SQL注入
PS:ORM简称对象关系映射,基于ORM语句,通过操作类的形式去操作数据库
理论上来说,原生SQL的查询效率会比ORM高一些
就好比C语言是所有语言的鼻祖
ORM模型的优点
1、易用性
可以写出非常复杂的查询语句
2、性能损耗小,带来的好处远远大于弊端
开发效率
代码的可阅读性
节省的成本可以用来增加硬件开销
或者云服务器
3、设计灵活,可以写出非常复杂的查询操作
ORM真的是这样的!
4、 可移植性
Django底层封装了多个关系型数据库引擎,轻松实现数据库切换
不关心后端使用何种数据库
类似于MyCat,不再关心后端的数据库是哪种类型的
MySQL、Oracle、PostgreSQL
使用Django开发网站,优先使用ORM语句!!!
047-【Django数据库】创建和映射ORM模型
1、首先在settings.py中配置好DATABASES,做好数据库配置,前提是已经通过命令行或者Navicat创建了数据库实例
修改为MySQL后,需要导入MySQL驱动程序pymysql
2、在app中的models.py中定义好模型,这个模型继承自django.db.models
3、将这个app添加到settings.py的INSTALLED_APPS中
4、执行makemigrations和migrate,实现数据库的迁移操作
Django数据库默认自带连接对象,可以不用使用第三方依赖-pymysql
最好用的还是web.py的使用,用于查询数据库!
048-【Django数据库】ORM中的基本的增删改查操作
添加数据
book.save()方法
一定要执行save方法,不然数据无法写入数据库
查找数据
get或者filter
first()
last()
all()
删除数据
思想:先查找到之后,再执行delete()操作
修改数据
查询到数据之后,进行重新赋值操作
049-【Django数据库】ORM常用的Field详解(1)
AutoField
BigAutoField
BooleanField
不再使用null=False
使用NullBooleanField来代替
CharField
必须制定max_length=256(以内的数值)
字符长度超过256之后,使用TextField
050- 【Django数据库】native时间和aware时间详解
DateField
DateTimeField
1、什么是native时间?什么是aware时间?
native-幼稚
aware-成熟的
import pytz
from datetime import datetime
now = datetime.now()
from datetime import datetime
now = datetime.now()
2、settings.py中的时区配置
USE_TZ = True,不建议将USE_TZ设置为False
如果设置为False,那么Django读取到的时间就是native类型的时间
知了课堂厉害,慕课网稍逊风骚!
051-【Django数据库】ORM常用的Field详解(2)
1、replace方法
可以将一个时间的某些属性进行更改
2、django.utils.timezone.now方法
3、django.utils.timezone.localtime方法
4、native和aware介绍以及在Django中的使用
创建时间和更新时间
auto_now
auto_add_now
TimeField
DateField
DateTimeField
052-【Django数据库】ORM常用的Field详解(3)
EmailField
类似于CharField类型
EmailField在数据库层面并不会限制字符串一定要满足邮箱格式,只是以后在使用ModelForm等表单相关操作的时候会起到作用
So,该使用何种格式,就使用何种格式!
FileField
ImageField
FloatField
IntegerField
BigIntegerField
TextField
UUIDField
URLField
https
http
ftp
053-【Django数据库】Field中常用参数详解
null
空字符串与null的区别
blank
db_column
default
blank=True,null=True联合使用
054-【Django数据库】Meta类中的常见配置
db_table
ordering
加上负号,倒序排列
055-【Django数据库】ORM外键使用详解
1、外键概念
ForeignKey
2、MySQL表引擎
InnoDB
MyISam
3、引用另外一个模型中的名字
author = models.ForeignKey("frontuser.FrontUser", on_delete=models.CASCADE, null=True)
可以添加,可以不添加!
4、引用自身
self
绝对路径和相对路径的问题
056-【Django数据库】ORM外键删除操作详解
project受保护的外键
视作业务水平而定
SET_NULL与null = True联合使用
SET_DEFAULT与default= “0”联合使用
author = models.ForeignKey("frontuser.FrontUser", on_delete=models.SET_DEFAULT, default=Category.objects.get(pk=4))
SET
可以指定函数,在函数中定义返回值
可以指定函数,在函数中定义返回值
DO_NOTHING
不采取任何行为,一切全看数据库级别的约束,不是ORM级别
057-【Django数据库】表关系之一对多
1、一对多
category.article_set()
related_name = 'articles'反向引用
2、多对多
多个表对应多个表
3、一对一
额外一张表存储不常用字段
058-【Django数据库】表关系之一对一
一对一,比如User表和UserExtentions表
两张表联合存储用户的多种信息
一张表存储常用信息
另外一张表存储不变化信息,提高查询效率,可取
059-【Django数据库】表关系之多对多
文章和标签的关系
ManyToMany
中间表进行连接
Django自动创建一张表进行存储对应关系
060-【Django数据库】ORM查询条件详解-准备工作
1、查询条件
exact
iexact
2、聚合函数的使用
Count,Avg,Min,Max,Sum
3、F和Q
与或非
4、修改默认数据库连接
SQLite
仅仅适用于开发
makemigrations
migrate
不适用于生产环境,大数据量部署
5、使用PyCharm连接MySQL数据库
下载安装JDBC连接驱动
6、视图函数的准备工作
061-【Django数据库】pycharm连接数据库
Database选项卡
安装MySQL连接驱动
PyCharm本身是Java编写的,所以要使用到JRE
PyCharm无法下载MySQL数据库驱动的话,可以去MySQL官网下载,再导入到工具中进行使用
不过一般来说,不用的
062-【Django数据库】ORM查询条件详解-exact和iexact
1、Django自定义的规则
2、查询条件
exact
3、对MySQL的大小写是否敏感
Windows
不敏感
utf8mb4_general_ci
排序规则
utf8mb4_bin
Linux
敏感
utf8mb4_general_ci
utf8mb4_bin
小结
不同的操作系统环境,不一致!
小结
exact会被翻译成=
iexact会被翻译成LIKE
063-【Django数据库】ORM查询条件详解-contains和Icontains
QuerySet.query可以用来查看这个ORM查询语句最终被翻译成的SQL语句。但是query只能作用在QuerySet对象上,不能用普通的ORM模型
connection.queries
get方法不能使用query,因为get方法返回的是满足条件的ORM模型
filter方法可以使用query进行查询
contains和icontains,区别就是大小写不敏感
contains会使用like binary
icontains会使用like
064-【Django数据库】ORM查询条件详解-in和关联模型查询
id__in =[1,2,3]
用于指定某个范围
article__id__in =[1,2,3]
基于双下滑线方式查询
如果要判断相关联的表的字段,也通过__来连接,并且在反向引用的时候不需要写model_set,直接使用模型名称的小写化即可
如果不想使用默认的形式,可以在外键定义的时候,传递related_query_name来指定反向引用的名字
in可以指定
列表
元组
QuerySet,本质也是list
使用type方法
小结
反向查询是将模型名字小写化,比如article_in
反向引用是将模型名字小写化,然后再加上_set
065-【Django数据库】ORM查询条件详解-gt、gte、lt和lte
gt
greater than
gte
greater than equal
lt
lower than
lte
lower than equal
066-【Django数据库】ORM查询条件详解-startwith和endwith
startswith
SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id` FROM `article` WHERE `article`.`title` LIKE hello%
istartswith
endswith
iendswith
i字母说明
ignore,不区分大小写
数据库层面进行配置,是否区分大小写!
067-【Django数据库】ORM查询条件详解-range
from django.utils.timezone import make_aware
关于事件查询的条件
range可以指定一个时间段,并且应该标记为aware,不然系统会发出RuntimeWarning
068-【Django数据库】ORM查询条件详解-date、time、year、week_day等
SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE DATE(CONVERT_TZ(`article`.`create_time`, 'UTC', 'Asia/Shanghai')) = 2019-02-15
Windows系统
MySQL数据库中默认没有“时区信息”
https://dev.mysql.com/downloads/timezones.html
下载之后,进行文件的导入
将文件拷贝替换后,重启MySQL服务
*nix系统
使用命令进行拷贝
mysql_tzinfo_to_sql /usr/share/zoneinfo |mysql -D mysql -u root -p
year根据年份查找
month
day
week_day
1表示星期天,7表示星期六
time
Django的官方文档也会有错误的时候
根据分时秒进行查找
069-【Django数据】ORM查询条件详解-isnull和regex
isnull
SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE `article`.`create_time` IS NOT NULL
regex
Python中使用r表示原生字符串
Django1.11中的urls部分使用的多
根据关联的表进行查询
正向查询
反向查询
聚合函数
070-【Django数据库】ORM聚合函数详解-准备工作
聚合函数初识
F、Q、Count、Sum,Avg等等
创建新的Django项目,导入sql文件
使用Navicat For MySQL工具进行导入
备份数据库的时候,使用Navicat将数据结构和数据全量备份
表结构
数据备份
source导入
使用Navicat For MySQL工具进行操作,Navicat For Premium无法实现
071-【Django数据库】ORM聚合函数讲解Avg
1、所有的聚合函数都是放在django.db.models下面
聚合函数的方法需要放在某个方法中执行
aggregate
2、聚合函数执行完毕后,默认名字为:filed+__+聚合函数的名字
如果不使用默认的名字,可以传递关键字参数进行重新指定
avg = Avg("price")
3、aggregate这个方法不会返回一个QuerySet对象,而是返回一个字典,字典的值就是聚合函数的返回结果
072-【Django数据库】ORM聚合函数详解aggregate和annotate
aggregate
默认不包含分组
annotate中包含group_by分组
results = Book.objects.annotate(avg=Avg("bookorder__price"))
for book in results:
print("%s %s" % (book.name, book.avg))
for book in results:
print("%s %s" % (book.name, book.avg))
体会分组查询的概念
小结:两者的异同
这两个函数都可以执行聚合函数Avg
aggregate返回的是字典;annotate返回的是QuerySet,并且会在查找的模型上添加一个聚合函数的属性
aggregate不会做group by分组,而annotate会做分组
073-【Django数据库】ORM函数详解Count
count获取指定对象的个数
Count可以去重
添加参数distinct = True
result = Book.objects.aggregate(book_nums=Count("id", distinct=True))
SELECT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, COUNT(`book_order`.`id`) AS `book_nums` FROM `book` LEFT OUTER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) GROUP BY `book`.`id` ORDER BY NULL
074-【Django数据库】ORM函数详解Max、Min
Max
SELECT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, MAX(`book_order`.`price`) AS `max`, MIN(`book_order`.`price`) AS `min` FROM `book` LEFT OUTER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) GROUP BY `book`.`id` ORDER BY NULL
Min
075-【Django数据库】ORM函数详解Sum
Sum函数
先过滤,再查询
SELECT SUM(`book_order`.`price`) AS `total` FROM `book_order` WHERE `book_order`.`create_time` BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 23:59:59.999999'
filter().aggregate
复杂的查询操作
SELECT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, SUM(`book_order`.`price`) AS `total` FROM `book` INNER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) WHERE `book_order`.`create_time` BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 23:59:59.999999' GROUP BY `book`.`id` ORDER BY NULL
链式调用
比如求一本图书在2019年的销售总额
通过Django官方网站进行学习
076 -【Django数据库】F表达式详解
F聚合函数会动态的去获取某一个值,然后进行修改
为每一本图书增加10元
Book.objects.update(price=F("price") + 10)
使用F函数,类似于迭代器的意思
authors = Author.objects.filter(name=F("email"))
077-【Django数据库】Q表达式详解
想要实现所有价格高于100元,并且评分达到9.0以上的图书
books = Book.objects.filter(Q(price__gte=100) & Q(rating__gte=4.8))
books = Book.objects.filter(price__gte=100, rating__gte=4.85)
想要实现所有价格高于100元,或者评分达到9.0以上的图书
books = Book.objects.filter(Q(price__gte=100) | Q(rating__lte=4))
books = Book.objects.filter(Q(price__gt=100) | Q(rating__lt=4))
F
与
Q
或
~Q
非
078-【Django数据库】objects对象所属类原理剖析
QuerySetAPI
Type用来动态创建类
想要实现所有价格高于100元,并且评分达到9.0以上的图书
Type作用,一来打印类型,二来动态创建类
模型.objects这个对象是django.db.models.manager.Manager的对象,这个类是一个空壳类,他上面的所有方法都是QuerySet这个类上面拷贝来的,因为学会了QuerySet就学会了objects如何使用了
079-【Django数据库】QuerySet API详解-filter、exclude、annotate
books = Book.objects.filter(id__gte=2)
books.filter(~Q(id=3))
books.filter(~Q(id=3))
books = Book.objects.filter(id__gte=2).filter(~Q(id=3))# Python中的链式调用;
filter
exclude
annotate
80-【Django数据库】-QuerySet API详解-order_by
根据创建时间正向排序
orders = BookOrder.objects.order_by("create_time", "price")
根据创建时间倒向排序
orders = BookOrder.objects.order_by("-create_time", "price")
使用负号
根据名字正向排序
根据名字倒向排序
先根据创建时间正向排序,再根据作者的姓名倒向排序
注意一点
多个order_by会把前面的排序规则给打乱,而使用后面的排序方式
如果再models中定义了ordering排序规则,那么在ORM查询语句中就无需使用order_by
ordering = ['create_time','price']
还可以根据annotate定义的字段进行排序
81-【Django数据库】QuerySet API详解-values、values_list
values
有时候在表中查找数据的时候,并不是想要把所有的字段都提取出来,我们有可能只是想要其中的几个字段,这时候可以使用values来实现
values默认提取表模型中的所有字段,但是可以指定被提取的字段
values的返回值同样是QuerySet对象,但是本质是字典
如果想改名,可以是关键字参数,结合F表达式使用,但是名称不能与之前原有的字段名相同
values可以使用聚合函数
values_list
返回的QuerySet中是元组
元组中之有一个元素的时候,使用逗号分隔!要不然系统无法区分
一定要这么做!
flag=True,可以实现数据扁平化操作
多个值就会报错!
避免浅尝辄止,应该深入下去,做任何事情都一致~
82-【Django数据库】QuerySet API详解 -all方法
Book.objects.all()会返回一个QuerySet对象,这个对象是原生的,没有经过任何修改(过滤)
83-【Django数据库】QuerySet API详解-select_related
在查找某个表的数据的时候,可以一次性把相关联的其他表的数据都提取出来,可以避免多次查询数据库,减少数据库开销!
但是select_related不能跨表查询
84-【Django数据库】QuerySet API详解-prefetch_related
prefetch_related会类似于迭代器的方式,减少查询次数,提高查询性能,可支持跨表查询操作
prefetch_related不能再使用filter等方法
如果想使用其他的做法,就是django.db.models.Prefetch
85-【Django数据库】QuerySet API详解-defer和only
这两个方法都会返回一个QuerySet对象,并且这个QuerySet中装的都是模型,而不是字典
defer过滤
only提取
使用了之后再使用的话,会重新发起一次请求,要谨慎操作。
86-【Django数据库】QuerySet API详解-get方法
get方法,只能返回一条具体数据,注意不是QuerySet对象,如果有多条数据或者空数据,会报错!
87-【Django数据库】QuerySet API详解-create方法
原来是两步操作,先查询再save()
publisher = Publisher(name="知了出版社")
publisher.save()
publisher.save()
直接create,创建过程之间遍保存了
publisher = Publisher.objects.create(name="知了出版社啦啦啦!")
88-【Django数据库】QuerySet API详解-get_or_create,bulk_create
get_or_create
有则查询,无则先创建出来再查询出来
result1 = publisher = Publisher.objects.get_or_create(name="知了课堂19930911")
bulk_create
打包创建
result1 = Publisher.objects.bulk_create([
Publisher(name="123出版社"),
Publisher(name="出版社123"),
Publisher(name="123出版社123"), ]
)
Publisher(name="123出版社"),
Publisher(name="出版社123"),
Publisher(name="123出版社123"), ]
)
一次性创建所有数据
89-【Django数据库】QuerySet API详解 count和exists
count
比Python中的len方法更高效
计算QuerySet中的个数,使用count比len高效
first
返回QuerySet中的第一条数据
last
返回QuerySet中的最后一条数据
aggregate使用聚合函数
exists
判断某个条件的数据是否存在
比count()>0更高效
比if是否存在更高效
distinct()
去重处理
90-【Django数据库】QuerySet API详解-distinct
去除重复的数据
books = Book.objects.filter(bookorder__price__gte=80).distinct()
如果使用了order_by语句,就无法将重复的数据过滤掉
通过annotate新增字段后,也无法实现将重复数据过滤掉
91-【Django数据库】QuerySet API详解-update和delete
update方法
Book.objects.update(price=F("price") + 5) # 一次性执行所有的sql语句;
delete方法
思路:先删除再修改
一次性可以把所有满足条件的数据进行删除,但是要注意models中on_delete的处理方式
92-【Django数据库】QuerySet API详解-切片操作
将查找的数据进行切片操作,提取其中的一部分数据
注意切片的原理不是从数据库中提取出来再切片,而是在数据库层面使用LIMIT和OFFSET来完成,所以如果提取一部分数据的时候,建议大家使用切片操作
books = Book.objects.all()[0:2]
支持步长操作
93-【Django数据库】QuerySet API详解-QuerySet转换为SQL的条件
迭代
使用步长做切片操作
len函数
list函数
判断
以上条件一出现,就立马执行SQL语句
94-【Django数据库】QuerySet ORM作业详解准备工作
98-【Django数据库】ORM迁移详解-migrations命令补充
makemigrations
后面可以跟上app_label
--name可以为执行的迁移脚本提供注释
--empty生成一个空的迁移脚本
migrate
showmigrations
sqlmigrate
前提是INSTALLED_APPS中添加了Django Application
99-【Django数据库】ORM
100-【Django数据库】ORM
章节05-视图高级
102 【Django视图高级】限制请求method装饰器
from django.views.decorators.http import require_http_methods, require_GET, require_POST, require_safe
@require_http_methods(['GET'])等价于require_GET装饰器
前者可以传递多个参数
通过装饰器方式来限制HTTP方法,优秀!
103 【Djangot视图高级】重定向详解
永久性重定向
301,多用于旧网站废弃,要跳转到新的网址确保用户的访问,比如访问www.jingdong.com或者www.360buy.com跳转至www.jd.com
暂时性重定向
302,比如页面的暂时性跳转,访问一个需要权限的网址,用户如果没有登录,应该使用暂时性重定向!
知乎网站,如果没有登录的话,就会自动跳转至注册页面。
使用redirect和reverse进行重定向和反转URL操作
设计应用命名空间
return redirect(reverse("front:signup"))
坚持某一个URL对应某一个页面,才符合Web开发规范!
104【Django视图高级】HttpRequest对象讲解
WSGIRequest对象
Django在接收到http请求之后,会根据http请求携带的参数以及报文信息创建一个WSGIRequest对象,并且作为视图函数的第一个参数传递给视图函数,对象的完整路径是django.core.handlers.wsgi.WSGIRequest
<class 'django.core.handlers.wsgi.WSGIRequest'>
浏览器中的XHR,代表查看Ajax请求
请求头RequestHeaders
request.POST.get()
request.GET.get()
request.META.get()
WSGIRequest对象常用属性和方法
WSGIRequest对象大部分上都是只读的,因为这些属性都是从客户端上传来的,没必要做任何修改,常用属性详解:
path
method
GET
类似于字典
POST
django.http.request.QueryDict对象,这个属性包含了所有以POST方式上传上来的参数
FILES
COOKIES
session
META
存储客户端发送上来的所有的header信息
print(request.path) # /login/
print(request.get_full_path()) # /login/?username=%E2%80%9C%E5%B4%94%E6%99%93%E6%98%AD%E2%80%9D
print(request.get_raw_uri()) # http://127.0.0.1:8000/login/?username=%E2%80%9C%E5%B4%94%E6%99%93%E6%98%AD%E2%80%9D
print(request.get_full_path()) # /login/?username=%E2%80%9C%E5%B4%94%E6%99%93%E6%98%AD%E2%80%9D
print(request.get_raw_uri()) # http://127.0.0.1:8000/login/?username=%E2%80%9C%E5%B4%94%E6%99%93%E6%98%AD%E2%80%9D
request.get_full_path()
request.get_raw_uri()
105 【Django视图高级】QueryDict的用法讲解
tags = request.POST.getlist("tags")
不推荐使用
title = request.POST['title']
106【Django视图高级】HttpResponse对象讲解
服务器接收到客户端发送过来的请求后,会将提交上来的这些数据进行封装成一个HttpRequest对象传给视图函数,那么视图函数在处理完成相关的逻辑后,也需要返回一个响应给浏览器,但这个响应必须返回HttpResponseBase或者他的子类的对象
常用属性
1、content
返回的内容
2、status_code
返回的HTTP响应状态码
3、content_type
返回的数据MIME类型,默认为text/html,浏览器会根据这个数据来显示数据,如果是text/plain,那么就会显示一个纯文本,常用的Content-Type
text/html
text/plain
text/javascript
multipart/form-data,文件提交
application/json
application/xml
4、设置请求头
常用方法
set_cookie
用来设置cookie信息
delete_cookie
用来删除cookie信息
write
HttpResponse是一个类似于文件的对象,可以用来写入数据到数据体中
107【Django视图高级】JsonResponse类
跨网络传输data只能使用json格式,使用Python中的json模块
import json
json.loads
json.dumps
Django中封装好了JsonResponse,用来代替以上操作
对json的封装
1、默认情况下JsonResponse只能对字典进行dump,如果想要对非字典的数据进行dump,那么需要给JsonResponse传递一个参数,safe=False
108【Django视图高级】生成和下载csv文件
1、生成csv文件
需求背景:有时候我们做网站的时候,需要将一些数据生成一个csv文件给浏览器,并且作为附件的形式保存下来。
2、生成小的csv文件
109【Django视图高级】大型CSV文件的处理方式
避免超时问题出现
关于StreamingHttpResponse
专门用于处理流数据的,使得处理一些大型文件的时候,不会因为服务器处理时间过长而导致时长超时连接
不是继承自HttpResponse,继承自HttpResponseBase
1、该类没有属性content,相反是streaming_content
2、这个类的streaming_content必须是一个可迭代的对象
3、该类没有write方法,如果给这个类的对象写入数据会报错
StreamingHttpResponse会启动一个进程来和客户端保持长连接,会很消耗资源,不是特殊要求,尽量少用该方法
110【Django视图高级】-类视图
在写视图函数的时候,Django除了使用函数作为视图,也可以使用类作为视图,至于是CBV还是FBV,各有优缺,使用类视图可以使用类的一些特性,比如继承,多态,封装
django.view.generic.base.View
使用类视图写代码比较优雅
def get
def post
url中使用as_view()方法
将类视图当做函数视图
类视图写完后,在url中使用as_view()方法
除了get方法之后,还有如下方法:
def http_method_not_allowed(self, request, *args, **kwargs):
def dispatch(self, request, *args, **kwargs):
print("dispatch")
super(BookDetailView, self).dispatch(request, *args, **kwargs)
print("dispatch")
super(BookDetailView, self).dispatch(request, *args, **kwargs)
111-【Django视图高级】TemplateView详解
from django.views.generic.base import TemplateView
该类视图是用来返回模板的,
使用场景
关于我们的静态页面,比如果壳网的关于我们
如果渲染的这个模板不需要传递任何参数,那么建议在urls中使用TemplateView
在view.py中定义
class AboutView(TemplateView):
template_name = 'about.html'
def get_context_data(self, **kwargs):
context = {"phone": "0731-12345568"}
return context
template_name = 'about.html'
def get_context_data(self, **kwargs):
context = {"phone": "0731-12345568"}
return context
用来继承自TemplateView
技术推动业务
FullStack
销售
全能
112-【Django视图高级】ListView详解
在网站开发中,经常会出现需要列出某个表中的一些数据作为列表展示出来
文章列表
图书列表
Django中使用ListView来帮助我们快速实现这种需求
http://127.0.0.1:8000/article/list/?p=2
def get_context_data
def get_queryset
113-【Django视图高级】Paginator和Page常用属性和方法
Django中的Paginator类和Page类
from django.core.paginator import Paginator, Page
Paginator常用属性
count
num_pages
page_range
Page常用属性和方法
has_next
has_previous
next_page_number
previous_page_number
number
start_index
end_index
114-【Django视图高级】手动实现普通分页效果
基于Bootstrap来配置
So Easy,使用Django来实现网站的快速开发
115-【Django视图高级】手动实现通用分页算法
page_nums
left_page
right_page
left_more
对应...
right_more
对应...
116-【Django视图高级】给类视图添加装饰器
# 定义装饰器
from django.utils.decorators import method_decorator
from django.utils.decorators import method_decorator
直接装饰在整个类上面
@method_decorator(login_required,name='dispatch)
多个装饰器,使用列表给装饰起来
117-【Django视图高级】状态码错误处理
在网站开发过程中,经常会捕获一些错误,然后将这些错误返回比较优美的页面,或者是将这个错误的请求做一些日志保存
常见的错误码
400
403
404
405
500
502
坏的网关,比如应用服务器如tomcat未启动
自定义错误模板
404.html
必须叫做404.html
500.html
必须叫做500.html
在templates模板中进行定义
其他Django App下方有自己的templates目录
错误处理的解决方案
对于404和500这种自动抛出的错误,可以直接在templates文件夹下新建相应的错误代码的模板文件,对于其他的错误,可以专门定义一个app,用于处理这种错误
章节06-Django表单
118-Django中表单的使用方式
HTML中的表单
form标签
发送给指定的URL
method=POST
name标签一定要给,用来让后端获取属性
不管后端是什么开发语言,表单都是一致的
登录和注册的输入框,都是表单
Django中的表单
通过表单实现验证
作用
1、渲染HTML标签
如果前后端分离开发,在前端进行验证
不建议在Django中进行使用,局限性较大,对于代码管理不方便
2、表单验证数据是否合法
用的最多
Django中的表单使用流程
必须继承自django.forms.Form
类似Django中的model
Django中的表单进行数据验证,是非常好用的
流程
1、定义forms.py文件,并在其中定义一个表单类
2、视图函数中进行调用
渲染
form.as_table
form.as_p
as_ul
验证成功后,使用cleand_data来获取数据
前端进行了表单验证后,后端还需要吗?
后端是最后一道防线,所以需要添加表单验证
postman进行接口测试时候,不需要使用前端页面
通过接口传输数据的时候,也不需要访问前端页面
写爬虫的方式,通过脚本的方式提交
119【Django表单】用表单验证数据是否合法
用表单验证数据
常用的Field
CharField
min_length
max_length
required
是否必须传入
error_messages
EmailField
继承自CharField
FloatField
max_value
min_value
IntergerField
max_value
min_value
常用验证器
MaxValueValidator
MinValueValidator
MinLengthValidator
MaxLengthValidator
EmailValidator
URLValidator
RegexValidator
使用Django表单的真正姿势
前端写表单
Django表单来做数据验证
120 【Django表单】表单中常用的验证器
验证最大值
验证最小值
验证最大长度
验证最小长度
验证是否是邮箱格式
验证是否是URL格式
正则格式验证
章节07-Memcached缓存系统
128-【memcached】memcached介绍
memcached的数据存储会更加高效
memcached相当于内存的缓存系统
速度会更加快
memcached介绍
LiveJournal
维基百科,自由的百科全书
最早是为LiveJournal服务的,为了加速LiveJournal访问速度而开发的,后被很多大型项目所使用
www.danga.com
www.memcached.org
高性能的分布式内存对象缓存系统,减少数据库负载的压力
memcached是通过在内存里维护一个统一的巨大的hash表
memcached可以存储各种各样藏的数据
图像
视频
文件
数据库检索结果
原理:将数据调用到内存中,从内存中读取,从而大幅提高读取速度
memcached的使用场景
存储验证码
图形验证码
短信验证码
登录session等不是至关重要的数据
129-【memcached的安装和参数详解】
Windows安装
memcached.exe安装
拷贝x.dll文件到C:\windows\system32
本地上安装memcahed是为了方便在本地开发使用
Ubuntu安装
ECS初始化之后
apt-get update
apt-get install memcached
systemctl start memcached
memcached的一些参数
-d
让memcache在后台运行
-m
指定占用内存大小
-p
指定占用的端口
-l
指定IP地址
默认端口号是
11211
一个程序占用一个端口号
以上参数不能通过systemctl的方式来管理
/usr/bin/memcached -p11211 -u memcache -d start
telnet连接memcached
telnet 127.0.0.1 11211
set username 0 120 7
130-【memcached】telnet操作memcached
1、登录语法
telnet 127.0.0.1 11211
2、set
存在则替换
不存在则添加
set username 0[是否需要压缩] 60[过期时间] 7[字符的长度]
输入被存储的值
获取值
get username
3、add
存在则添加失败
不存在则添加成功
4、delete
delete username
5、flush_all
删除memecached中所有的数据都清理掉,谨慎使用
6、incr
给一个数字类型进行相加一个值
数据类型只能是数字
7、decr
想减
数据类型是数字
8、stats
查看memcached的命中概率
stats
STAT pid 3503
STAT uptime 1760
STAT time 1552208557
STAT version 1.4.25 Ubuntu
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.024000
STAT rusage_system 0.052000
STAT curr_connections 1
STAT total_connections 3
STAT connection_structures 2
STAT reserved_fds 20
STAT cmd_get 9
STAT cmd_set 8
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 8
STAT get_misses 1
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 1
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 594
STAT bytes_written 681
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 70
STAT curr_items 1
STAT total_items 7
STAT expired_unfetched 1
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 4
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
END
STAT pid 3503
STAT uptime 1760
STAT time 1552208557
STAT version 1.4.25 Ubuntu
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.024000
STAT rusage_system 0.052000
STAT curr_connections 1
STAT total_connections 3
STAT connection_structures 2
STAT reserved_fds 20
STAT cmd_get 9
STAT cmd_set 8
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 8
STAT get_misses 1
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 1
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 594
STAT bytes_written 681
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 70
STAT curr_items 1
STAT total_items 7
STAT expired_unfetched 1
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 4
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
END
命中概率特别低的时候
查看是否垃圾数据多
131-【memcached】Python操作memcached
代码中操作memcached
pip install python-memcached
修改/etc/memcache.conf
将127.0.0.1 改为0.0.0.0
创建连接对象
mc = memcache.Client(['47.94.211.18:11211'], debug=True)
mc.set('username', 'Hello World', time=120)
mc.set('username', 'Hello World', time=120)
一次性设置多个值
set_multi
分布式的概念
分布式存储热数据
多个容器存储
在列表中存储多个IP地址
132-【memcached】memcached的安全机制
133-【memcahed】在Django中使用memcached
章节08-Cookie和Session
134 【Cookie和Session】cookie的工作机制
http请求无状态
初次访问百度服务器
再次访问百度服务器
记录cookie值
IP地址不够用,公网IP地址紧缺
IPv4
IPv6
浏览器自动保存百度返回的cookie信息
cookie存储量有限,一般是4kb
网易服务器的cookie不会发送到百度服务器
这是肯定的啦,常识
135【Cookie和Session】在django中操作cookie
【Cookie和Session】在django中操作cookie
设置cookie
通过response.set_cookie来实现
key
value
max_age
expires
过期时间
通过浏览器可以查看cookie值
path
domain
secure
httponly
False
True
IE浏览器不支持expires
获取cookie
通过request.COOKIES来获取
删除cookie
delete_cookie方法来删除
136 【Cookie和Session】Session的概念和机制
网站开发人员提出的概念而已
如何实现由开发者决定
不是一个真正的解决方案,只是一个思路
每个互联网公司处理方式不一致
基于Cookie来实现session
存储在服务端
sessionid
session存储在服务器,返回一个sessionid用来进行数据交换
数据
过期时间
可以将session数据存储在cookie中
为什么要使用session?
1、安全
2、快速
session存储在服务端还是cookid中的优缺点
137 【Cookie和Session】在Django中操作session
Django中的session默认情况下是存储在服务器的数据库中,在表中会根据sessionid来提取指定的session数据
get
pop
keys
items
clear
flush
set_expiry
None
clear_expired
python manage.py clearsessions来清除过期的session
138 【Cookie和Session】更改Session的存储机制
默认情况下,session数据是存储在数据库中的,当用户量大的时候,过多的请求会影响MySQL数据库的查询性能,影响用户体验
可以将session存储到其他地方
Django中设计了6种处理方案
可以通过设置SESSION_ENGINE来更改session的存储位置
django.contrib.sessions.backends.db
使用数据库,默认就是这种方案
django.contrib.sessions.backends.file
使用文件来存储session
django.contrib.sessions.backends.cache
使用缓存来存储session,前提是必须要在settings.py中配置好CACHES配置项,而且是需要使用Memcached,而不能使用纯内存作为缓存
django.contrib.sessions.backends.cached_db
在存储数据的时候,先将数据存储到缓存中,然后再存储到数据库中
万一环境系统出问题,session数据不会丢失
在读取的时候,先从缓存中读取,如果缓存中没有,再从数据库中读取
django.contrib.sessions.backends.signed_cookies
将session信息加密后存储到浏览器的cookie中,这种方式要注意安全,建议设置SESSION_COOKIE_HTTPONLY=True,那么在浏览器中不能通过js来操作session数据,并且还需要对settings.py中的SECRET_KEY进行加密,因为一旦被人获取到这个SECRET_KEY的值,就可以进行解密,在cookie中,存储的数据不能超过4k
Django settings.py中的配置
# SESSION_COOKIE_AGE
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
章节09-上下文处理器和中间件
139 【上下文处理器】用户系统案例
子主题
章节10-安全
章节11-验证和授权
160【验证和授权】验证和授权系统概述
Django内置授权系统,处理用户、分组、权限以及基于cookie的会话系统
用户
权限
分组
一个可以配置的密码哈希系统
一个可拔插的后台管理系统
Admin
授权
验证
使用授权系统
django.contrib.auth
核心授权框架,大部分的模型定义
django.contrib.contenttypes
Content Type系统,可以用来关联模型和权限
中间件
SessionMiddleware
用来管理session
AuthenticationMiddleware
用来处理和当前session相关联的用户
161【验证和授权】内置User模型的基本使用
学会看源码
User模型的基本用法
继承关系讲解
创建用户
创建超级用户
修改密码
登录验证
authenticate方法进行验证
162 【验证和授权】扩展User模型-使用Proxy模型
1、设置proxy模型
?: (models.E017) Proxy model 'Person' contains model fields.
代理不能定义任何字段
User.objects.all
Person.objects.all
不会对User模型产生任何的影响
3、AbstractUser
4、AbstractBaseUser
163【验证和授权】扩展User模型-一对一方式扩展
一对一外键方式来拓展
一对一表关系
Django中的信号初识
推荐大家使用“一对一”进行拓展
自定义my_authenticate
164 【验证和授权】扩展User模型-继承AbstractUser
局限性
必须在第一次数据库迁移的时候,进行映射
165 【验证和授权】扩展User模型-继承AbstractBaseUser
完完全全实现自己的一套User模型
自定义User模型,必须在第一次执行的时候,就定义好
166 【验证和授权】登录、退出登录以及登录限制案例
login
logout
login_requeired
限制用户登录装饰器函数
167 【验证和授权】权限-添加权限的两种方式
auth_permission
django_content_type
手工添加权限
通过代码的方式添加权限
168 【验证和授权】权限-用户和权限相关操作
一次性添加多个权限
一次性清除多个权限
一个个添加权限
具体的方法
set
add
remove
clear
get_all_permissons
has_permisson
判断用户是否拥有权限
权限限定装饰器
from django.contrib.auth.decorators import permission_required
169 【验证和授权】权限-权限验证装饰器
permission_required装饰器
from django.contrib.auth.decorators import login_required, permission_required
is_authenticated,判断用户是否登录
170 【验证和授权】权限-Group、Permission、User的操作
Group.objects.
基于角色的权限控制RBAC
分组操作
Group.objects.create(group_name)
group.permissions
group.permissions.add
group.permissions.remove
group.permissions.clear
user.get_group_permissions()
171 【验证和授权】补充-在模板中添加权限控制
get
pop
在模板中使用权限
settings.TEMPLATES.OPTIONS.context_processors下
'django.contrib.auth.context_processors.auth',
172-【Redis】Redis的概述和使用场景介绍
Redis概述
NoSQL数据库
可定时将数据保存到硬盘
支持持久化
支持更多的数据结构
Redis的使用场景
1、登录会话存储
2、排行榜/计数器
主播排名
新浪微博的点赞数
3、作为消息队列
celery就是使用redis作为中间人
4、当前在线人数
例如QQ在线人数
5、常用数据缓存
BBS论坛版块
6、把前面200篇文章缓存或者评论缓存
7、好友关系
微博好友关系
8、发布和订阅功能
不是很多
Redis和Memcached的比较
Redis
Memcached
数据类型
虚拟内存
过期策略
存储数据安全
灾难恢复
分布式
订阅与发布
Redis在Ubuntu系统中的安装和启动
sudo apt-get install redis
173 【Redis】Redis的安装及客户端连接
1、更新安装源
sudo apt-get update
2、安装Redis
sudo apt-get install redis-server
174 【Redis】Redis的字符串以及过期时间操作
set username cuixiaozhao
get username
keys *
set username cxz EX 10
ttl username
expire username 20
176 【Redis】Redis列表操作
lpush
rpush
lrange
lpop
rpop
lrem
177【Redis】Redis集合操作
集合set的概念
章节12-Redis键值对数据库
章节13-项目实战
243【后端开发】后端开发准备工作
1、配置好数据库MySQL
使用大写XFZ
NAME
USER
PASSWORD
HOST
PORT
2、配置好模板路径
'DIRS': [os.path.join(BASE_DIR, 'front', 'templates')]
3、配置好静态文件的路径
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'front', 'dist')
]
os.path.join(BASE_DIR, 'front', 'dist')
]
4、配置好时区
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True
5、配置模板的static查找
# from django.templatetags import static,在template 中不用每次在{% load static %}
'builtins': [
'django.templatetags.static'
'builtins': [
'django.templatetags.static'
mark as templates/SourceRoot
244【后端开发】AdminLTE框架的集成以及前端登录页面的实现
公司运营人员做“轮播图的推广”
需要CMS后台管理系统,不再使用Django自带的admin,而是使用AdminLTE
AdminLTE前端框架的下载及使用
AdminLTE-2.4.5
可以下载源码
login.html模板页面的开发
使用AdminLTE=2.4.5的examples下的login.html进行修改开发
静态资源的引用使用{% static 'xxx' %}
在settings.py中配置了builtins
创建Django APP ——CMS并进行注册
系统登录页面开发
245【后端开发】User模型创建
关于用户系统
使用Django内置的User系统,简直大强大了,没理由不使用它!!!
需要重新定制
比如firstname、lastname
前、后台使用同一个User系统
同一张表和同一个用户
比如拥有登录后台系统的权限
最好的用户体验,使用同一套用户登录系统,实现用户登录
PS:使用两套系统,安全性高一些,缺点是的登录繁琐
自定义User模型
创建一个xfzauth的app,用来管理用户系统
# 我们不使用默认的自增长的主键;id——101,102,103等等,我们使用UUID——全球唯一的值,但是字符太长,So使用ShortUUID;
使用第三方包-pip install django-shortuuidfield
from shortuuidfield import ShortUUIDField
全部重写,继承来自AbstractBaseUser
自定义UserManager
设置AUTH_USER_MODEL
映射到数据库中
makemigrations
migrate
246【后端开发】登录功能实现1
1、因为共用一个账号,只要一个登录界面就可以了
CMS的登录界面目前为止完全是为了测试,后期全部使用之前写好的登录界面
2、因为登录界面是一个模态框,所有应该走ajax请求
因此登录的视图函数应该使用json进行交互
3、把所有的登录逻辑都写在xfzauth这个app的试图函数中
247 【后端开发】登录功能实现(2)
返回Json格式数据
创建的user对象,一定要保存,执行save()方法
248 重构RestfulAPI的实现
新增工具包目录-utils
restful.py的使用!
将重复代码抽取出来,然后再去调用!
249【后端开发】将静态页面改造成Django模板(1)
extends和include并存使用,依据使用场景来用
引用的好处就是,一处发生变化,引用的位置均同时发生变化,无需处处修改!
250 【后端开发】将静态页面改造成Django模板(2)
254 【后端开发】登录状态更改和退出登录
context_processors
273 【后端开发】UEditor富文本编辑器的集成
富文本编辑器
经典、古老好用的富文本编辑器
百度官方出品
百度贴吧
百度其他产品
UEditor官方不支持Python
311-购买课程-配置pycharm同步代码到服务器
PyCharm建立远程SSH连接
Exclude去除文件
自动上传文件
Ctrl+S
章节14-Django项目部署
子主题
328-【部署】开发机上的准备工作
使用Ubuntu16.04LTS服务器(阿里云ECS)
1、确认项目没有Bug;
2、使用pip生成requirements.txt文件,pip freeze >requirements.txt;
3、将dysms_python准备好,因为短信验证码的包必须通过测试;
4、将项目上传到这个目录下
使用Git进行版本管理
git --version
安装Git
搭建私有Git服务器
git init
初始化为Git仓库
git remote add origin https://gitee.com/cuixiaozhao/CUSTOMRE.git
git add .
git commit -m "注册登录功能的开发"
.gitignore文件配置
front/node_modules
front/src
whoosh_index/
front/src
whoosh_index/
Git pull origin master --allow-unrelated-histories
pull和push之前,输入用户名和密码
git push origin master
工作区——>缓存区——>仓库
Python项目不用打包发布?
Tomcat项目打成war包,然后启动的时候进行解压缩
329-【服务器上安装vim、mysql、memcached等】
1、切换成root用户
su - root
2、安装openssh-server openssh-client
sudo apt install openssh-server openssh-client
可使用ssh工具进行连接
3、更改apt源
vim /etc/apt/sources.list
xxx
xxx
更改前先备份,养成好习惯
cp -a /etc/sourse.list{,.ori}
4、安装vim和mysql
apt get install -y vim
apt get install mysql-server mysql-client
5、登录和查看mysql数据库
root@iZ2ze776rnzxhq6p432hn5Z:~# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.25-0ubuntu0.16.04.2 (Ubuntu)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> quit;
Bye
root@iZ2ze776rnzxhq6p432hn5Z:~#
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.25-0ubuntu0.16.04.2 (Ubuntu)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> quit;
Bye
root@iZ2ze776rnzxhq6p432hn5Z:~#
6、安装memcached
sudo apt-get install -y memcached
memcached的端口号为11211
测试memcahed是否可用
telnet 127.0.0.1 11211
root@iZ2ze776rnzxhq6p432hn5Z:~# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
ERROR
ERROR
ERROR
ERROR
set username 0 60 7
zhiliao
CLIENT_ERROR bad data chunk
ERROR
set username 0 60 7
zhiliao
STORED
get username
VALUE username 0 7
zhiliao
END
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
ERROR
ERROR
ERROR
ERROR
set username 0 60 7
zhiliao
CLIENT_ERROR bad data chunk
ERROR
set username 0 60 7
zhiliao
STORED
get username
VALUE username 0 7
zhiliao
END
set
get
330-【部署】服务器上安装Python环境、git、虚拟环境等
1、安装python
Ubuntu16升级Python3.5至3.6
https://blog.csdn.net/gangzhucoll/article/details/81294236
2、报错信息处理处理
root@iZ2ze776rnzxhq6p432hn5Z:~# pip3 install --upgrade pip
python3: can't open file 'install': [Errno 2] No such file or directory
root@iZ2ze776rnzxhq6p432hn5Z:~# pip3 install --upgrade pip
Traceback (most recent call last):
File "/usr/bin/pip3", line 9, in <module>
from pip import main
ImportError: cannot import name 'main'
root@iZ2ze776rnzxhq6p432hn5Z:~#
python3: can't open file 'install': [Errno 2] No such file or directory
root@iZ2ze776rnzxhq6p432hn5Z:~# pip3 install --upgrade pip
Traceback (most recent call last):
File "/usr/bin/pip3", line 9, in <module>
from pip import main
ImportError: cannot import name 'main'
root@iZ2ze776rnzxhq6p432hn5Z:~#
Bug处理
修改 /usr/bin/pip3
root@iZ2ze776rnzxhq6p432hn5Z:~# cat /usr/bin/pip3
#!/usr/bin/python3
# GENERATED BY DEBIAN
import sys
# Run the main entry point, similarly to how setuptools does it, but because
# we didn't install the actual entry point from setup.py, don't use the
# pkg_resources API.
from pip import __main__
if __name__ == '__main__':
sys.exit(__main__._main())
root@iZ2ze776rnzxhq6p432hn5Z:~#
#!/usr/bin/python3
# GENERATED BY DEBIAN
import sys
# Run the main entry point, similarly to how setuptools does it, but because
# we didn't install the actual entry point from setup.py, don't use the
# pkg_resources API.
from pip import __main__
if __name__ == '__main__':
sys.exit(__main__._main())
root@iZ2ze776rnzxhq6p432hn5Z:~#
3、supervisor不支持python3,需要安装pip2
apt install python2
apt install python2-pip
4、安装virtualenvwrapper
root@iZ2ze776rnzxhq6p432hn5Z:~# pip install virtualenvwrapper
使用pip2进行安装
配置环境变量
root@iZ2ze776rnzxhq6p432hn5Z:~# vim .bashrc
root@iZ2ze776rnzxhq6p432hn5Z:~# source .bashrc
virtualenvwrapper.user_scripts creating /root/.virtualenvs/premkproject
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postmkproject
virtualenvwrapper.user_scripts creating /root/.virtualenvs/initialize
virtualenvwrapper.user_scripts creating /root/.virtualenvs/premkvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postmkvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/prermvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postrmvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/predeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postdeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/preactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/get_env_details
root@iZ2ze776rnzxhq6p432hn5Z:~#
root@iZ2ze776rnzxhq6p432hn5Z:~# source .bashrc
virtualenvwrapper.user_scripts creating /root/.virtualenvs/premkproject
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postmkproject
virtualenvwrapper.user_scripts creating /root/.virtualenvs/initialize
virtualenvwrapper.user_scripts creating /root/.virtualenvs/premkvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postmkvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/prermvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postrmvirtualenv
virtualenvwrapper.user_scripts creating /root/.virtualenvs/predeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postdeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/preactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/postactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/get_env_details
root@iZ2ze776rnzxhq6p432hn5Z:~#
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
source /usr/local/bin/virtualenvwrapper.sh
创建虚拟环境,指定Python版本
root@iZ2ze776rnzxhq6p432hn5Z:~# mkvirtualenv --python=/usr/bin/python3 XFZ-venv
Running virtualenv with interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /root/.virtualenvs/XFZ-venv/bin/python3
Also creating executable in /root/.virtualenvs/XFZ-venv/bin/python
Please make sure you remove any previous custom paths from your /root/.pydistutils.cfg file.
Installing setuptools, pip, wheel...
done.
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/predeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/postdeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/preactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/postactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/get_env_details
(XFZ-venv) root@iZ2ze776rnzxhq6p432hn5Z:~#
Running virtualenv with interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /root/.virtualenvs/XFZ-venv/bin/python3
Also creating executable in /root/.virtualenvs/XFZ-venv/bin/python
Please make sure you remove any previous custom paths from your /root/.pydistutils.cfg file.
Installing setuptools, pip, wheel...
done.
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/predeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/postdeactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/preactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/postactivate
virtualenvwrapper.user_scripts creating /root/.virtualenvs/XFZ-venv/bin/get_env_details
(XFZ-venv) root@iZ2ze776rnzxhq6p432hn5Z:~#
代码拉取
git remote add origin https://gitee.com/cuixiaozhao/XFZ
git pull origin master
331-【部署】生产环境Django项目配置
开发机
Git服务器
业务服务器(只是一时爽,以后就遭殃了)
Django的运行
pip install -r requirements.txt
安装过程中的报错处理——apt install libmysqld-dev
1、数据库的迁移
ImportError: cannot import name 'connections'的错误解决办法——先卸载,再安装
pip uninstall haystack django-haystack
pip install haystack django-haystack
python manage.py makemigrations
python manage.py migrate
2、settings.py中配合STATIC_ROOT目录并指定static_dist
python manage.py collectstatic使用命令进行静态文件的搜集
玩转Django2.0中也建议这么使用!
3、python manage.py runserver 0.0.0.0:8000
使用0代替0.0.0.0
4、域名和IP地址的配置
5、DEBUG的设置,改为False
6、git提交代码,git拉取代码;
进制远程调试!
7、为了将所有静态文件都收集起来,便于Nginx处理
static_dist
python manage.py collectstatic
可能会出现静态文件丢失的情况,后续设置,已解决该问题
332-【部署】用uwsgi部署Django项目
uwsgi是一个应用服务器!
高性能应用服务器,类似于Tomcat、Jboss、Jetty
非静态文件的网络请求必须通过他完成
uwsgi是通过python进行编写的,使用pip3 install uwsgi即可
uwsgi必须安装在系统级别中,不能安装到虚拟环境中
创建一个uwsgi.ini的文件
CUSTOMER.ini
使用项目名进行命名,规范化开发!
TTS.ini
启动运行uwsgi服务器
uwsgi --ini uwsgi.ini
被supervisor所启动
apt-get install python3.6-dev解决报错问题
pip3 install uwsgi
配置项
chdir
module
master
home
process
333-【部署】用nginx+uwsgi部署项目
uwsgi对静态文件资源处理并不好,包括响应速度,缓存等,Nginx是专业的Web服务器;
Apache
Nginx
IIS
2、Nginx作为专业的Web服务器,暴露在公网上会比uwsgi更加安全一些
可以做很多的操作
比如端口转发
虚拟主机
重定向处理
伪静态处理
防盗链处理
用户访问控制
3、运维起来更加方便,比如要将某些IP写入黑名单,Nginx可以非常方便的写进去,而uwsgi要写一大段代码
apt get install nginx
启动:service nginx start
关闭:service nginx stop
重启:service nginx restart
重载:service nginx reload
测试配置文件:service nginx configtest
4、添加配置文件
vim xfz.conf
子主题
5、启动Nginx,启动uwsgi
默认自带80端口
Nginx读取到了静态文件,所以样式正常出现
334-【部署】用supervisor管理uwsgi进程
注意uwsgi不是以守护进程存在的,所以需要使用进程管理器supervisor来管理
uwsgi不是以守护进程运行,容易发生意外,supervisor是用来管理uwsgi的
pip2 install uwsgi
自定义supervisor.conf文件
autorestart
supervisorctl是客户端
supervisord是服务器
通信
supervisord来管理uwsgi进程
supervisorctl操作uwsgi
收藏
0 条评论
下一页