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

Django 3.1静态URL自动加斜杠致django-bakery构建问题求助

解决Django 3.1+ 与 django-bakery 兼容的静态资源路径问题

我之前碰到过完全一样的坑——Django 3.0.x版本里用相对路径STATIC_URL = 'static/'配合django-bakery生成静态站点完全正常,但升级到3.1+之后,生成的HTML里静态资源路径自动被加上了开头的/,导致本地打开index.html时直接报404,找不到同级static文件夹里的资源。

问题根源

Django 3.1的向后不兼容变更里明确提到:设置为相对路径的STATIC_URL和MEDIA_URL,会被服务器提供的SCRIPT_NAME值(未设置则默认是/)自动添加前缀。这个逻辑对依赖服务器的常规Django站点没问题,但django-bakery生成的是无服务器的静态文件包,static文件夹和index.html处于同一目录,必须用纯相对路径才能正确加载资源。

推荐解决方案:自定义模板标签绕过前缀处理

最稳定可靠的方法是写一个自定义静态标签,在django-bakery构建时自动去掉路径开头的斜杠,开发环境则保持正常的绝对路径行为:

  1. 创建自定义模板标签文件
    在你的Django应用下新建templatetags/static_relative.py:
from django import template
from django.templatetags.static import StaticNode
from django.conf import settings

register = template.Library()

class RelativeStaticNode(StaticNode):
    def url(self, context):
        # 先获取Django默认生成的静态资源URL
        static_url = super().url(context)
        # 如果处于bakery构建状态,去掉路径开头的斜杠
        if getattr(settings, 'BAKERY_BUILDING', False):
            return static_url.lstrip('/')
        return static_url

@register.tag('static_relative')
def do_static_relative(parser, token):
    return RelativeStaticNode.handle_token(parser, token)
  1. 配置构建时的状态标识
    修改bakery的构建命令,让构建过程触发我们的路径处理逻辑。在项目根目录新建management/commands/custom_build.py:
from bakery.management.commands.build import Command as BuildCommand
from django.conf import settings

class Command(BuildCommand):
    def handle(self, *args, **options):
        # 设置构建标识,告知自定义标签需要处理路径
        settings.BAKERY_BUILDING = True
        super().handle(*args, **options)
  1. 替换模板中的静态标签
    把原来模板里的{% static %}替换成自定义的{% static_relative %}:
<script src="{% static_relative 'js/main.js' %}"></script>
  1. 用自定义命令构建站点
    以后生成静态站点时,使用这个自定义命令代替原生的build:
python manage.py custom_build

替代方案:环境变量控制STATIC_URL

如果你不想写自定义标签,也可以通过环境变量在构建时强制设置无前缀的STATIC_URL:

  1. 修改settings.py配置
import os

# 开发环境用绝对路径,构建时切换为相对路径
if os.environ.get('BAKERY_BUILD') == '1':
    STATIC_URL = 'static/'
else:
    STATIC_URL = '/static/'
  1. 构建时设置环境变量
BAKERY_BUILD=1 python manage.py build

验证效果

构建完成后打开生成的index.html,脚本标签应该显示为<script src="static/js/main.js"></script>,这样本地打开页面时就能正确加载同级static文件夹里的资源了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:07:42