• Django 项目设置 Debug=False 后静态文件和上传文件404错误问题解决


    注:该方法适用于 Django 项目、静态文件和上传文件在同一台设备中。如静态文件在专用服务器或使用CDN,请参考 https://docs.djangoproject.com/zh-hans/3.0/howto/static-files/deployment/

    ​ 静态文件和用户上传文件的相关配置本文不再赘述,直入主题吧。

    ​ 默认配置下,Django 会在 DEBUG=True 时通过 django.contrib.staticfiles app 自动发现静态文件,用户上传文件则需要下面代码去实现自动配置。

    from django.conf.urls.static import static
    from django.conf import settings
    
    urlpatterns = [
    	...
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    

    ​ 然而当 DEBUG=False 后再次访问项目时,会发现静态文件和用户上传文件(如用户头像)均报404错误。这是因为该方法对于 DEBUG=False 不适用。

    ​ 对于静态文件和用户上传文件的部署,Django 给了两种方案。

    1. 手动通过 django.views.static.serve() 为静态文件和用户上传文件配置提供服务。但这种方法不安全。
    2. 结合 Django 项目的部署 ,通过配置 Web 服务器(如:Nginx),使其在 STATIC_URL 下为 STATIC_ROOT 目录下的文件提供静态文件服务,用户上传文件类似。官网推荐使用该方法。

    环境

    centos 7
    nginx = 1.2
    django = 2.2
    python = 3.7
    

    方案一:手动通过django.views.static.serve() 为静态文件和上传文件配置服务

    • settings.py 中配置静态文件和上传文件
    # settings.py
    
    DEBUG = False
    
    # 静态文件
    STATIC_URL = '/static/'
    STATIC_ROOT=os.path.join(BASE_DIR,"/static/") # 使用 collectstatic后收集的静态文件的存放绝对路径
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] # 存放静态文件的目录,其中也可以包含url
    
    # 文件上传
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    MEDIA_URL = '/media/'
    
    • project/project/urls.py 中为静态文件和上传文件配置URL
    # urls.py
    
    from django.urls import path, include, re_path
    from django.views.static import serve
    from django.conf import settings
    
    urlpatterns = [
        ...
        re_path(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}, name='static'),
        re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media')
    ]
    
    • 收集静态文件,并将已发现静态文件复制到 settings.STATUS_ROOT 目录中
    # 终端
    python manage.py collectstatic
    
    • 启动服务,会发现静态文件和上传文件均显示成功
    python manage.py runserver 0:8000
    

    此后,若静态文件发生改变后再出现404错误,再次执行 python manage.py collectstatic 即可

    方案二:通过配置 Web 服务器提供静态文件服务

    该方案会涉及 Nginx + uwsgi + Django 的部署(本次为单机部署),本次解决的问题是静态文件和用户上传文件404错误问题,部署的相关知识后期会陆续补充。

    先看部署框架

    我们的目的是当用户访问 /static/media 后会正常访问静态资源和用户上传文件。Let's begin

    • Nginx 服务器中新建静态文件和用户上传文件的保存目录,并修改权限(不修改会爆403错误)
    mkdir -P /var/www/finance/static
    mkdir -P /var/www/finance/media
    
    chmod 777 /var/www/finance/static
    chmod 777 /var/www/finance/media
    
    • 修改 settings.py ,将 STATOC_ROOTMEDIA_ROOOT 设置为 Nginx 服务器中保存静态文件和用户上传文件的位置
    # 静态文件
    STATIC_URL = '/static/'
    STATIC_ROOT="/var/www/finance/static"
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
    
    # 文件上传
    MEDIA_URL = '/media/'
    MEDIA_ROOT = "/var/www/finance/media/"
    

    注意:MEDIA_ROOT 发生改变后,用户上传文件的存放路径也会随之改变。如果开发环境中已上传用户数据,那么需要将这些数据一并复制到 MEDIA_ROOT 下才能保证页面的正常显示

    • 收集静态文件,将项目涉及的所有静态文件收集到 STATIC_ROOT 目录下
    # 终端
    python manage.py collectstatic
    
    • 重启 uwsgi 服务器
    uwsgi --stop uwsgi.pid
    uwsgi --ini uwsgi.ini
    
    • 配置 Nginx 服务器 /etc/nginx/nginx.conf
    ...
    server {
            ...
            location / {
                # 包含uwsgi的请求参数
                include /etc/nginx/uwsgi_params;
                # 转交请求给uwsgi
                uwsgi_pass 127.0.0.1:8000;
            }
    
            location /static {
                # 指定静态文件存放的目录
                alias /var/www/finance/static/;
            }
            
            location /media {
                # 指定用户上传存放目录
                alias /var/www/finance/media/;   
            }
    
            ...
        }
    

    配置 /static/media 的转发规则,URL 字段可以根据项目需求自行更改

    • 重启 Nginx 服务,浏览器中打开项目,会发现静态文件和上传文件均显示成功
    systemctl restart nginx
    

    此后,若静态文件在项目中发生改变,再次执行 python manage.py collectstatic 将其转移至 STATIC_ROOT 中即可正常显示。

    【完】

  • 相关阅读:
    在人生路上对我影响最大的三位老师
    秋季学期学习总结
    转载非原创 Windows编程革命简史
    转载 关于12360系统的讨论
    SQLServer 触发器
    sqlserver 自定义函数
    jQuery 动画
    jQuery让页面生动起来(操作页面里面的元素)
    jQuery选择元素
    SqlServer_Case_When用法
  • 原文地址:https://www.cnblogs.com/izbw/p/12378605.html
Copyright © 2020-2023  润新知