Heroku Django 图像未加载

wor*_*vel 1 python django heroku

几个小时以来我一直试图解决这个问题,但似乎无法解决这个问题。我安装了白噪声,除了图像未加载外,网站工作正常。这是我的媒体代码:

\n\n

\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80.idea

\n\n

\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80分析员

\n\n

\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 pycache

\n\n

\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80博客

\n\n

\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80迁移

\n\n

\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 pycache

\n\n

\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80static

\n\n

\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80博客

\n\n

\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80images

\n\n

\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 模板

\n\n

\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80博客

\n\n

\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 pycache

\n\n

\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80media

\n\n

\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80article_pics

\n\n
STATIC_ROOT = os.path.join(BASE_DIR, \'staticfiles\')\nSTATIC_URL = \'/static/\'\n\nMEDIA_ROOT = os.path.join(BASE_DIR, \'media\')\nMEDIA_URL = \'/media/\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

主要网址:

\n\n
from django.contrib import admin\nfrom django.urls import path, include\nfrom django.conf import settings\nfrom django.conf.urls.static import static\n\nurlpatterns = [\n    path(\'admin/\', admin.site.urls),\n    path(\'\', include(\'blog.urls\'))\n]\n\nif settings.DEBUG:\n    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)\n
Run Code Online (Sandbox Code Playgroud)\n\n

主页模板:

\n\n
{% extends "blog/base.html" %}\n{% load static %}\n{% load crispy_forms_tags %}\n\n{%block content%}\n<!-- Images Section -->\n\n<div class="swiper-container" style="height:520px;">\n        <div class="swiper-wrapper">\n\n            <section class="swiper-slide about two">\n                <div class="container">\n                    <div class="title title-dark">\n                        <h2 class="title-heading">Analyze Everything</h2>\n                        <img class="about-profile" src="{%static \'images/think.png\'%}" alt="">\n                        <p class="price"></p>\n                    </div>\n                    <div class="cta">\n\n                    </div>\n                </div>\n            </section>\n\n            <section class="swiper-slide about two">\n                <div class="container">\n                    <div class="title title-dark">\n                        <h2 class="title-heading">Free Subscription</h2>\n                        <h3 class="title-sub-heading">Read. Analyze. Learn.</h3>\n                    </div>\n                    <div class="cta">\n                        <a href="#newsletter" class="btn btn-danger">Subscribe</a>\n                    </div>\n                </div>\n            </section>\n\n\n            </div>\n     <div class="swiper-pagination"></div>\n    <!-- Add Arrows -->\n    <div class="swiper-button-next"></div>\n    <div class="swiper-button-prev"></div>\n\n\n\n\n</div>\n<!-- End of Images Section -->\n\n<!-- Latest Articles -->\n<div class="container">\n    <hr><br>\n    <h1 class="text-center">Latest Articles</h1>\n    <!-- Row One of Articles -->\n    <div class="row">\n        {%for articles in articles%}\n          <div class="col-md-4 pt-4">\n            <div class="card h-100">\n                <img class="card-img-top" src="{{ articles.image.url }}" alt="Card image cap">\n                <div class="card-body">\n                    <a href="{% url \'article-detail\' articles.id%}" class="article-title">{{articles.title}}</a>\n                    <hr>\n                    <p class="card-text">{{articles.content|safe|slice:":80"}}...</p>\n                    <a class="btn btn-sm btn-outline-primary" href="{% url \'article-detail\' articles.id%}">Read More...</a>\n                </div>\n            </div>\n        </div>\n        {%endfor%}\n    </div>\n    <!-- End of Row One of Articles -->\n\n\n    <!-- Row Two of Articles -->\n    <div class="row ">\n        {% for articles_two in articles_two %}\n          <div class="col-md-4 pt-4">\n            <div class="card h-100">\n                <img class="card-img-top" src="{{ articles_two.image.url }}" alt="Card image cap">\n                <div class="card-body">\n                    <a href="{% url \'article-detail\' articles_two.id%}" class="article-title">{{articles_two.title}}</a><hr>\n                    <p class="card-text">{{articles_two.content|safe|slice:":80"}}...</p>\n                    <a class="btn btn-sm btn-outline-primary" href="{% url \'article-detail\' articles_two.id%}">Read More...</a>\n                </div>\n            </div>\n        </div>\n        {% endfor %}\n    </div>\n    <!-- End of Row Two of Articles -->\n\n    <br>\n    <a style="float:right;" href="{%url \'articles\' %}" class="btn btn-warning"> <i class="fas fa-angle-double-right"></i></a>\n</div>\n<!-- End of Latest Articles -->\n\n<br><br><hr>\n\n<section id="newsletter" class="newsletter">\n    <h1 class="text-center">Subscribe to The Analyst Now</h1>\n    <p class="text-center mb-3" style="color: grey;">Subscribe For Automatic Updates.</p>\n    <div class="text-center">\n        <form method="POST">\n            {% csrf_token %}\n            <fieldset class="form-group">{{form.as_p}}\n                <button class="btn btn-danger" type="submit">Subscribe</button>\n            </fieldset>\n        </form>\n    </div>\n    <br>\n</section>\n\n\n    <!-- Javascript Tags -->\n    <script src="{% static \'blog/swiper.min.js\' %}"></script>\n    <script>\n        var swiper = new Swiper(\'.swiper-container\', {\n          effect: \'coverflow\',\n          grabCursor: true,\n          centeredSlides: true,\n          slidesPerView: \'1\',\n\n          autoplay: {\n            delay: 3000,\n            disableOnInteraction: false,\n          },\n\n          coverflowEffect: {\n            stretch: 0,\n            depth: 100,\n            modifier: 1,\n            slideShadows : true,\n          },\n\n          navigation: {\n            nextEl: \'.swiper-button-next\',\n            prevEl: \'.swiper-button-prev\',\n          },\n          pagination: {\n            el: \'.swiper-pagination\',\n          },\n        });\n      </script>\n{%endblock%}\n
Run Code Online (Sandbox Code Playgroud)\n

Phi*_*ord 6

我认为这里发生了一些事情:

静态文件与媒体文件

只是为了清楚区别...静态文件是代码库的一部分,包括用于网站设计的 CSS 文件、JavaScript 文件和图像等内容。它们仅在您进行一些开发工作时才会改变。

媒体文件是通过管理员或通过您制作的供用户使用的表单上传到您网站的文件。例如个人资料图像、书籍封面或博客文章中的图像。

由于您对媒体文件的控制较少,因此它们通常会受到不同的对待,因为安全风险稍高,而且可能会有更多。

当地发展

在本地开发期间(当您使用./manage.py runserver)时,Django 的开发服务器应该毫无问题地提供静态文件和媒体文件。在本地工作时,您不需要使用白噪声。如果静态和/或媒体文件未加载,则可能是因为:

  • STATIC_ROOT设置 ( 、 )中的路径与MEDIA_ROOT静态目录和媒体目录的位置不匹配,或者
  • 您尝试指向模板中的文件的方式存在错误。

那么,本地开发时,静态文件和媒体文件都加载不出来吗?或者只是其中之一?在浏览器中查看页面的源代码并查看其中文件的路径 - 它们是您所期望的吗?

赫罗库

Heroku 没有持久文件系统,这意味着它无法提供媒体文件。因此,如果您或任何人通过网站上的表单上传新文件,虽然它最初可能会按预期加载,因为它已保存到磁盘,但很快文件本身就会消失并且不再在网站上加载。唯一保留在磁盘上的文件是那些属于代码存储库的文件。

您使用白噪声是正确的,但这只适用于您项目的静态文件。

要提供媒体文件,您需要使用django-storages并将文件托管在其他位置(例如 Amazon S3,或 django-storages 支持的其他服务)。这真的很痛苦,而且 Heroku 没有在他们的文档中解释这一点,这很烦人。如果你用谷歌搜索的话,有一些设置指南(我以前用过这个;我不知道它是否仍然有效)。


除了上述内容之外,我目前看到的文件结构的主要问题是article_picsmedia. 我假设你有一个带有字段的模型(Article?)image?也许您已将该字段的upload_to参数设置为article_pics?在这种情况下,该目录应该位于media.

当您在开发过程中添加新文章并上传图像时,您可以在文件系统中看到它吗?它去哪里?