Django鸡尾酒项目图片服务器显示404错误的排查与解决咨询
Django 鸡尾酒网站图片404问题修复方案
问题概述
开发个人鸡尾酒食谱网站时,饮品详情页的图片无法正常加载,仅显示占位图标,服务器返回404错误。Admin后台可正常保存图片,本地文件存储路径显示正确,但调整settings路径后,Admin上传图片会生成新文件夹而非存入现有img目录。已安装Pillow和Whitenoise库。
现有代码片段
models.py
from django.db import models class Vodka(models.Model): name = models.CharField(max_length=200) ingredients = models.TextField() instructions = models.TextField() notes = models.TextField() image = models.ImageField(upload_to='media/img/', default='') background = models.TextField(max_length='2000', default='')
settings.py
STATIC_URL = "static/" STATICFILES_DIRS = [ os.path.join(BASE_DIR, "cocktail_book", "media", "img"),] MEDIA_ROOT = BASE_DIR / 'cocktail_book'
vodka_display.html
{% extends 'base.html' %} {% load static %} {% block content %} <section> <h1>{{vodka_entry.name}}</h1> <div class="container"> {% if vodka_entry.image %} <img src="{% static vodka_entry.image.url %}" alt="Image"> {% endif %} </div> <h2>Ingredients</h2> <p>{{vodka_entry.ingredients|linebreaks }}</p> <h3>Instructions</h3> <p>{{vodka_entry.instructions|linebreaks }}</p> <h4>Notes</h4> <p>{{vodka_entry.notes}}</p> <h5>Background</h5> <p>{{vodka_entry.background}}</p> </section> {% endblock %}
核心问题分析
- 媒体资源配置缺失:未设置
MEDIA_URL,且MEDIA_ROOT与upload_to路径逻辑冲突,导致实际存储路径混乱 - 模板调用错误:用静态文件标签
{% static %}处理用户上传的媒体文件,混淆了静态资源与动态媒体资源的访问规则 - 静态目录配置混乱:将媒体图片目录加入
STATICFILES_DIRS,导致资源定位逻辑出错
修复步骤
1. 修正settings.py配置
import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent # 静态文件配置(存放CSS、JS等固定资源) STATIC_URL = "static/" STATICFILES_DIRS = [os.path.join(BASE_DIR, "cocktail_book", "static")] STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles") # 媒体文件配置(存放用户上传的动态资源) MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, "cocktail_book", "media")
2. 调整models.py的upload_to路径
upload_to是MEDIA_ROOT的子路径,无需重复写media/,避免路径嵌套错误:
from django.db import models class Vodka(models.Model): name = models.CharField(max_length=200) ingredients = models.TextField() instructions = models.TextField() notes = models.TextField() image = models.ImageField(upload_to='img/', default='') # 移除前缀media/ background = models.TextField(max_length=2000, default='')
3. 修改模板中的图片调用方式
媒体文件直接使用image.url属性,无需静态文件标签:
{% extends 'base.html' %} {% block content %} <section> <h1>{{vodka_entry.name}}</h1> <div class="container"> {% if vodka_entry.image %} <img src="{{ vodka_entry.image.url }}" alt="{{ vodka_entry.name }}"> {% endif %} </div> <h2>Ingredients</h2> <p>{{vodka_entry.ingredients|linebreaks }}</p> <h3>Instructions</h3> <p>{{vodka_entry.instructions|linebreaks }}</p> <h4>Notes</h4> <p>{{vodka_entry.notes}}</p> <h5>Background</h5> <p>{{vodka_entry.background}}</p> </section> {% endblock %}
4. 配置项目urls.py支持媒体文件访问
在项目根urls.py中添加媒体资源路由(仅开发环境生效):
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), # 其他业务路由 ] # 开发环境下提供媒体文件访问支持 if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
5. 迁移旧图片路径(可选)
若已有上传的图片存放在错误路径(如cocktail_book/media/media/img/),需手动将文件移动到cocktail_book/media/img/,并更新数据库中image字段的值(移除多余的media/前缀)。
内容的提问来源于stack exchange,提问作者2turtley
相关产品推荐
相关产品推荐

