新乡网站建设哪家好,做网站的怎样找客户,门头沟手机网站建设,用照片做视频的模板下载网站好在上一章#xff0c;为其他程序与我们的Web应用交互创建了RESTful API。本章将学习如何创建生产环境让我们的网站正式上线#xff0c;主要内容有#xff1a;配置生产环境创建自定义中间件实现自定义管理命令1创建生产环境现在该将Django项目正式部署到生产环境中了。我们将按…在上一章为其他程序与我们的Web应用交互创建了RESTful API。本章将学习如何创建生产环境让我们的网站正式上线主要内容有配置生产环境创建自定义中间件实现自定义管理命令1创建生产环境现在该将Django项目正式部署到生产环境中了。我们将按照下列步骤将站点部署到生产环境中为生产环境配置项目设置使用PostgreSQL数据库使用uWSGI和NGINX建立web服务器管理静态资源使用SSL加强站点安全管理1.1管理用于多个环境的配置在实际的项目中很可能要面对不同的环境。一般至少有一个本地开发环境和一个生产环境也可能有其他环境比如测试环境预上线环境等。对于不同的环境有些设置是通用的有些则因环境而异。让我们将项目设置为可以适合不同环境又可以保证项目结构不会被改变。在educa/educa/目录下建立settings目录包与settings.py同级将settings.py文件重命名为base.py然后移动到settings目录中来再创建其他文件setting/目录如下所示Copysettings/__init__.pybase.pylocal.pypro.py这些文件用途如下base.py基本的设置文件包含通用的设置是原来的settings.pylocal.py本地环境的自定义设置pro.py生产环境的自定义设置编辑settings/base.py找到下列这行CopyBASE_DIR os.path.dirname(os.path.dirname(os.path.abspath(__file__)))将其替换成下边这行CopyBASE_DIR
os.path.dirname(os.path.dirname(os.path.abspath(os.path.join(__file__, os.pardir))))由于我们将settings.py文件又往下级目录放了一级必须让BASE_DIR指向正确的路径所以使用了os.pardir指向父目录来让最后的路径依然是原来的项目根目录。编辑settings/local.py添加下列代码Copyfrom .base import *DEBUG True
DATABASES {default: {ENGINE: django.db.backends.sqlite3,NAME: os.path.join(BASE_DIR, db.sqlite3),}
}
这是代表我们本地环境的配置文件。在其中导入了所有base.py中的设置内容然后写了DEBUG和DATABASES两个设置这两个设置会覆盖原来base.py中的设置成为本文件中的设置。由于DEBUG设置和DATABASES设置在每个配置文件中都会修改也可以将这两个设置从base.py中删除。再来编辑settings/pro.py如下所示Copyfrom .base import *DEBUG False
ADMINS ((Antonio M, emailmydomain.com),
)
ALLOWED_HOSTS [*]
DATABASES {default: {}
}这是生产环境的配置文件来详细看一下其中的内容DEBUG设置DEBUG为False是生产环境的强制要求。如果不关闭会将错误跟踪和敏感配置信息泄露给所有人。ADMINS当DEBUG设置为False的时候如果一个视图抛出异常所有信息会以邮件形式发送到ADMINS配置中列出的所有人。需要将其中的信息改成自己的名字和邮箱还需要配置SMTP服务器。ALLOWED_HOSTSDjango只会向这个设置中的地址或者主机名称提供Web服务。这是一个安全手段。我们使用了通配符*表示可以用于所有主机名称或者IP地址。在稍后的配置中会更详细的作出限制。DATABASES生产环境的数据库设置现在留空后边会进行该设置。由于生产环境的数据库和非生产环境的数据库一般是隔离的甚至生产环境数据库只有处于生产环境才能访问。所以该项需要单独配置。在需要面对多种环境时建立一个基础配置文件并为每种环境编写单独的配置文件。用于具体环境的配置文件继承基础配置并重写与环境相关的配置即可。由于我们现在没有把配置文件放在原来settings.py所在的位置所以无法运行manage.py必须为其指定settings模块的所在路径即使用--settings参数或者设置环境变量DJANGO_SETTINGS_MODULE。打开系统命令行窗口输入Copyexport DJANGO_SETTINGS_MODULEeduca.settings.pro这条命令会为当前的会话窗口设置DJANGO_SETTINGS_MODULE环境变量。如果不想每次运行shell都执行一遍可以把这条命令加入到shell配置文件如.bashrc或者.bash_profile中。如果不想对系统进行任何设置那么在启动站点的时候必须加上--settings参数如下Copypython manage.py migrate --settingseduca.settings.pro现在我们就为多环境做好了基础设置。1.2使用PostgreSQL数据库在整本书中我们大部分都使用了Python自带的SQLite数据库只要在博客全文检索的时候推荐使用了PostgreSQL数据库。SQLite轻量而且易于使用但对于生产环境而言太过简陋必须需要一个更强力的数据库比如PostgreSQL和MySQL或者Oracle。PostgreSQL的安装在第三章中已经介绍过不再赘述。让我们为我们的应用创建一个PostgreSQL用户打开系统命令行输入如下命令Copysu postgres
createuser -dP educa系统会提示输入用户密码和权限。输入密码并且给予用户权限然后使用下列命令建立一个新的数据库Copycreatedb -E utf8 -U educa educa这样就建立好了一个新的数据库并且将其分配给educa用户之后编辑settings/pro.py修改数据库的设置如下CopyDATABASES {default: {ENGINE: django.db.backends.postgresql,NAME: educa,USER: educa,PASSWORD: ,}
}将密码部分替换成为educa用户设置的密码。由于新数据库是空的运行Copypython manage.py migrate然后创建一个超级用户Copypython manage.py createsuperuser译者注安装PostgreSQL远没有这么简单尤其是通过第三方程序远程管理PostgreSQL需要修改PostgreSQL的配置文件将认证方式修改为md5或者trust然后启用允许访问的IP建议查看官方文档和各种安装教程进行配置。1.3部署前检查Django提供了一个check命令可以在任何时候检查项目。通常检查过程包括检查所有注册的应用输出所有错误和警告信息。如果包含--deploy参数还会额外执行针对生产环境的检查。打开系统终端然后输入如下命令进行检查Copypython manage.py check --deploy译者注作者这里遗漏了配置文件的路径应该写成python manage.py check --deploy --settingseduca.settings.*其中*为baselocal或pro如果站点编写正确的话会看到没有错误输出但是会有一些警告信息。这说明站点通过了检查但这些警告信息应该得到处理以让站点更加安全。本书不会深入这里的内容但是要记得在正式部署之前一定要进行部署前检查。1.4通过WSGI程序提供Django服务Django的主要部署平台就是WSGIWSGI是Web Server Gateway Interface的简称是基于Python的程序提供Web服务的标准格式。由于Django也是Python程序也需要通过WSGI对外提供服务。当通过startproject命令新建一个项目的时候Django会在项目目录内新建一个wsgi.py。这个文件包含了一个WSGI可调用函数为我们的Django应用提供了一个接口。无论是我们之前采用本机8000端口的开发服务器还是正式生产环境都需要通过这个接口。关于WSGI的详细知识可以看https://wsgi.readthedocs.io/en/latest/及Python的PEP333。1.5安装WSGI直到本节之前我们的所有开发都是在django在本地环境运行的开发服务器上进行的。在生产环境中需要一个真正的web服务器才能部署django服务。uWSGI是一个非常快的Python应用程序WSGI服务器使用WSGI标准与Python应用进行通信。uWSGI把HTTP请求翻译成Django程序能够处理的格式。安装uSWGICopypip install uwsgi2.0.17在pip安装之后会built uWSGI编译安装需要一个C编译器比如GCC或者clang在linux环境下可以输入命令apt-get install build-essential。如果是MacOS X可以通过Homebrew安装执行命令brew install uwsgi。如果在windows下安装需要Cygwin https://www.cygwin.com。推荐在基于UNIX的操作系统上安装uWSGI。UNIX环境下如果看到Successfully built uwsgi就说明成功安装了uWSGI。关于uWSGI的文档可以在https://uwsgi-docs.readthedocs.io/en/latest/找到。1.6配置uWSGI可以通过命令行配置uWSGI打开系统命令行模式进入educa项目的根目录然后输入Copysudo uwsgi --moduleeduca.wsgi:application --envDJANGO_SETTINGS_MODULEeduca.settings.pro --master --pidfile/tmp/project-master.pid --http127.0.0.1:8000 --uid1000 --virtualenv/home/env/educa/必须需要su权限才可以。通过这条命令为本机上的uWSGI设置了如下的内容使用educa.wsgi:application作为调用接口载入生产环境的设置文件使用virtualenv设置的虚拟环境注意将/home/env/educa/替换为实际的虚拟环境所在路径。如果未使用虚拟环境该配置可以不填。如果不是在项目目录内执行的上述命令需要额外加一个参数指定具体的项目目录--chdir/path/to/educa/将其中的/path/to/educa/替换成educa的项目路径。通过浏览器访问http://127.0.0.1:8000/无需启动django服务可以看到站点内容显示了出来但没有任何CSS样式也无法显示图片这是因为还没有配置uWSGI来提供静态文件服务。uWSGI允许使用一个.ini配置文件进行自定义配置比使用命令行要方便很多。在educa项目根目录下建立Copyconfig/uwsgi.ini编辑uwsgi.ini添加如下代码Copy[uwsgi]# variablesprojectname educa
base /home/projects/educa# configurationmaster truevirtualenv /home/env/%(projectname)
pythonpath %(base)
chdir %(base)
env DJANGO_SETTINGS_MODULE%(projectname).settings.pro
module educa.wsgi:application
socket /tmp/%(projectname).sock在这个.ini文件里我们定义了两个变量projectnameDjango项目的名称是educabaseeduca项目的绝对路径将其替换成实际项目路径上边定义的这两个变量是自定义变量还可以定义任意其他变量只要不和内置的名称冲突。接下来是具体设置的解释master表示启用主进程virtualenv虚拟环境地址将其替换成实际的路径所在不包含bin/activate)pythonpath加入到Python PATH中的地址一般就是项目的根目录chdir项目的实际地址uWSGI会在加载应用之前将工作目录变更到这个路径env环境变量设置为DJANGO_SETTINGS_MODULE具体路径指向生产环境的配置文件module要使用的WSGI模块指向项目中的wsgi.py中的调用函数。application是该函数在项目中默认的命名。socket绑定该服务的套接字。是一个文件套接字用于与NGINX通信其中的socket套接字是用于和第三方路由软件进行通信比如NGINX。命令行模式中我们使用的--http 127.0.0.1:8000指的是让uWSGI自己接受HTTP请求并自己负责路由这些请求。我们需要把uWSGI作为socket启动在.ini文件设置中并没有设置--http参数因为我们要使用NGINX作为我们的web服务器NGINX通过刚才设置的文件套接字与uWSGI进行通信。关于uWSGI的详细设置可以看 https://uwsgi-docs.readthedocs.io/en/latest/Options.html。现在可以通过使用配置文件来启动uWSGI先关闭原来运行的uWSGI服务Copyuwsgi --ini config/uwsgi.ini这样运行之后可以发现暂时无法通过浏览器访问http://127.0.0.1:8000/因为此时uWSGI监听文件套接字而不是HTTP端口我们还需要继续完善生产环境配置。1.7配置uWSGI当启动一个Web服务的时候很显然必须提供动态的内容服务但也需要静态的文件服务比如CSSJavaScript文件图像等。如果用uWSGI来管理静态文件会为HTTP请求增加不必要的开销所以最好在uWSGI之前加一个Web服务比如NGINX。NGINX是一个高并发低内存占用的Web服务端也具有反向代理功能即接受一个HTTP请求然后把这个请求路由给不同的后端。通常来说你需要一个web服务端如NGINX用于快速高效的提供静态文件然后把动态的请求转发给uWSGI。通过使用NGINX还可以设置其反向代理功能从而更好的提供web服务。安装NGINX可以使用下列命令Copysudo apt-get install nginx如果使用MacOS X可以通过brew install nginx来安装。Windows下的NGINX可以通过https://nginx.org/en/download.html下载。译者注安装NGINX后不会立刻启动译者使用的Centos 7.5 1804还需要启动NGINX服务和开机启动Copysystemctl start nginx.service
systemctl enable nginx.service正常情况下在启动NGINX之后直接访问本机IP地址可以看到NGINX欢迎页面表示基础配置成功运行之后可以先停用NGINX服务以配置生产环境。1.8生产环境下面的图表示了我们最终配置的生产环境的结构当一个浏览器发起一个HTTP请求的时候发生如下事情NGINX接收HTTP请求如果请求静态文件NGINX直接提供服务。如果请求动态页面NGINX通过SOCKET与uWSGI通信将请求转交给uWSGI处理uWSGI将请求转交给Django后端进行处理返回的响应被传递给NGINXNGINX再发回给浏览器。1.9配置NGINX在config/目录下创建nginx.conf文件在其中添加如下代码Copy# the upstream component nginx needs to connect to
upstream educa {server unix:///tmp/educa.sock;
}
server {listen80;server_name www.educaproject.com educaproject.com;location / {include /etc/nginx/uwsgi_params;uwsgi_pass educa;}
}这是NGINX的基础配置。我们建立了一个upstream名叫educa指定了uWSGI使用的socket名称 然后使用server指令其中的设置有listen 80表示让NGINX监听80端口设置主机名为www.educaproject.com和educaproject.comNGINX会为这两个主机地址提供服务配置location参数将所有在/路径下的URL转发给上边的upstream educa也就是uWSGI的socket进行处理。还把NGINX自带的关于和uwsgi协同工作的参数设置也包含进去。NGINX还有很多复杂的设置文档可以参考https://nginx.org/en/docs/。NGINX主要的设置文件位于/etc/nginx/nginx.conf该文件包含/etc/nginx/sites-enabled/下的所有配置文件。为了让NGINX使用我们刚才编写的配置文件打开系统命令行窗口建立一个软连接Copysudo ln -s /home/projects/educa/config/nginx.conf /etc/nginx/sites-enabled/educa.conf将其中的/home/projects/educa/替换成实际的绝对路径。注意这里如果没有/sites-enabled/目录要先手工建立。如果还没有运行uWSGI打开系统命令行窗口在educa项目根目录先运行uWSGICopyuwsgi --ini config/uwsgi.ini当前窗口会被uWSGI占用再开一个命令行窗口然后执行Copyservice nginx start由于我们使用了自定义的域名还必须修改/etc/hosts添加如下两行Copy127.0.0.1 educaproject.com127.0.0.1 www.educaproject.com这样我们就把这两个域名都路由到本地回环地址上由于我们是从本机访问本机所以要更改HOSTS实际生产环境不必做本步修改因为生产环境会有固定的IP域名和对应的DNS解析。打开浏览器输入http://educaproject.com/应该可以看到站点了但是所有的静态文件依然没有被加载没关系即将完成生产环境的配置。如果系统是Centos 7这里显示502错误查看/var/log/nginx/error.log如果其中的错误是[crit] 4036#4036: *1 connect() to unix:///tmp/educa.sock failed (13: Permission denied)就先执行/usr/sbin/sestatus查看SELINUX的状态如果为开启就编辑SELINUX的设置将其关闭如下Copyvi /etc/selinux/config#SELINUXenforcing
SELINUXdisabled之后reboot重启系统才行。之后应该就可以正常显示站点了。之后为了安全起见到settings/pro.py中修改ALLOWED_HOSTS设置为NGINX配置文件中的两个域名CopyALLOWED_HOSTS [educaproject.com, www.educaproject.com]现在Django就只为这两个主机名提供服务了。关于ALLOWED_HOSTS的更多信息可以看https://docs.djangoproject.com/en/2.0/ref/settings/#allowed-hosts。1.10让NGINX提供静态文件和媒体资源服务NGINX提供静态文件的速度很快。刚才我们把所有的地址转发都交给了uWSGI现在要将所有的静态文件通过NGINX提供服务对于我们站点来说就是把所有的CSS JS文件和用户上传的媒体文件都交给NGINX来代理。编辑settings/base.py增加下边一行CopySTATIC_ROOT os.path.join(BASE_DIR, static/)这行表示存放站点静态文件的地址还记得之前学习过使用python manage.py collectstatic吗现在就需要将所有的静态文件收集过来放在此目录中在命令行中输入Copypython manage.py collectstatic --settingseduca.settings.pro注意原书的命令缺少了 --settingseduca.settings.pro可以看到下列输出Copy160 static files copied to /educa/static.静态文件目录设置好了现在需要将这个目录设置到NGINX中编辑config/nginx.conf在server指令后的大括号中增加下列内容Copylocation /static/ {alias /home/projects/educa/static/;
}
location /media/ {alias /home/projects/educa/media/;
}将其中的/home/projects/educa/static/和/home/projects/educa/media/替换成你项目的实际static和media目录的绝对路径。这两个参数解释如下/static/这个路径是Django中设置的STATIC_URL表示当NGINX看到/static/的路径请求的时候就到这个设置对应的路径中寻找所需文件。/media/这个路径是Django中设置的MEDIA_URL路径表示当NGINX看到/media/的路径请求的时候就到这个设置对应的路径中寻找所需文件。重新启动NGINX服务以便让配置文件生效Copyservice nginx reload在浏览器中打开http://educaproject.com/现在可以看到整个站点包含静态资源都正确的显示了。对于站点的静态文件请求NGINX将绕开uWSGI把文件直接返回给浏览器。现在生产环境就初步配置完毕。整个站点现在可以说运行在生产环境之下了。1.11使用SSL安全连接在配置完初步的生产环境之后下一个话题是站点的安全性。Secure Sockets Layer现在逐渐成为提供Web安全连接服务的规范。强烈建议对于正式的网站使用HTTPS协议现在就在NGINX中配置SSL认证来让站点变得更加安全。1.11.1创建一个SSL认证在educa项目根目录下建立一个ssl目录然后通过openssl生成我们的SSL证书Copysudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ssl/educa.key -out ssl/educa.crt用这条命令生成一个365天有效的2048位的SSL证书然后系统会提示输入一些信息CopyCountryName (2 letter code) [AU]:
StateorProvinceName (full name) [Some-State]:
LocalityName (eg, city) []:
OrganizationName (eg, company) [Internet Widgits Pty Ltd]:
OrganizationalUnitName (eg, section) []:
CommonName (e.g. server FQDN or YOUR name) []: educaproject.comEmailAddress[]: emaildomain.com这其中最关键的是Common Name必须将主机域名名称输入这里使用educaproject.com之后会在ssl/目录下生成两个文件educa.key是私钥educa.crt是实际的SSL证书。1.11.2配置NGINX使用SSL编辑config/nginx.conf在server设置中加入下列内容Copyserver {
listen 80;
listen 443 ssl;
ssl_certificate /home/projects/educa/ssl/educa.crt;
ssl_certificate_key /home/projects/educa/ssl/educa.key;
server_name www.educaproject.com educaproject.com;
# ...
}将其中的路径都修改为SSL证书所在的实际绝对路径。这么设置之后NGINX将同时监听80端口HTTP协议和443端口HTTPS协议然后指定了SSL的验证信息ssl_certificate与对应的密钥ssl_certificate_key。现在重新启动NGINX服务访问 https://educaproject.com/ 会看到类似如下提示这个提示因浏览器而异。意思是警告当前站点并没有使用一个值得信任的验证方式浏览器无法确定该站点安全与否。这是因为我们使用的SSL证书是由我们自行签发的而不是从一个受信任的机构Certification Authority获得的证书。当我们有了实际的公开域名之后就可以向一个受信任的证书颁发机构申请一个SSL证书这样浏览器就能识别该站点的HTTPS认证。如果想为实际的站点申请证书可以使用Linux基金会Linux Foundation的Lets Encrypt项目。这是一个致力于免费获得和更新SSL证书的计划该计划的站点在 https://letsencrypt.org/。点击 Add Exception 按钮可以让浏览器知道可以信任该站点这时浏览器的显示可能如下点击小锁按钮就可以看到SSL的详细信息。译者注这里也因浏览器而异有的浏览器依旧会提示证书不可信或者存在问题毕竟这个证书是我们自行签发的。1.11.3配置Django使用SSLDjango也有针对SSL的配置编辑settings/pro.py增加下边的代码CopySECURE_SSL_REDIRECT True
CSRF_COOKIE_SECURE True这两个设置的含义如下SECURE_SSL_REDIRECT是否所有的HTTP请求都必须被重定向到HTTPSCSRF_COOKIE_SECURE是否建立加密cookie防止CSRF攻击现在我们就配置好了一个高效的提供Web服务的生产环境。2自定义中间件在之前我们已经了解了中间件MIDDLEWARE的设置该设置包含项目中所有使用到的中间件。关于中间件可以认为其是一个底层的插件系统为在请求/响应的过程中提供钩子。每一个中间件都负责一个特定的行为会在HTTP请求和响应的过程中得到执行。注意不要添加开销非常大的中间件因为中间件会在项目的所有请求和响应的过程中被执行。当一个HTTP请求进来的时候中间件会按照其在MIDDLEWARE设置中从上到下的顺序执行当HTTP响应被生成且发送的过程中中间件会按照设置中从下到上的顺序执行。一个符合标准的函数可以作为一个中间件被注册在settings.py中。类似下边的函数就可以作为一个中间件Copydefmy_middleware(get_response):defmiddleware(request):# 对于每个HTTP请求在视图和之后的中间件执行之前执行的代码response get_response(request)# 对于每个HTTP请求和响应在视图执行之后执行的代码return responsereturn middleware一个中间件工厂函数接受一个get_response可调用对象然后返回一个中间件函数。一个中间件接受一个请求然后返回一个响应类似于视图。这里的get_response可以是下一个中间件如果自己就是中间件列表中的最后一个也可以是一个视图名称。如果任何一个中间件在尚未调用get_response这个可调用对象之前就返回了一个响应这个时候就会短路整个中间件链条的处理其后的中间件不再被执行这个响应开始从同级的中间件向上返回。所以MIDDLEWARE设置中的中间件顺序非常重要因为中间件依赖于上下中间件的数据进行工作。在向MIDDLEWARE中添加一个中间件时必须注意将其放置在正确的位置反复强调中间件在HTTP请求进来的时候从上到下执行HTTP响应发出的时候从下到上执行。原书在这里只是比较简单的说了一下执行顺序详细的中间件执行顺序请参考Django进阶-中间件以及https://docs.djangoproject.com/en/2.0/topics/http/middleware/。2.1创建二级域名中间件我们来创建一个自定义中间件用于通过一个自定义的二级域名来访问课程资源。例如某个显示课程的URLhttps://educaproject.com/course/django/可以通过一个二级域名django.educaproject.com来访问。这样用户就可以使用二级域名作为快捷方式快速访问课程也比较容易记忆该路径。所有发往这个二级域名的请求都会被重定向到实际的educaproject.com/course/django/这个URL。与视图模型表单等组件一样中间件也可以写在项目的任何位置。推荐在应用目录内建立middleware.py文件来编写中间件。在courses应用目录内创建middleware.py文件并编写如下代码Copyfrom django.urls import reverse
from django.shortcuts import get_object_or_404, redirect
from .models import Coursedefsubdomain_course_middleware(get_response):为课程提供二级域名defmiddleware(request):host_parts request.get_host().split(.)iflen(host_parts) 2and host_parts[0] ! www:# 通过指定的二级域名查询课程对象course get_object_or_404(Course, slughost_parts[0])course_url reverse(course_detail, args[course.slug])# 将二级域名请求重定向至实际的URLurl {}://{}{}.format(request.scheme, ..join(host_parts[1:]), course_url)return redirect(url)response get_response(request)return responsereturn middleware当一个HTTP请求进来的时候这个中间件执行如下任务取得这个HTTP请求中的域名然后将其分割成几部分例如mycourse.educaproject.com会被分割得到一个列表[mycourse, educaproject, com]检查这个域名是否包含二级域名判断分割后的域名是否包含多于2个元素。如果包含就取出第一个元素也就是二级域名如果这个域名不是www那就通过根据slug查询并取得该课程对象。如果找不到对应的课程就返回404错误如果找到了就重定向到课程对象对应的规范化URL。编辑settings/base.py把自定义中间件添加到MIDDLEWARE设置中CopyMIDDLEWARE [# ......courses.middleware.subdomain_course_middleware,
]还需要看一下ALLOWED_HOSTS中的域名设置这里我们将其设置为可以是任何eduproject.com的二级域名CopyALLOWED_HOSTS [.educaproject.com]ALLOWED_HOSTS中以一个.开始的域名例如.educaproject.com会匹配educaproject.com及所有的educaproject.com的二级域名比如course.educaproject.com和django.educaproject.com。2.3配置NGINX的二级域名编辑config/nginx.conf将以下这行Copyserver_name www.educaproject.com educaproject.com;修改成Copyserver_name *.educaproject.com educaproject.com;通过增加通配符设置让NGINX也可以代理所有的二级域名为了测试中间件还必须在etc/hosts中配置相关内容比如如果要测试二级域名django.educaproject.com需要增加一行Copy127.0.0.1 django.educaproject.com然后启动站点到https://django.educaproject.com/可以发现中间件现在将其重定向到 https://educaproject.com/course/django/3实现自定义的管理命令Django允许应用向manage.py管理工具中注册自定义的管理命令。所谓管理命令就是通过manage.py使用的指令例如我们曾经使用在第9章使用过makemessages和compilemessages命令。一个管理命令由一个Python模块组成这个模块里包含一个Command类这个Command类继承django.core.management.base.BaseCommand或者BaseCommand的子类。我们可以创建一个简单的包含参数和选项的自定义命令。对于每个在INSTALLED_APPS内注册的应用Django会在应用目录下边的management/commands/目录下搜索管理命令搜索到的每个命令模块都会被注册成为一个同名的命令。更多自定义管理命令的信息可以查看https://docs.djangoproject.com/en/2.0/howto/custom-management-commands/。我们准备来创建一个提醒学生至少选一个课程的命令。这个命令会向所有已经注册超过一定时间但还没有选任何一门课程的学生发送一封邮件。在student应用下建立如下的目录和文件结构Copymanagement/__init__.pycommands/__init__.pyenroll_reminder.py编辑enroll_reminder.py添加下列代码Copyimport datetime
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.mail import send_mass_mail
from django.contrib.auth.models import User
from django.db.models import CountclassCommand(BaseCommand):help Sends an e-mail reminder to users registered more than N days that are not enrolled into any courses yetdefadd_arguments(self, parser):parser.add_argument(--days, destdays, typeint)defhandle(self, *args, options):emails []subject Enroll in a coursedate_joined datetime.date.today() - datetime.timedelta(daysoptions[days])users User.objects.annotate(course_countCount(courses_joined)).filter(course_count0,date_joined__ltedate_joined)for user in users:message Dear {},\n\n We noticed that you didnt enroll in any courses yet. What are you waiting for?.format(user.first_name)emails.append((subject, message, settings.DEFAULT_FROM_EMAIL, [user.email]))send_mass_mail(emails)self.stdout.write(Sent {} reminders.format(len(emails)))这是enroll_reminder命令解释如下Command类继承BaseCommand类Command类包含一个help属性为命令提供帮助信息运行python manage.py help enroll_reminder就可以看到这段信息。add_arguments()用来设置可用的参数这里设置了--days参数指定其类型为整型。运行命令时这个参数用于指定天数方便筛选出要向其发送邮件的学生。handle()方法定义命令的实际业务逻辑。这里从命令行中获取解析后的days属性然后查询注册时间超过该天数的用户再通过分组计算这些用户的选课数量从中选出未选课的用户。然后使用一个emails列表记录所有需要发送的邮件最后通过send_mass_mail()方法发送邮件这样可以使用一个SMTP链接发送大量邮件而不用每发一次邮件就新开一个SMTP链接。编写好上述代码后打开系统命令行来运行命令Copypython manage.py enroll_reminder --days20如果还没有配置SMTP服务器可以参考第二章中的内容。如果确实没有SMTP服务器可以在settings.py中加上CopyEMAIL_BACKEND django.core.mail.backends.console.EmailBackend以让Django将邮件内容显示在控制台而不实际发送邮件。还可以通过系统让这个命令每天早上8点运行如果使用了基于UNIX的操作系统可以打开系统命令行模式输入crontab -e来编辑crontab在其中增加下边这行Copy0 8 * * * python /path/to/educa/manage.py enroll_reminder --days20 --settingseduca.settings.pro将其中的/path/to/educa/manage.py替换成实际的manage.py所在的绝对路径。如果不熟悉cron的使用可以参考http://www.unixgeeks.org/security/newbie/unix/cron-1.html。如果使用的是Windows可以使用系统的计划任务功能具体可以参考https://docs.microsoft.com/zh-cn/windows/desktop/TaskSchd/task-scheduler-start-page。还有一个方法是使用Celery定期执行任务。我们在第7章使用过Celery可以使用Celery beat scheduler来建立定期执行的异步任务具体可以参考https://celery.readthedocs.io/en/latest/userguide/periodic-tasks.html。对于想通过cron或者Windows的计划任务执行的单独脚本都可以通过自定义管理命令的方式来进行。Django还提供了一个使用Python执行管理命令的方法可以通过Python代码来运行管理命令例如Copyfrom django.core import management
management.call_command(enroll_reminder, days20)程序在执行到这里的时候就会去运行这个命令。现在我们就可以为自己的应用定制管理命令并且计划运行了。总结这一章里使用uWSGI和NGINX配置完成了生产环境还实现了自定义中间件和管理命令。到这里本书已经结束。祝贺你本书通过创建实际的项目和将其他软件与Django集成的方式指引你学习使用Django建立Web应用所需的技能。无论一个简单的项目原型还是大型的Web应用你现在都具备使用Django创建它们的能力。学习方向学习可不是拼多多这里学一点哪里学一点、到头来竹篮打水一场空所以得有个自动化测试所有方向技术点做一份整理形成各个领域的知识点汇总它的用处就在于你可以按照上面的知识点去找对应的学习资源保证自己学得较为全面。一、Python编程从入门到精通专题Python编程从入门到精通专题二、接口自动化测试项目实战专题接口1图接口自动化入门三、WEB自动化测试项目实战专题四、App自动化测试项目实战专题根据这个学习架构路线不断地去摸索与提升突破技术的瓶颈可以说这个过程会让你痛不欲生但只要你熬过去了。以后的生活就轻松很多。我也是走过这样一段路才能获得更多高薪职位的机会付出终有回报也算是对我能力的一种认可吧真正的证明了自己的价值。至少税后30的薪水是我当前状态下比较满意的。作为一位过来人也是希望你们少走一些弯路在这里我给大家分享一些自动化测试的相关资料希望帮你们更好的突破自己提高自己需要的可以来一手三连支持笔者我把这些资料的都放在这个群953306497了需要的自行领取哦。精品软件测试学习书籍1.技术沉淀学习积累对于三年多快四年的测试人员来说无论是在大厂小厂还是在外包公司基本上都是做得功能界面测试对接口、性能、自动化测试只是有点接触。很多人认为重复简单的工作对自己的技术是没有提升的但实际上也有人能从中杀出一条血路所以关键是你自己是否花了心思付出了努力。当然我个人也有自己的一套学习方式和习惯平时喜欢利用碎片时间来看点什么东西比如一些技术性的书籍或文档还有一些视频讲解等经常会让我有一种恍然大悟的感觉对我的工作也起到了很大的帮助。阅读书籍文档之前有些做手工测试的同事想转自动化测试让我推荐几本自动化测试入门的书籍 我都会建议他们根据自己所在项目的产品来选用对应的自动化测试工具来实践再结合自身的喜好来选书 下面推荐几本实用性强的书籍。1《Selenium 3自动化测试实战:基于Python语言》selenium 3自动化测试实战这本书是大佬虫师的作品虫师可以说是我的启蒙人了早期看了他很多的文章。这本书系统的讲解最新的selenium 3的应用涉及到持续集成、两大python单元测试框架unittest和pytest的应用还有数据驱动、PO模型、selenium的分布式运行等等非常全面值得入手。2《QTP自动化测试最佳实践》详细介绍了基于QTP的自动化测试技术适合自动化测试初学者阅读。因为QTP是付费软件如果所在公司或项目组能使用正版那真是个深入学习的好机会。3《自动化测试最佳实践》这本书在自动化测试领域影响深远它为很多公司指明了测试成功的方向。本书讲述了一些公司应用自动化的经历其中涉及了很多项目从复杂的政府部门系统到医疗设备从SAP业务过程开发到Android移动应用和云计算。4《App自动化测试与框架实战》从App测试基础、实战技术再到自动化测试框架的搭建全面地讲解App测试所需要的知识主要内容为App测试及其类型、Java编程环境构建、Java语言基础、Android自动化环境精讲、Android自动化测试基础精讲、Android Appium自动化框架、Appium数据驱动测试框架封装实战、Appium关键字驱动测试框架封装实战、持续集成的自动化、Appium常见问题处理方式。5《postman接口自动化测试持续集成》如果你正好需要利用postman完成接口自动化测试的工作那么这本书很适合你。如果你想看看 postman 是如何完成自动化测试并与自己的框架比对比对这本书也适合阅读。这本书详细讲解了接口测试基础、postman 如何来完成自动化设计和用例编写、newmangitjenkins 钉钉来完成持续集成工作。实战案例光学理论是没用的要学会跟着一起敲要动手实操才能将自己的所学运用到实际当中去这时候可以搞点实战案例来学习。电商项目实战web测试项目webApph5小程序 测试项目接口自动化测试实战项目Linux实战项目面试资料我们进阶学习自动化测试必然是为了找到高薪的工作下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料并且有字节大佬给出了权威的解答刷完这一套面试资料相信大家都能找到满意的工作。以上资料对于想要测试进阶的朋友们来说应该会很有帮助需要的小伙伴可以后台私信找我免费领取。总结我见过很多leader在面试的时候遇到处于迷茫期的大龄程序员比面试官年龄都大。这些人有一些共同特征可能工作了好几年更夸张的是7、8年工作内容的重复性比较高没有什么技术含量的工作。凡事要趁早特别是技术行业一定要提升技术功底丰富自动化项目实战经验这对于你未来几年职业规划以及测试技术掌握的深度非常有帮助。如果对你有帮助的话点个赞收个藏给作者一个鼓励。也方便你下次能够快速查找。如有不懂还要咨询下方小卡片博主也希望和志同道合的测试人员一起学习进步在适当的年龄选择适当的岗位尽量去发挥好自己的优势。我的自动化测试开发之路一路走来都离不每个阶段的计划因为自己喜欢规划和总结测试开发视频教程、学习笔记领取传送门