Can someone please explain how you can write a url pattern and view that allows optional parameters? I've done this successfully, but I always break the url template tag.
Here's what I have currently:
Pattern
(r'^so/(?P<required>\d+)/?(?P<optional>(.*))/?$', 'myapp.so')
View
def so(request, required, optional):
If I use the url template tag in this example providing both arguments, it works just fine; however, if I omit the optional argument, I get a reversing error.
How can I accomplish this?
Thanks, Pete
You can make a URI parameter as optional by adding a question mark (“?”) to the route parameter. If you make a route parameter as optional then you must specify a default value by using parameter = value for the method parameter.
The local Django webserver will automatically restart to reflect the changes. Try again to refresh the web page for the User section of the admin without the trailing slash: 127.0. 0.1:8000/admin/auth/user .
I generally make two patterns with a named url:
url(r'^so/(?P<required>\d+)/$', 'myapp.so', name='something'), url(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', 'myapp.so', name='something_else'),
Django urls are polymorphic:
url(r'^so/(?P<required>\d+)/$', 'myapp.so', name='sample_view'), url(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', 'myapp.so', name='sample_view'),
its obious that you have to make your views like this:
def sample_view(request, required, optional = None):
so you can call it with the same name and it would work work url resolver fine. However be aware that you cant pass None as the required argument and expect that it will get you to the regexp without argument:
Wrong:
{% url sample_view required optional %}
Correct:
{% if optional %} {% url sample_view required optional %} {% else %} {% url sample_view required %} {% endif %}
I dont know whether this is documented anywhere - I have discovered it by accident - I forgot to rewrite the url names and it was working anyway :)
Others have demonstrated the way to handle this with two separate named URL patterns. If the repetition of part of the URL pattern bothers you, it's possible to get rid of it by using include():
url(r'^so/(?P<required>\d+)/', include('myapp.required_urls'))
And then add a required_urls.py file with:
url(r'^$', 'myapp.so', name='something')
url(r'^(?P<optional>.+)/$', 'myapp.so', name='something_else')
Normally I wouldn't consider this worth it unless there's a common prefix for quite a number of URLs (certainly more than two).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With