Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a good way to handle url parameters types?

Imagine an app with the following url.py:

urlpatterns = patterns('',
    url(r'^$', views.index),
    url(r'^double/(?P<number>\d+)/$', views.double),
)

And this views.py:

def double(request, number=42):
    return HttpResponse(2*number)

Obviously, I want number to be always taken as an int. When querying /double/5/, I'll always expect to get 10, not 55.

Are there any good way to handle the parameters typing within Django urls?

like image 943
Anto Avatar asked Jul 17 '14 15:07

Anto


2 Answers

Here's a decorator-based solution:

def param_type(**type_spec):
    def deco(f):
        def view(request, **kwargs):
            for k, type_ in type_spec.items():
                kwargs[k] = type_(kwargs[k])
            return f(request, **kwargs)
        return view
    return deco

@param_type(number=int)
def double(request, number=42):
    return HttpResponse(2*number)
like image 147
falsetru Avatar answered Sep 17 '22 21:09

falsetru


This thread says that auto-conversion isn't a good solution:

Note that automatic conversion wouldn't be a good plan, either. For example, the next version of my blog converts URLs like 2008/2/25/ to 2008/02/25/ because I want a canonical form. So I need to know if \d{1,2} matches one of two digits, even if the first one is 0. Auto-conversion to an integer would remove that capability (and it's not hard to think of other cases like this). So you'd need configurabiliy.

It also suggests a solution based on a decorator, but I'm not really convinced, it sounds a bit burdensome:

One solution to your problem could be to write a decorator that takes a list of types (plus something like None for "don't care") and automatically converts argument N to the type in the N-th element of the list before calling your function

like image 42
Anto Avatar answered Sep 20 '22 21:09

Anto