平台:windows
python:3.10.0
django:4.0.8
nginx:1.24.0
背景
开发阶段采用前后端分离模式,现在要将项目部署到工控机上,把前端项目编译出来的静态文件放到后端项目中进行一体化部署,且不修改生成的html文件,不使用django的模板标签
项目结构
开发模式
相关配置
settings.py
#项目根目录路径,也可以用其它写法
BASE_DIR = Path(__file__).resolve().parent.parent
#仅在DEBUG模式(开发模式)下,才能用django自带的方法加载静态资源
DEBUG = True
#模板配置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 模板文件存放的位置,这里html文件放在项目的static文件夹下
'DIRS': [os.path.join(BASE_DIR, 'static')],
'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',
],
},
},
]
#静态文件的基础 URL
STATIC_URL = '/static/'
#第一个斜杠加不加都可以,但这个前缀必须和html文件中请求资源文件的url前缀保持一致
#例如,html文件中请求资源文件的url为:/static/js/chunk-vendors.js,那么这里就不能写成statics或者其它的,否则匹配不上
#静态文件搜索目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
os.path.join(BASE_DIR, 'static','static'),
#由于脚本文件放在 工程绝对路径/static/static/js目录下,所以搜索目录必须加上 工程绝对路径/static/static,否则当请求路径为 /static/js/chunk-vendors.js时,只会到 工程绝对路径/static目录下去找,不会到下一级static目录继续寻找
]
#总结:
#请求路径为 /static/js/chunk-vendors.js
#先到 工程绝对路径/static/js/chunk-vendors.js寻找(STATICFILES_DIRS配置的第一个目录)
#找不到目标文件,再到 工程绝对路径/static/static/js/chunk-vendors.js寻找(STATICFILES_DIRS配置的第二个目录)
#如果还是找不到资源文件,就会报错(404)
由于资源文件是前端项目直接生成的,我并不想用模板标签对生成的HTML文件进行改动。刚开始出现了访问不到资源文件的问题,后来发现在不使用模板标签的情况下,在HTML文件中访问静态文件,也是需要通过路由映射的。django提供了 staticfiles_urlpatterns() 这个函数将静态文件服务的url模式添加到django项目的url配置中,所以不需要我们手动添加。
当DEBUG设置为True时,django会自动提供静态文件服务,这样在开发环境中,就可以通过访问STATIC_URL中定义的路径来获取静态文件。
urls.py
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.http import HttpResponse
from django.views.generic.base import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path('system/', include(DeviceManager.urls)), # demo add
path('', TemplateView.as_view(template_name='index.html')),
path('monitor', TemplateView.as_view(template_name='monitor.html')),
]
urlpatterns += staticfiles_urlpatterns()
staticfiles_urlpatterns()源码
def staticfiles_urlpatterns(prefix=None):
"""
Helper function to return a URL pattern for serving static files.
"""
#没有指定前缀,就用STATIC_URL作为前缀
if prefix is None:
prefix = settings.STATIC_URL
return static(prefix, view=serve)
# Only append if urlpatterns are empty
#可见当settings.DEBUG为False的时候,这个配置是不起作用的
if settings.DEBUG and not urlpatterns:
urlpatterns += staticfiles_urlpatterns()
启动django项目,用localhost:5000/xxx(django的IP和端口,根据实际情况写)访问目标url即可
生产模式(需要安装nginx)
nginx:1.24.0
nginx下载地址
选择windows版本进行下载和安装
修改nginx配置
在nginx安装目录下找到conf/nginx.conf
#user nobody;
worker_processes 1;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#access_log logs/access.log;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
#index index.html index.htm;
proxy_pass http://127.0.0.1:5000; # 将端口号替换为 Django 项目运行的端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static/ {
alias E:/Demo/工程名/static/static/; # 将路径替换为静态文件所在的绝对路径(相对路径也可以,这里的相对路径就是相对于nginx.conf的路径)
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
主要需要关注的地方有
server {
listen 80; #用于指定 Nginx 监听的端口号,表示监听 HTTP 请求的标准端口
server_name localhost; #用于指定 Nginx 服务器的域名或 IP 地址,表示对来自该域名的请求进行处理
#charset koi8-r;
#access_log logs/host.access.log main;
#用于配置处理根路径 / 的请求的规则
location / {
root html; #指定静态文件的根目录。在这里,设置为 html,表示 Nginx 在处理请求时会从 html 目录中查找文件(nginx安装目录下的html目录)
index index.html index.htm;
#指定 Nginx 将请求转发到的后端服务器的地址。
#在这里,将请求代理到运行在 http://127.0.0.1:5000 上的 Django 项目,相当于直接访问 http://127.0.0.1:5000。
#设置代理后,会优先匹配并将请求代理到后端服务器,而不会使用 root 指令指定的静态文件目录
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
#域名/static/与服务端的静态文件路径间的映射
#用于配置处理静态文件路径 /static/ 的请求的规则。在这里,使用 alias 指令指定静态文件的根目录。
location /static/ {
alias E:/Demo/工程名/static/static/; # 将路径替换为你的静态文件路径(最后的斜杠不能少)
}
}
说明:
HTML文件用<script>标签请求资源文件:<script defer src=“/static/js/chunk-vendors.js”>
相当于向nginx服务器发送一个URL为 http://127.0.0.1:80/static/js/chunk-vendors.js 的 GET 请求
又由于 location /static/ 映射到的是 E:/Demo/工程名/static/static/,因此所有 /static/ 开头的请求都会从该目录中查找静态文件。
http://127.0.0.1:80/static/js/chunk-vendors.js 这个请求就会到 E:/Demo/工程名/static/static/js/chunk-vendors.js 目录下去寻找文件。
启动nginx服务
配置完成后,在nginx的安装目录下用命令行启动nginx.exe
修改settings.py
DEBUG = False
启动django项目,在浏览器中,用nginx.conf中配置的nginx服务器的IP和端口去访问页面。
例如,访问localhost:80(80可省略),就相当于直接访问localhost:5000
在django项目的urls.py中,有映射关系如下:
path('', TemplateView.as_view(template_name='index.html')),
path('monitor',TemplateView.as_view(template_name='monitor.html')),
localhost:5000对应的模板文件是index.html,浏览器就会加载这个页面,并根据nginx的配置,到指定路径下寻找html请求的资源文件
location /static/ {
alias E:/Demo/工程名/static/static/; # 将路径替换为你的静态文件路径
}
同样的,访问localhost:80/monitor也就相当于直接访问localhost:5000/monitor,对应的模板文件是monitor.html
停止nginx服务
nginx.exe -s stop
总结
对于根路径 / 的请求,Nginx 使用 proxy_pass 将请求代理到运行在 http://127.0.0.1:5000 上的 Django 项目。这是通过指定 proxy_pass http://127.0.0.1:5000; 实现的。这样,所有根路径的请求都会被转发到 Django 项目处理。
对于路径以 /static/ 开头的请求,Nginx 使用 alias 将请求映射到 E:/Demo/工程名/static/static/ 目录下。这是通过指定 alias E:/Demo/工程名/static/static/; 实现的。因此,所有 /static/ 开头的请求都会从该目录中查找静态文件。
这样就实现了对不同路径的请求的不同处理方式,其中 / 请求会被代理到 Django 项目,而 /static/ 开头的请求会在本地寻找静态文件。
这样做的好处是什么
动态请求(根路径 /):
动态请求通常需要在后端进行处理,例如 Django 项目中的视图处理。这包括处理用户的请求、查询数据库等。
通过代理到后端 Django 项目,Nginx 允许 Django 处理动态请求,因为 Django 项目通常负责处理这些动态内容。
静态文件请求(路径以 /static/ 开头):
静态文件(如样式表、脚本等)不需要在每个请求时都由 Django 处理,因为它们通常是不变的。将这些文件配置为由 Nginx 直接提供可以减轻 Django 项目的负担,提高性能。
通过使用 alias 将 /static/ 请求映射到本地静态文件目录,Nginx 可以直接提供这些文件,而无需经过 Django 项目。
这种分开处理的方式可以提高网站的整体性能,因为它允许专门的服务器处理专门的任务,并允许更灵活的配置和优化。
【参考】
Windows服务器,通过Nginx部署VUE+Django前后端分离项目
windows系统下安装Nginx以及简单使用(详解)
Windows安装部署nginx
django部署在windows使用nginx_nginx的原理
django静态文件配置(nginx)
Django静态文件配置
Django 关闭Debug后使用Nginx做静态文件的访问
P.S:小白一个,如有错误欢迎指正!