V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
princelai
V2EX  ›  Django

Django2.0 的 static 一直报错,加载不到 js 和 css,哪位懂得朋友给看看

  •  
  •   princelai · 2018-02-11 13:30:09 +08:00 · 12140 次点击
    这是一个创建于 2237 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我的 django 项目想使用 bootstrap,下载后分别放在了项目根目录的 static 和 app 目录的 static,app 叫 recommend,放两个是因为我怕报错,随便加载哪一个我都能接受,但是他一个都找不到。css 和 js 文件夹里都是有东西的。

    项目的结构如下

    .
    ├── Intelgoriform
    │   ├── configs.py
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── manage.py
    ├── README.md
    ├── recommend
    │   ├── admin.py
    │   ├── apps.py
    │   ├── initial.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── static
    │   │   ├── css
    │   │   └── js
    │   ├── templates
    │   │   └── index.html
    │   ├── tests.py
    │   ├── urls.py
    │   └── views.py
    └── static
        ├── css
        └── js
    

    index.html 就是 helloword,包含如下内容

    {% load static %}
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"/>
    

    app/urls.py 里只有‘’的路由,没加入 static 的路由,因为我看官方文档并没有设置路由

    当我在 settings 里加入如下信息时

    STATIC_URL = '/static/'
    
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, "static/"),
        os.path.join(BASE_DIR, "recommend", "static/"),
    ]
    

    网页是能够访问的,但是 css 和 js 是加载不出来的,报错内容为 指向“ http://127.0.0.1:8000/static/js/bootstrap.min.js ”的 <script> 加载失败。

    当我把 settings.py 的内容更改为

    # STATIC_URL = '/static/'
    
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, "static/"),
        os.path.join(BASE_DIR, "recommend", "static/"),
    ]
    

    STATIC_URL 被我注释掉了 这时候网页会报 500 错误,django 给我的反馈是 django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the required STATIC_URL setting.

    请问我到底是哪里做错了。如何才能正确加载啊,我弄了一天了快

    20 条回复    2018-02-12 12:08:35 +08:00
    chenqh
        1
    chenqh  
       2018-02-11 13:40:02 +08:00   ❤️ 1
    debug 模式,不是线上模式,django 的 static 好像只支持 debug=True
    twor
        2
    twor  
       2018-02-11 13:43:01 +08:00
    webserver (比如 Nginx ) 配置了没
    /my/project/path/static/
    或者 /my/project/path/recommend/static/
    Hstar
        3
    Hstar  
       2018-02-11 13:46:05 +08:00
    乍一看没什么问题,注释掉 STATICFILES_DIRS 试试
    twor
        4
    twor  
       2018-02-11 13:48:10 +08:00
    如果是 Nginx 可以参考

    location /static {
    alias /home/qr/static;
    }
    Hstar
        5
    Hstar  
       2018-02-11 13:54:16 +08:00   ❤️ 1
    楼主你先说下是怎么运行的,如果是 runserver 命令跑的调试模式,就不需要配置 nginx,那是生产环境分离静态文件用的。
    Gothack
        6
    Gothack  
       2018-02-11 14:03:11 +08:00
    缺少 STATIC_ROOT ?
    Gothack
        7
    Gothack  
       2018-02-11 14:04:40 +08:00
    这样试试

    ```python
    STATIC_URL = '/static/'

    STATIC_ROOT = os.path.join(BASE_DIR,'/static/')

    STATICFILES_DIRS = (
    ('','/usr/lib64/python2.7/site-packages/django/contrib/admin/static/'),
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    )
    ```
    princelai
        8
    princelai  
    OP
       2018-02-11 14:13:25 +08:00
    @Gothack @twor
    @chenqh
    @Hstar

    运行方式就是 python manage.py runserver
    本地没有 nginx,以后也准备就用 python 再带的 http 跑了,我先试试你们说的方法,感谢了
    princelai
        9
    princelai  
    OP
       2018-02-11 14:14:00 +08:00
    另外我把 debug 模式特意关了,就是为了模拟真正运行的时候不开 debug 模式
    kid7788
        10
    kid7788  
       2018-02-11 14:18:19 +08:00
    STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static/"),
    os.path.join(BASE_DIR, "recommend", "static/"),
    ]

    这里去掉“/”试试
    twor
        11
    twor  
       2018-02-11 14:19:29 +08:00   ❤️ 1
    https://stackoverflow.com/questions/5836674/why-does-debug-false-setting-make-my-django-static-files-access-fail

    With debug turned off Django won't handle static files for you any more - your production web server (Apache or something) should take care of that.
    ossicee
        12
    ossicee  
       2018-02-11 14:20:03 +08:00 via Android
    load staticfiles 吧
    princelai
        13
    princelai  
    OP
       2018-02-11 14:21:19 +08:00
    看了大家的回复我好想明白了点,问题是不是出在 django 的 static 必须是绝对路径下?

    我的需求就是 static 就在当前目录下,因为要在我本地,测试服务器和生产服务器配置,所以我想让 static 文件夹在哪个机器上都能动态加载,所以就想用相对目录而不是绝对目录。
    Readme16
        14
    Readme16  
       2018-02-11 14:26:48 +08:00   ❤️ 1
    settings.py 中配置 STATIC_ROOT:
    ```python
    STATIC_ROOT = 'static'
    ```

    urls.py 添加 static 路径
    ```python
    from django.conf import settings
    if settings.DEBUG:
    pass
    else:
    from django.views.static import serve
    from project.settings import STATIC_ROOT
    urlpatterns.append(url(r'^static/(?P<path>.*)$', serve, {'document_root': STATIC_ROOT}))
    ```
    princelai
        15
    princelai  
    OP
       2018-02-11 14:48:04 +08:00   ❤️ 1
    问题解决了,看了#11 @twor 的链接,里面的回答就是我要的结果,Django 的 static 文件确实需要 debug 模式的支持,#14 @Readme16 的方法确实也可以,在官方文档里叫“ Serving static files during development ”,就是把 static 的路由在非 debug 模式时候加入 urls,但是太麻烦,我还是用前一种方法吧。

    最后成功时的配置
    settings
    ```
    STATIC_URL = '/static/'

    STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    os.path.join(BASE_DIR, "recommend", "static"),
    ]
    ```
    没有设置 STATIC_ROOT

    启动 django 时要加--insecure
    `python   manage.py runserver --insecure`
    这时候不管static文件夹在 app/static 还是 /static/都是可以的,
    再次感谢所有回复的朋友。
    nekoprpr
        16
    nekoprpr  
       2018-02-11 16:44:14 +08:00
    建议 css,js 用放在云端(对象存储服务),不用担心这些,还能减轻服务器负担,我用青云对象存储,有一定免费额度的,足够用
    nekoprpr
        17
    nekoprpr  
       2018-02-11 16:47:22 +08:00
    你把这些放在本地部署的时候还要

    踩个大坑,你把 debug 关了后,django 就无法帮你加载静态文件了,你要用 nignx 配置才能用,血泪史啊
    princelai
        18
    princelai  
    OP
       2018-02-11 21:57:02 +08:00 via Android
    @nekoprpr Nginx 目前不归我管,是否最后用他加载静态文件还需要沟通,项目比较小,用 Django 自带的这个应该足够了
    746970179
        19
    746970179  
       2018-02-12 10:29:34 +08:00   ❤️ 1
    楼主是这样的
    当 debug=True 时, 就是本地的开发模式, 这个时候, 访问压力很小, django 能处理, 所以直接 python manage.py runserver 就会加载静态文件, 即 django 为了方便, 帮你处理了静态文件问题
    但是当 debug=False 时, django 认为这是生产环境了, 这个时候, 因为 django 处理静态文件能力时较差的, 这种情况一般(99%)会使用 nginx 处理今天文件, 所以 django 就不再处理静态文件了
    这个时候, 你再 runserver, 这个 server 只会处理那些 views 中的请求, 静态文件不再处理, 所以网站能用, 但是 css 没有加载
    PS: 有时候你会发现, debug=False, 好像有 css. 这是因为如果你先 debug=True, 刷新页面(此时加载了 css), 再 debug=False, 刷新页面会发现还有 css, 这是因为页面有缓存, 还没有及时清理. 使用清缓存刷新(win 下时 ctrl+F5, mac 下是 cmd+shift+R), 就会发现 css 没了
    如果想 debug=False 仍能有 css, 最简单就是
    python manage.py runserver --insecure
    princelai
        20
    princelai  
    OP
       2018-02-12 12:08:35 +08:00 via Android
    @746970179 谢谢回复这么长,大概了解了原因,不过因为我是对内留了一个可视化的页面,只有内部人看,外部不访问,所以压力很小,insecure 应该够了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   980 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:30 · PVG 04:30 · LAX 13:30 · JFK 16:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.