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

Django中re_path路由下页面图片仅显示链接不加载的问题

Django媒体图片加载失败问题(re_path路由导致)

我开发了dashboard.html页面,用于展示近30天新注册用户的姓名、注册日期和头像。目前姓名和注册日期显示正常,但头像仅能看到链接(如<img src="/media/user_images/dream_TradingCard_1.jpg">),无法加载图片。经测试,使用path定义URL路由时图片显示正常,改用re_path后出现该问题。

相关代码与配置

1. 用户模型(podcast_user/models.py)

class PodcastUser(AbstractUser):
    user_id = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    username = models.CharField(max_length=30,unique=True)
    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',message="Phone number must be in the format: '+999999999'. Up to 15 digits allowed.")
    phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True, null=True, unique=True, default='+')
    date_of_birth = models.DateField(blank=True, null=True)
    date_of_join = models.DateField(blank=True, null=True,default=date.today)
    address = models.CharField(max_length=100,blank=True, null=True)
    country = models.ForeignKey(Country, on_delete=models.CASCADE,blank=True, null=True)
    image = models.ImageField(upload_to='user_images/', blank=True, null=True)
    city_name = models.CharField(max_length=30, blank=True, null=True)
    postal_code = models.CharField(max_length=10,blank=True, null=True)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    email = models.EmailField(max_length=30,
                          validators=[RegexValidator(regex="^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
                                                     message='please enter the correct format')],unique=True)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name','username']

    def create_superuser(self, email, password, **extra_fields):
        if self.filter(is_superuser=True).exists():
            raise ValueError('Superuser already exists')
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self._create_user(email=email, password=password, **extra_fields)

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

2. 视图函数(podcast_user/views.py)

def PodcastDashboard(request):
    thirty_days_ago = datetime.now() - timedelta(days=30)
    new_users = PodcastUser.objects.filter(date_of_join__gte=thirty_days_ago)
    return render(request, 'pages/podcast_dashboard.html', {'new_users': new_users})

3. 应用路由(podcast_user/urls.py)

from django.urls import re_path,path
from .views import login_and_register,PodcastDashboard,logout_view,confirm_user_request

urlpatterns = [
    re_path(r'^login_and_register/', login_and_register, name='login_and_register'),
    re_path(r'^podcast_dashboard/', PodcastDashboard, name='podcast_dashboard'),
    re_path(r'^logout/', logout_view, name='logout'),
    path('confirm_user_request/<int:user_id>/', confirm_user_request, name='confirm_user_request'),
]

4. 项目根路由(podcast/urls.py)

from django.contrib import admin
from django.urls import include, re_path,path
from django.views.generic import TemplateView
from django.conf.urls.static import static
from podcast.settings.base import MEDIA_URL, MEDIA_ROOT

urlpatterns = [
    re_path(r'^admin', admin.site.urls),
    re_path(r"^user/", include('podcast_user.urls')),
    re_path(r"^", TemplateView.as_view(template_name="pages/home.html"), name="home"),
]+ static(MEDIA_URL, document_root=MEDIA_ROOT)

5. 前端模板(podcast_dashboard.html)

{% load static %}
{% if user.is_authenticated %}
{% block content %}
<div class="card-body p-0">
  <h1>新注册用户</h1>
    <ul class="users-list clearfix">
       {% for user in new_users %}
         <li>
           {% if user.image %}
              <img src="{{ user.image.url }}" >
           {% endif %}
           <a class="users-list-name" href="#">{{ user.first_name }} {{ user.last_name }}</a>
           <span class="users-list-date"> {{ user.date_of_join|date:"M d, Y" }}</span>
         </li>
        {% empty %}
           <li>暂无新注册用户。</li>
         {% endfor %}
      </ul>
    </div>
{% endblock %}
{% endif %}

项目结构

podcast
|
├── podcast_user
|
└── templates_static_media
    ├── media
    |   └── user_images
    |       ├── default.jpg
    |       ├── dream_TradingCard.jpg
    |       ├── dream_TradingCard_1.jpg
    |       ├── Podcast-ddddd.png
    |       
    ├── static
    └── templates
        └── pages
            ├── podcast_dashboard.html
            └── test.htm

配置文件(settings.py)

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
APPS_DIR = os.path.join(ROOT_DIR, "templates_static_media/")
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = "static/"
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
STATICFILES_DIRS = (os.path.join(APPS_DIR, "static/"),)
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'

MEDIA_ROOT = os.path.join(APPS_DIR, "/media/")
MEDIA_URL = "/media/"

问题原因与解决方案

核心问题

  1. 路由匹配优先级错误:根路由re_path(r"^", ...)没有添加结束符$,导致所有包含/media/的请求会被该根路由先行匹配,媒体文件的静态路由无法生效。
  2. MEDIA_ROOT路径错误:os.path.join(APPS_DIR, "/media/")中第二个参数以/开头,导致MEDIA_ROOT直接变成/media/,而非项目下的templates_static_media/media/,Django无法找到存储的图片文件。

解决步骤

  1. 修正根路由匹配规则
    修改podcast/urls.py中的根路由,添加$以精确匹配根路径:
re_path(r"^$", TemplateView.as_view(template_name="pages/home.html"), name="home"),

同时建议给admin路由补全后缀,避免不必要的匹配:

re_path(r'^admin/', admin.site.urls),
  1. 修正MEDIA_ROOT路径
    修改settings.py中的MEDIA_ROOT配置:
MEDIA_ROOT = os.path.join(APPS_DIR, "media/")
  1. 验证DEBUG模式
    确保开发环境下DEBUG=True,因为static()函数仅在DEBUG模式下提供媒体文件的服务。

完成以上修改后,重启Django服务,头像即可正常加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:51:18