| | 60 | |
|---|
| | 61 | urlpatterns = patterns('', |
|---|
| | 62 | (r'^articles/2003/$', 'news.views.special_case_2003'), |
|---|
| | 63 | (r'^articles/(\d{4})/$', 'news.views.year_archive'), |
|---|
| | 64 | (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), |
|---|
| | 65 | (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), |
|---|
| | 66 | ) |
|---|
| | 67 | |
|---|
| | 68 | Notes: |
|---|
| | 69 | |
|---|
| | 70 | * ``from django.conf.urls.defaults import *`` makes the ``patterns`` |
|---|
| | 71 | function available. |
|---|
| | 72 | |
|---|
| | 73 | * To capture a value from the URL, just put parenthesis around it. |
|---|
| | 74 | |
|---|
| | 75 | * There's no need to add a leading slash, because every URL has that. For |
|---|
| | 76 | example, it's ``^articles``, not ``^/articles``. |
|---|
| | 77 | |
|---|
| | 78 | * The ``"r"`` in front of each regular expression string is optional but |
|---|
| | 79 | recommended. It tells Python that a string is "raw" -- that nothing in |
|---|
| | 80 | the string should be escaped. See `Dive Into Python's explanation`_. |
|---|
| | 81 | |
|---|
| | 82 | Examples: |
|---|
| | 83 | |
|---|
| | 84 | * A request to ``/articles/2005/03/`` would match the third entry in the |
|---|
| | 85 | list. Django would call the function |
|---|
| | 86 | ``news.views.month_archive(request, '2005', '03')``. |
|---|
| | 87 | |
|---|
| | 88 | * ``/articles/2005/3/`` would not match any URL patterns, because the |
|---|
| | 89 | third entry in the list requires two digits for the month. |
|---|
| | 90 | |
|---|
| | 91 | * ``/articles/2003/`` would match the first pattern in the list, not the |
|---|
| | 92 | second one, because the patterns are tested in order, and the first one |
|---|
| | 93 | is the first test to pass. Feel free to exploit the ordering to insert |
|---|
| | 94 | special cases like this. |
|---|
| | 95 | |
|---|
| | 96 | * ``/articles/2003`` would not match any of these patterns, because each |
|---|
| | 97 | pattern requires that the URL end with a slash. |
|---|
| | 98 | |
|---|
| | 99 | * ``/articles/2003/03/3/`` would match the final pattern. Django would call |
|---|
| | 100 | the function ``news.views.article_detail(request, '2003', '03', '3')``. |
|---|
| | 101 | |
|---|
| | 102 | .. _Dive Into Python's explanation: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3 |
|---|
| | 103 | |
|---|
| | 104 | Named groups |
|---|
| | 105 | ============ |
|---|
| | 106 | |
|---|
| | 107 | The above example used simple, *non-named* regular-expression groups (via |
|---|
| | 108 | parenthesis) to capture bits of the URL and pass them as *positional* arguments |
|---|
| | 109 | to a view. In more advanced usage, it's possible to use *named* |
|---|
| | 110 | regular-expression groups to capture URL bits and pass them as *keyword* |
|---|
| | 111 | arguments to a view. |
|---|
| | 112 | |
|---|
| | 113 | (Note that support for non-named regex groups is a new feature in the Django |
|---|
| | 114 | development version. Django 0.90 requires named groups.) |
|---|
| | 115 | |
|---|
| | 116 | In Python regular expressions, the syntax for named regular-expression groups |
|---|
| | 117 | is ``(?P<name>pattern)``, where ``name`` is the name of the group and |
|---|
| | 118 | ``pattern`` is some pattern to match. |
|---|
| | 119 | |
|---|
| | 120 | Here's the above example URLconf, rewritten to use named groups:: |
|---|
| 65 | | Notes: |
|---|
| 66 | | |
|---|
| 67 | | * ``from django.conf.urls.defaults import *`` makes the ``patterns`` |
|---|
| 68 | | function available. |
|---|
| 69 | | |
|---|
| 70 | | * To capture a value from the URL, use the syntax ``(?P<name>pattern)``, |
|---|
| 71 | | where ``name`` is the name for that value and ``pattern`` is some pattern |
|---|
| 72 | | to match. |
|---|
| 73 | | |
|---|
| 74 | | * There's no need to add a leading slash, because every URL has that. For |
|---|
| 75 | | example, it's ``^articles``, not ``^/articles``. |
|---|
| 76 | | |
|---|
| 77 | | * The ``"r"`` in front of each regular expression string is optional but |
|---|
| 78 | | recommended. It tells Python that a string is "raw" -- that nothing in |
|---|
| 79 | | the string should be escaped. See `Dive Into Python's explanation`_. |
|---|
| 80 | | |
|---|
| 81 | | Examples: |
|---|
| 82 | | |
|---|
| 83 | | * A request to ``/articles/2005/03/`` would match the third entry in the |
|---|
| 84 | | list. Django would call the function |
|---|
| 85 | | ``news.views.month_archive(request, year='2005', month='03')``. |
|---|
| 86 | | |
|---|
| 87 | | * ``/articles/2005/3/`` would not match any URL patterns, because the |
|---|
| 88 | | third entry in the list requires two digits for the month. |
|---|
| 89 | | |
|---|
| 90 | | * ``/articles/2003/`` would match the first pattern in the list, not the |
|---|
| 91 | | second one, because the patterns are tested in order, and the first one |
|---|
| 92 | | is the first test to pass. Feel free to exploit the ordering to insert |
|---|
| 93 | | special cases like this. |
|---|
| 94 | | |
|---|
| 95 | | * ``/articles/2003`` would not match any of these patterns, because each |
|---|
| 96 | | pattern requires that the URL end with a slash. |
|---|
| 97 | | |
|---|
| 98 | | * ``/articles/2003/03/3/`` would match the final pattern. Django would call |
|---|
| 99 | | the function |
|---|
| | 129 | This accomplishes exactly the same thing as the previous example, with one |
|---|
| | 130 | subtle difference: The captured values are passed as keyword arguments rather |
|---|
| | 131 | than positional arguments. For example: |
|---|
| | 132 | |
|---|
| | 133 | * A request to ``/articles/2005/03/`` would call the function |
|---|
| | 134 | ``news.views.month_archive(request, year='2005', month='03')``, instead |
|---|
| | 135 | of ``news.views.month_archive(request, '2005', '03')``. |
|---|
| | 136 | |
|---|
| | 137 | * A request to ``/articles/2003/03/3/`` would call the function |
|---|
| 102 | | .. _Dive Into Python's explanation: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3 |
|---|
| | 140 | In practice, this means your URLconfs are slightly more explicit and less prone |
|---|
| | 141 | to argument-order bugs -- and you can reorder the arguments in your views' |
|---|
| | 142 | function definitions. Of course, these benefits come at the cost of brevity; |
|---|
| | 143 | some folks find the named-group syntax ugly and too verbose. |
|---|
| | 144 | |
|---|
| | 145 | The matching/grouping algorithm |
|---|
| | 146 | ------------------------------- |
|---|
| | 147 | |
|---|
| | 148 | Here's the algorithm the URLconf parser follows, with respect to named groups |
|---|
| | 149 | vs. non-named groups in a regular expression: |
|---|
| | 150 | |
|---|
| | 151 | * If there are any named groups, it will use those as keyword arguments, |
|---|
| | 152 | ignoring any non-named groups. |
|---|
| | 153 | * Otherwise, it will pass all non-named groups as positional arguments. |
|---|
| | 154 | * In both cases, it will pass any extra |
|---|
| | 155 | |
|---|
| | 156 | If there are any named arguments, it will use those, ignoring non-named arguments. |
|---|
| | 157 | Otherwise, it will pass all non-named arguments as positional arguments. |
|---|
| | 158 | |
|---|
| | 159 | In both cases, it will pass any extra keyword arguments as keyword arguments. |
|---|
| | 160 | See "Passing extra options to view functions" below. |
|---|