admin代码:
#admin.py
from django.contrib import admin
class MyAdmin(admin.ModelAdmin):
form = PushRuleForm
class Media:
js = ('my.js?r=1.0',)
请求错误,404
GET http://localhost:8888/static/my.js%3Fr%3D1.0 net::ERR_ABORTED 404 (Not Found)
因为js路径被encode了,所以找不到,
之前django1.8,django1.9都是正常的,django1.11报错
先说个解决方,相对路径换成绝对路径就可以了,
class Media:
js = ('http://localhost:8888/static/my.js?r=1.0',)
代码分析:/site-packages/django/forms/widgets.py
absolute_path方法中如果是http、https、/开头的,就直接返回,不会被static方法处理,所以查询字符串参数不会被encode,显示正常。
def absolute_path(self, path):
"""
Given a relative or absolute path to a static asset, return an absolute
path. An absolute path will be returned unchanged while a relative path
will be passed to django.templatetags.static.static().
"""
if path.startswith(('http://', 'https://', '/')):
return path
return static(path)
如果是相对路径:
方法调用过程调用static——>handle_simple——>url——>filepath_to_uri——>quote
quote方法最后一句代码通过quoter函数对字符串每个字符进行了encode,
return ''.join(map(quoter, s))
大概就是这样.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
这些字符应该都是会被encode的
quote方法详情
def quote(s, safe='/'):
"""quote('abc def') -> 'abc%20def'
Each part of a URL, e.g. the path info, the query, etc., has a
different set of reserved characters that must be quoted.
RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
the following reserved characters.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
"$" | ","
Each of these characters is reserved in some component of a URL,
but not necessarily in all of them.
By default, the quote function is intended for quoting the path
section of a URL. Thus, it will not encode '/'. This character
is reserved, but in typical usage the quote function is being
called on a path where the existing slash characters are used as
reserved characters.
"""
# fastpath
if not s:
if s is None:
raise TypeError('None object cannot be quoted')
return s
cachekey = (safe, always_safe)
try:
(quoter, safe) = _safe_quoters[cachekey]
except KeyError:
safe_map = _safe_map.copy()
safe_map.update([(c, c) for c in safe])
quoter = safe_map.__getitem__
safe = always_safe + safe
_safe_quoters[cachekey] = (quoter, safe)
if not s.rstrip(safe):
return s
return ''.join(map(quoter, s))
也可以通过重写django的内置方法来解决,