Optional URL parameters in django.urls.path

2,436 views
Skip to first unread message

Meiyer

unread,
Sep 19, 2022, 8:07:50 AM9/19/22
to Django developers (Contributions to Django itself)
Hi,

I feel there is a use case that the `path()` function does not address and thus requires to switch over to `re_path()` which immediately adds a lot of additional and error-prone syntax.

Often there is a need to capture a URL parameter which can be optional into the view’s kwargs. In terms of path() syntax, this could be accomplished by simply allowing, e.g., <int:param?>. However, I am not sure how to handle the forward slash that would usually appear after the parameter, and I don’t know how difficult it would be to amend the current implementation to support this feature.

By the way, if there was a discussion about this before, I couldn’t find it. Please point me to it if there was.

Carlton Gibson

unread,
Sep 19, 2022, 9:12:05 AM9/19/22
to django-d...@googlegroups.com
One approach is to route two patterns (one with the parameter and one without) to the same URL. Some duplication but (perhaps) easier to read at a glance than either an optional `?` operator.

Given that — and the alternative re_path() approach being available —  unless there was a particularly simple implementation on display I'd likely be sceptical about an addition here… 🤔

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/818f30d8-308b-4860-b861-7c7dde9b7aaan%40googlegroups.com.

Meiyer

unread,
Sep 19, 2022, 9:58:34 AM9/19/22
to Django developers (Contributions to Django itself)
> One approach is to route two patterns (one with the parameter and one without) to the same URL. Some duplication but (perhaps) easier to read at a glance than either an optional `?` operator.

I thought about that, but it won't work if I want both cases to be named similarly (via the `name` parameter). It also feels as duplicating the same line.

> Given that — and the alternative re_path() approach being available —  unless there was a particularly simple implementation on display I'd likely be sceptical about an addition here… 🤔

I did a bit of digging in the Django code and in fact it might be quite easy (it is also possible I am missing the elephant). django.urls.resolvers defines the syntax for the path parameters on line 245 [1] and converts the matches to regular expressions on line 290 [2]. Looks like an addition of the '?' to the regex after the closing bracket would do it..?


Matthew Pava

unread,
Sep 19, 2022, 10:07:26 AM9/19/22
to django-d...@googlegroups.com

I wonder if maybe you should look at the APPEND_SLASH setting.

https://docs.djangoproject.com/en/4.1/ref/settings/#append-slash

--

You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.

Meiyer

unread,
Oct 2, 2022, 2:16:21 AM10/2/22
to Django developers (Contributions to Django itself)
Is there any interest in implementing this feature? If yes, what would be the syntax for the path components that would follow the optional parameter (only if it is present)? I thought about something along the lines of  <int:param?:/> with the characters after the second colon having to appear literally in the URL.
For example: 
path(format_lazy('{org}<country_code:country?:/><slug:groupby>/', org=pgettext_lazy('URL', 'event/organizers/')), OrganizersView.as_vew()) 
would match both 
/üritus/korraldajad/perekonnanimi/ and /üritus/korraldajad/FI/perekonnanimi/ (in Estonian).

Carlton Gibson

unread,
Oct 2, 2022, 3:35:24 AM10/2/22
to django-d...@googlegroups.com
Hi. 

Re-reading again, I'm still not sure (personally) of the need/motivation given either of the "use two entries" or "use re_path()" options. 
Maybe it would be a nice-to-have but I'm not seeing the benefit as outweighing the complexity (remembering docs, and tests, and related functionality such as reverse() that would also need updating.) 

(IRL I've rarely needed this pattern. I've used both the options above without issue)

So, I'd probably be -1 at this point. 

Kind regards
Carlton


Adam Johnson

unread,
Oct 3, 2022, 5:26:44 PM10/3/22
to django-d...@googlegroups.com
I'd also be -1. There are two good alternatives already, which are both more flexible. No need to add a third way.

Reply all
Reply to author
Forward
0 new messages