#31070: Add a check for URLconfs that mix named and unnamed capture groups
-------------------------------------+-------------------------------------
     Reporter:  Baptiste Mispelon    |                    Owner:  Baptiste
                                     |  Mispelon
         Type:  New feature          |                   Status:  assigned
    Component:  Core (System         |                  Version:  master
  checks)                            |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Baptiste Mispelon):

 I agree that named groups should be preferred over unnamed groups (the
 documentation currently suggests that too). My problem is that it doesn't
 seem like a backwards-compatible suggestion.

 Consider the case of someone who has a working mixed-pattern URLConf,
 something like:
 {{{
 ^entry/(?P<pk>\d+)(\.html|/)$
 }}}
 In that case, changing the unnamed capture group to a named one will most
 likely break because the view will start receiving a new keyword argument
 which is probably incompatible (the view could be defined as `def
 blog_entry(request, pk)` for example).

 In contrast, changing the unnamed capture groups to non-capturing ones is
 100% backwards compatible and everything will keep behaving the same: the
 view will keep receiving the same keyword arguments as it did before.

 Here's a table that summarizes Django's behavior when matching the URL
 `/entry/123.html`:

 ||=            Pattern                   =||=               view call
 =||
 ||=`^entry/(?P<pk>\d+)(\.html|/)$`        || `blog_entry(pk='123')`
 ||
 ||=`^entry/(?P<pk>\d+)(?P<ext>\.html|/)$` || `blog_entry(pk='123',
 ext='.html')` ||
 ||=`^entry/(?P<pk>\d+)(?:\.html|/)$`      || `blog_entry(pk='123')`
 ||



 __**TLDR**__: What if the warning message was something like this
 (hopefully we can make it a bit less verbose while keeping it clear):

   Warning: you're mixing both named capture groups (syntax `(?P<name>...)`
 and unnamed capture groups (syntax `(...)`) in your URL pattern XXX.
   When you mix those, Django will only pass the named capture groups to
 the view while the unnamed ones will be discarded.
   Consider naming all your capture groups or alternatively, if you're
 relying on the silently-discarding-unnamed-captured-groups behavior then
 consider using unnamed capture groups for them (syntax `(?:...)`).

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31070#comment:8>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/067.264ace95679aa66bff4f763a5937ae1d%40djangoproject.com.

Reply via email to