2

I am using

import base64
string_for_url = base64.urlsafe_b64encode(string_to_format)

but I'm not sure how to match the generated string in a url pattern. I found this regex: (?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$ but I don't understand how to convert it into a named group. As you can tell my regex knowledge is pretty limited.

Thanks for any help in advance.

imns
  • 4,728
  • 11
  • 51
  • 77

4 Answers4

5

To name a group, so that it is passed to your view methods prefix it with (?P<name_of_variable>(group to name)). By the way, this is not something specific to django, its part of standard Python regular expression syntax.

For your example it would be:

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
Burhan Khalid
  • 152,028
  • 17
  • 215
  • 255
  • As a data point, if you need a pattern to match a `uidb64`, according to the [Django 1.6 release notes](http://docs.djangoproject.com/en/1.7/releases/1.6/), the following is sufficient: `r'^reset/(?P[0-9A-Za-z_\-]+)/(?P.+)/$'` This obviously isn't a complete base64 match, but I ended up on this page when I was trying to understand why a pre-1.6 Django password reset example wasn't working. – mirth23 Feb 20 '15 at 23:01
5

That regex seems needlessly complicated.

My Django is rusty, but you should be able to do:

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

This would match anything that looked like www.example.com/things/abc123= and pass 'abc123=' into the b64_string argument of the views.b64_string view.

Then you could test for it being b64 encoded simply by trying to decode it. That would be a lot simpler than trying to find a regex that matched of the b64 encoded string.

Michael Davis
  • 2,020
  • 2
  • 17
  • 28
  • This works as long as you don't have URLs such as 'base64_string/another_token'. For example, you may need to encode an external identifier as base64 (which may contain any character) and then have a confirmation link. – ChrisR Dec 10 '13 at 10:19
0

Since 2.0, djano uses captured values in url paths.

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

You can, of course, still use regular expressions if the built-in path converters (str, int, slug, uuid, path) aren't specific enough. In the case of url-safe base 64 encoding, slug may match, but if you need ., = and ~ then you can define your own:

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)

then 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),
    ...
]
Escher
  • 4,200
  • 6
  • 39
  • 78
  • Somehow, I keep getting NoReverseMatch errors. Even when I manullay check re.match(pattern, encoded_value) it does match. Very weird. – gabn88 May 06 '20 at 14:34
-3

How about this: (?P<string_to_format>[0-9A-Za-z]+)

Abid A
  • 6,626
  • 4
  • 28
  • 31