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

Django媒体图片访问404错误排查求助

问题现象

尝试获取媒体图片时出现404错误
获取图片文件时出现404错误

URL配置(应用级)

from django.urls import include, path

from rest_framework import routers
from django.conf.urls.static import static
from django.conf import settings

from my_awesome_api.views import PersonViewSet, SpeciesViewSet

router = routers.DefaultRouter()
router.register(r'people', PersonViewSet)
router.register(r'species', SpeciesViewSet)

urlpatterns = [
   path('', include(router.urls)),
]
urlpatterns+= static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
print('avail url patterns')
print(urlpatterns)

视图配置

from django.shortcuts import render

from rest_framework import viewsets
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework import permissions

from my_awesome_api.serializers import PersonSerializer, SpeciesSerializer
from my_awesome_api.models import Person, Species

class PersonViewSet(viewsets.ModelViewSet):
   queryset = Person.objects.all()
   serializer_class = PersonSerializer
   parser_classes = (MultiPartParser, FormParser)
   #permission_classes = [permissions.IsAuthenticatedOrReadOnly]
   def perform_create(self, serializer):
    serializer.save()


class SpeciesViewSet(viewsets.ModelViewSet):
   queryset = Species.objects.all()
   serializer_class = SpeciesSerializer
   parser_classes = (MultiPartParser, FormParser)
   #permission_classes = [permissions.IsAuthenticatedOrReadOnly]
   def perform_create(self, serializer):
    serializer.save()

模型配置

from django.db import models

# Create your models here.
class Species(models.Model):
   name = models.CharField(max_length=100)
   classification = models.CharField(max_length=100)
   language = models.CharField(max_length=100)
   image_url = models.ImageField(blank=True, null=True)


class Person(models.Model):
   name = models.CharField(max_length=100)
   birth_year = models.CharField(max_length=10)
   eye_color = models.CharField(max_length=10)
   species = models.ForeignKey(Species, on_delete=models.DO_NOTHING)
   image_url = models.ImageField(blank=True, null=True)

设置配置

MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'media')
print(MEDIA_ROOT)
print('value of media root')

# URL used to access the media
MEDIA_URL = 'media/'

已做排查

  • 已确认MEDIA_ROOT路径正确:/Users/ss1/Desktop/drf/media
  • 打印URL配置输出:[<URLResolver (None:None) ''>, <URLPattern '^media/(?P.*)$'>]
  • 项目级URL配置:
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path('star-wars/', include('my_awesome_api.urls')),
]
  • 图片已成功上传:
    图片上传成功

问题原因与解决方法

问题出在媒体URL的配置位置:你把static(settings.MEDIA_URL...)添加到了应用级的urls.py里,但应用是通过star-wars/路径被项目级URL包含的,这导致媒体文件的访问路径被解析为star-wars/media/xxx,但序列化器返回的图片URL是media/xxx,直接访问根路径下的media/时,项目级URL里没有对应的路由,所以返回404。

解决步骤:

  1. 删除应用级urls.py中的媒体URL配置代码:
# 移除以下内容
urlpatterns+= static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
print('avail url patterns')
print(urlpatterns)
  1. 将媒体URL配置添加到项目级的urls.py中,修改后代码如下:
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path("admin/", admin.site.urls),
    path('star-wars/', include('my_awesome_api.urls')),
]
# 添加媒体URL路由
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

额外注意:确保项目DEBUG模式处于开启状态(DEBUG=True),因为static()函数仅在DEBUG模式下生效,生产环境需用Nginx等服务托管媒体文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 09:45:28