【问题标题】:django - url pattern to match url safe base64 stringdjango - 用于匹配 url 安全 base64 字符串的 url 模式
【发布时间】:2012-11-28 14:38:38
【问题描述】:

我正在使用

import base64
string_for_url = base64.urlsafe_b64encode(string_to_format)

但我不确定如何在 url 模式中匹配生成的字符串。我找到了这个正则表达式:(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$,但我不明白如何将其转换为命名组。如您所知,我的正则表达式知识非常有限。

提前感谢您的帮助。

【问题讨论】:

    标签: python regex django


    【解决方案1】:

    要命名一个组,以便将其传递给您的视图方法,并在其前面加上(?P<name_of_variable>(group to name))。顺便说一句,这不是 django 特有的,它是标准 Python regular expression syntax 的一部分。

    对于您的示例,它将是:

    base64_pattern = r'(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
    urlpatterns = patterns('',
        (r'^foo/bar/(?P<base64string>{})'.format(base64_pattern), 'mymethod'),
        # your other patterns
    )
    
    # in the view
    
    def mymethod(request, base64string):
       # do stuff with base64string
    

    【讨论】:

    • 作为一个数据点,如果你需要一个模式来匹配一个uidb64,根据Django 1.6 release notes,以下就足够了:r'^reset/(?P&lt;uidb64&gt;[0-9A-Za-z_\-]+)/(?P&lt;token&gt;.+)/$'这显然不是一个完整的base64匹配,但是当我试图理解为什么 1.6 之前的 Django 密码重置示例不起作用时,我最终进入了这个页面。
    【解决方案2】:

    那个正则表达式似乎不必要地复杂。

    我的 Django 生锈了,但你应该可以做到:

    urlpatterns = patterns('',
        (r'things/(?P<b64_string>.+)', views.b64_view, name='b64_view')
    )
    

    这将匹配任何看起来像 www.example.com/things/abc123= 的内容,并将 'abc123=' 传递到 views.b64_string 视图的 b64_string 参数中。

    然后您可以通过尝试对其进行解码来测试它是否为 b64 编码。这比尝试找到与 b64 编码字符串匹配的正则表达式要简单得多。

    【讨论】:

    • 只要您没有诸如“base64_string/another_token”之类的 URL,它就可以工作。例如,您可能需要将外部标识符编码为 base64(可能包含任何字符),然后有一个确认链接。
    【解决方案3】:

    从 2.0 开始,djano 在 url 路径中使用 captured values

    urlpatterns = [
      path('articles/2003/', views.special_case_2003),
      path('articles/<int:year>/', views.year_archive),
    ]
    

    当然,如果内置路径转换器(strintsluguuidpath)不够具体,您仍然可以使用正则表达式。在 url-safe base 64 编码的情况下,slug 可能匹配,但如果您需要.=~,那么您可以定义自己的:

    convertors.py

    class b64Converter:
        # decide on complexity of your b64 regex by
        # referring to https://stackoverflow.com/a/475217
        regex = 'define_your_regex here'
    
        def to_python(self, value):
            return base64.urlsafe_b64decode(value)
    
        def to_url(self, value):
            return base64.urlsafe_b64encode(value)
    

    然后是 urls.py:

    from django.urls import path, register_converter
    from . import converters, views
    
    register_converter(converters.b64Convertor, 'b64')
    
    urlpatterns = [
        path('widgets/<b64:my_url_param>/', views.widgetview),
        ...
    ]
    

    【讨论】:

    • 不知何故,我不断收到 NoReverseMatch 错误。即使我手动检查 re.match(pattern, encoded_value) 它确实匹配。很奇怪。
    【解决方案4】:

    这个怎么样:(?P&lt;string_to_format&gt;[0-9A-Za-z]+)

    【讨论】:

    • base64 编码输出的不仅仅是字母数字字符
    • 你查过base64吗?
    猜你喜欢
    • 2012-06-18
    • 2018-12-07
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 2011-11-03
    • 2021-08-24
    • 1970-01-01
    • 2016-06-07
    相关资源
    最近更新 更多