You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django数据库存储图片无法显示的解决求助

问题解决:Django管理员上传图片无法显示修复方案(指定blog应用内存储)

一、静态文件vs媒体文件的选择

直接给结论:管理员上传的用户生成内容(UGC)必须用媒体文件(Media)。静态文件仅适用于网站开发阶段固定的资源(如CSS、默认图标),Django的静态文件机制是收集各应用static文件夹的资源到统一目录,完全不适合动态上传的内容。

二、修复步骤(严格遵循指定的blog应用内文件夹结构)

1. 修正Models.py配置

回归合理的关联结构,同时指定正确的上传路径:

class Reviews(models.Model):
    title = models.CharField(max_length=100)
    game_title = models.CharField(max_length=100)
    description = models.CharField(max_length=300)
    content = models.CharField(max_length=10000)
    game_rating = models.DecimalField(max_digits=2, decimal_places=1)
    game_user_rating = models.DecimalField(max_digits=2, decimal_places=1)
    date_of_publishing = models.DateField()

    def __str__(self):
        return f"{self.game_title}"

class ReviewsMiniaturesImages(models.Model):
    # upload_to写相对路径,会基于MEDIA_ROOT自动生成完整存储路径
    miniature_image = models.ImageField(upload_to="reviews_miniatures_images/")
    description = models.CharField(max_length=50)
    review = models.ForeignKey(Reviews, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.review.game_title} - {self.description}"

2. 修正settings.py的媒体文件配置

指定MEDIA_ROOT指向blog应用内的media文件夹,同时配置MEDIA_URL:

# 保留原有静态文件配置
STATIC_URL = "static/"

# 新增媒体文件配置
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 指向blog应用内的media目录
MEDIA_ROOT = os.path.join(BASE_DIR, 'blog', 'media')
MEDIA_URL = '/media/'

3. 配置项目urls.py,让Django提供媒体文件服务

在项目根目录的urls.py中添加媒体文件路由(仅开发环境使用,生产环境需交给Nginx/Apache):

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('accounts.urls')),
    path('blog/', include('blog.urls')),
    # 其他路由...
]

# 开发环境下添加媒体文件访问路由
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

4. 修正模板中的图片引用

使用{{ 字段名.url }}获取媒体文件的完整访问URL,无需static标签:

{% extends 'base.html' %}
{% block content %}
{% for review in reviews %}
<div class="h-100 d-flex align-items-center justify-content-center">
  <div class="card" style="width: 60rem;">
    {% with img=review.reviewsminiaturesimages_set.first %}
    {% if img %}
    <img src="{{ img.miniature_image.url }}" class="card-img-top"
         alt="{{ img.description }}">
    {% endif %}
    {% endwith %}
    <div class="card-body">
      <div class="row">
        <div class="col">
          <h5 class="card-title">{{review.game_title}}</h5>
        </div>
        <div class="col-7 d-flex justify-content-center">
          <h4 class="card-title">{{review.title}}</h4>
        </div>
        <div class="col d-flex justify-content-end">
          <h5 class="card-title">{{review.date_of_publishing}}</h5>
        </div>
      </div>
      <p class="card-text">{{review.description}}</p>
      <div class="row">
        <div class="col">
          <a href="{% url 'reviews-detail' review.id %}" class="btn btn-primary">To review</a>
        </div>
        <div class="col d-flex justify-content-end">
          <form action="" method="post">
            {% csrf_token %}
            <input type="submit" class="btn btn-primary" value="Add 'To Read'">
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
{% endfor %}
{% endblock %}

这里用first替代get避免多图片时报错,同时添加判断确保有图片时才渲染。

5. 迁移数据库并重新上传测试图片

修改Model后执行迁移,再重新上传图片:

python manage.py makemigrations
python manage.py migrate

此时图片会自动保存到blog/media/reviews_miniatures_images/目录下。

三、之前配置失败的原因

  1. 初始配置把上传文件放到static文件夹:静态文件机制是收集固定资源,动态上传的文件不会被识别,生产环境路径还会混乱。
  2. MEDIA_ROOT配置错误:用了绝对路径/blog/media/...,指向的是服务器根目录而非项目内路径,导致Django找不到文件。
  3. 模板引用错误:未使用url属性获取完整访问路径,直接写字段值仅能得到存储的相对路径,缺少MEDIA_URL前缀。

内容的提问来源于stack exchange,提问作者M4ti06

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:25:25