django admin class media 查询字符串参数乱码问题

 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的内置方法来解决,

详情参考:https://stackoverflow.com/questions/50259834/add-query-string-parameter-to-media-file-in-django-admin-form

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值