Fixed #22378 -- Updated \d to [0-9]+ in urlpatterns of docs and tests.

Thanks tomwys for the suggestion.
This commit is contained in:
chriscauley 2014-04-14 14:12:44 -04:00 committed by Tim Graham
parent 030dd4f72c
commit 66ec9ee441
38 changed files with 181 additions and 181 deletions

View File

@ -187,9 +187,9 @@ example above::
from django.conf.urls import url from django.conf.urls import url
urlpatterns = [ urlpatterns = [
url(r'^articles/(\d{4})/$', 'news.views.year_archive'), url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'news.views.article_detail'),
] ]
The code above maps URLs, as simple `regular expressions`_, to the location of The code above maps URLs, as simple `regular expressions`_, to the location of

View File

@ -215,11 +215,11 @@ Wire these new views into the ``polls.urls`` module by adding the following
# ex: /polls/ # ex: /polls/
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),
# ex: /polls/5/ # ex: /polls/5/
url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'), url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
# ex: /polls/5/results/ # ex: /polls/5/results/
url(r'^(?P<question_id>\d+)/results/$', views.results, name='results'), url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/ # ex: /polls/5/vote/
url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'), url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
] ]
Take a look in your browser, at "/polls/34/". It'll run the ``detail()`` Take a look in your browser, at "/polls/34/". It'll run the ``detail()``
@ -251,15 +251,15 @@ Here's what happens if a user goes to "/polls/34/" in this system:
* Then, Django will strip off the matching text (``"polls/"``) and send the * Then, Django will strip off the matching text (``"polls/"``) and send the
remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
further processing which matches ``r'^(?P<question_id>\d+)/$'`` resulting in a further processing which matches ``r'^(?P<question_id>[0-9]+)/$'`` resulting in a
call to the ``detail()`` view like so:: call to the ``detail()`` view like so::
detail(request=<HttpRequest object>, question_id='34') detail(request=<HttpRequest object>, question_id='34')
The ``question_id='34'`` part comes from ``(?P<question_id>\d+)``. Using parentheses The ``question_id='34'`` part comes from ``(?P<question_id>[0-9]+)``. Using parentheses
around a pattern "captures" the text matched by that pattern and sends it as an around a pattern "captures" the text matched by that pattern and sends it as an
argument to the view function; ``?P<question_id>`` defines the name that will argument to the view function; ``?P<question_id>`` defines the name that will
be used to identify the matched pattern; and ``\d+`` is a regular expression to be used to identify the matched pattern; and ``[0-9]+`` is a regular expression to
match a sequence of digits (i.e., a number). match a sequence of digits (i.e., a number).
Because the URL patterns are regular expressions, there really is no limit on Because the URL patterns are regular expressions, there really is no limit on
@ -554,7 +554,7 @@ defined below::
... ...
# the 'name' value as called by the {% url %} template tag # the 'name' value as called by the {% url %} template tag
url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'), url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
... ...
If you want to change the URL of the polls detail view to something else, If you want to change the URL of the polls detail view to something else,
@ -563,7 +563,7 @@ template (or templates) you would change it in ``polls/urls.py``::
... ...
# added the word 'specifics' # added the word 'specifics'
url(r'^specifics/(?P<question_id>\d+)/$', views.detail, name='detail'), url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
... ...
Namespacing URL names Namespacing URL names

View File

@ -61,7 +61,7 @@ created a URLconf for the polls application that includes this line:
.. snippet:: .. snippet::
:filename: polls/urls.py :filename: polls/urls.py
url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'), url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
We also created a dummy implementation of the ``vote()`` function. Let's We also created a dummy implementation of the ``vote()`` function. Let's
create a real version. Add the following to ``polls/views.py``: create a real version. Add the following to ``polls/views.py``:
@ -228,9 +228,9 @@ First, open the ``polls/urls.py`` URLconf and change it like so:
urlpatterns = [ urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'), url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'), url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'), url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'), url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
] ]
Amend views Amend views

View File

@ -198,8 +198,8 @@ RedirectView
from article.views import ArticleCounterRedirectView, ArticleDetail from article.views import ArticleCounterRedirectView, ArticleDetail
urlpatterns = [ urlpatterns = [
url(r'^counter/(?P<pk>\d+)/$', ArticleCounterRedirectView.as_view(), name='article-counter'), url(r'^counter/(?P<pk>[0-9]+)/$', ArticleCounterRedirectView.as_view(), name='article-counter'),
url(r'^details/(?P<pk>\d+)/$', ArticleDetail.as_view(), name='article-detail'), url(r'^details/(?P<pk>[0-9]+)/$', ArticleDetail.as_view(), name='article-detail'),
url(r'^go-to-django/$', RedirectView.as_view(url='http://djangoproject.com'), name='go-to-django'), url(r'^go-to-django/$', RedirectView.as_view(url='http://djangoproject.com'), name='go-to-django'),
] ]

View File

@ -171,7 +171,7 @@ YearArchiveView
from myapp.views import ArticleYearArchiveView from myapp.views import ArticleYearArchiveView
urlpatterns = [ urlpatterns = [
url(r'^(?P<year>\d{4})/$', url(r'^(?P<year>[0-9]{4})/$',
ArticleYearArchiveView.as_view(), ArticleYearArchiveView.as_view(),
name="article_year_archive"), name="article_year_archive"),
] ]
@ -267,11 +267,11 @@ MonthArchiveView
urlpatterns = [ urlpatterns = [
# Example: /2012/aug/ # Example: /2012/aug/
url(r'^(?P<year>\d{4})/(?P<month>[-\w]+)/$', url(r'^(?P<year>[0-9]{4})/(?P<month>[-\w]+)/$',
ArticleMonthArchiveView.as_view(), ArticleMonthArchiveView.as_view(),
name="archive_month"), name="archive_month"),
# Example: /2012/08/ # Example: /2012/08/
url(r'^(?P<year>\d{4})/(?P<month>\d+)/$', url(r'^(?P<year>[0-9]{4})/(?P<month>[0-9]+)/$',
ArticleMonthArchiveView.as_view(month_format='%m'), ArticleMonthArchiveView.as_view(month_format='%m'),
name="archive_month_numeric"), name="archive_month_numeric"),
] ]
@ -361,7 +361,7 @@ WeekArchiveView
urlpatterns = [ urlpatterns = [
# Example: /2012/week/23/ # Example: /2012/week/23/
url(r'^(?P<year>\d{4})/week/(?P<week>\d+)/$', url(r'^(?P<year>[0-9]{4})/week/(?P<week>[0-9]+)/$',
ArticleWeekArchiveView.as_view(), ArticleWeekArchiveView.as_view(),
name="archive_week"), name="archive_week"),
] ]
@ -475,7 +475,7 @@ DayArchiveView
urlpatterns = [ urlpatterns = [
# Example: /2012/nov/10/ # Example: /2012/nov/10/
url(r'^(?P<year>\d{4})/(?P<month>[-\w]+)/(?P<day>\d+)/$', url(r'^(?P<year>[0-9]{4})/(?P<month>[-\w]+)/(?P<day>[0-9]+)/$',
ArticleDayArchiveView.as_view(), ArticleDayArchiveView.as_view(),
name="archive_day"), name="archive_day"),
] ]
@ -597,7 +597,7 @@ DateDetailView
from django.views.generic.dates import DateDetailView from django.views.generic.dates import DateDetailView
urlpatterns = [ urlpatterns = [
url(r'^(?P<year>\d+)/(?P<month>[-\w]+)/(?P<day>\d+)/(?P<pk>\d+)/$', url(r'^(?P<year>[0-9]+)/(?P<month>[-\w]+)/(?P<day>[0-9]+)/(?P<pk>[0-9]+)/$',
DateDetailView.as_view(model=Article, date_field="pub_date"), DateDetailView.as_view(model=Article, date_field="pub_date"),
name="archive_date_detail"), name="archive_date_detail"),
] ]

View File

@ -217,7 +217,7 @@ The police beat feeds could be accessible via URLs like this:
These can be matched with a :doc:`URLconf </topics/http/urls>` line such as:: These can be matched with a :doc:`URLconf </topics/http/urls>` line such as::
(r'^beats/(?P<beat_id>\d+)/rss/$', BeatFeed()), (r'^beats/(?P<beat_id>[0-9]+)/rss/$', BeatFeed()),
Like a view, the arguments in the URL are passed to the ``get_object()`` Like a view, the arguments in the URL are passed to the ``get_object()``
method along with the request object. method along with the request object.

View File

@ -930,10 +930,10 @@ Slightly complex built-in ``Field`` classes
# Or define a different message for each field. # Or define a different message for each field.
fields = ( fields = (
CharField(error_messages={'incomplete': 'Enter a country code.'}, CharField(error_messages={'incomplete': 'Enter a country code.'},
validators=[RegexValidator(r'^\d+$', 'Enter a valid country code.')]), validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid country code.')]),
CharField(error_messages={'incomplete': 'Enter a phone number.'}, CharField(error_messages={'incomplete': 'Enter a phone number.'},
validators=[RegexValidator(r'^\d+$', 'Enter a valid phone number.')]), validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid phone number.')]),
CharField(validators=[RegexValidator(r'^\d+$', 'Enter a valid extension.')], CharField(validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.')],
required=False), required=False),
) )
super(PhoneField, self).__init__( super(PhoneField, self).__init__(

View File

@ -642,7 +642,7 @@ template tag and a high-level wrapper for the
An example should make it clear how to use ``permalink()``. Suppose your URLconf An example should make it clear how to use ``permalink()``. Suppose your URLconf
contains a line such as:: contains a line such as::
(r'^people/(\d+)/$', 'people.views.details'), (r'^people/([0-9]+)/$', 'people.views.details'),
...your model could have a :meth:`~django.db.models.Model.get_absolute_url` ...your model could have a :meth:`~django.db.models.Model.get_absolute_url`
method that looked like this:: method that looked like this::
@ -655,7 +655,7 @@ method that looked like this::
Similarly, if you had a URLconf entry that looked like:: Similarly, if you had a URLconf entry that looked like::
(r'/archive/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', archive_view) (r'/archive/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', archive_view)
...you could reference this using ``permalink()`` as follows:: ...you could reference this using ``permalink()`` as follows::
@ -684,7 +684,7 @@ pattern tuple by a call to the ``url`` function)::
from django.conf.urls import url from django.conf.urls import url
url(r'^people/(\d+)/$', 'blog_views.generic_detail', name='people_view'), url(r'^people/([0-9]+)/$', 'blog_views.generic_detail', name='people_view'),
...and then using that name to perform the reverse URL resolution instead ...and then using that name to perform the reverse URL resolution instead
of the view name:: of the view name::

View File

@ -1000,7 +1000,7 @@ takes a client ID (here, ``client()`` is a method inside the views file
.. code-block:: python .. code-block:: python
('^client/(\d+)/$', 'app_views.client') ('^client/([0-9]+)/$', 'app_views.client')
If this app's URLconf is included into the project's URLconf under a path If this app's URLconf is included into the project's URLconf under a path
such as this: such as this:

View File

@ -23,9 +23,9 @@ URLconf from the :doc:`Django overview </intro/overview>`::
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^articles/(\d{4})/$', 'news.views.year_archive'), url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'news.views.article_detail'),
) )
In this example, each view has a common prefix -- ``'news.views'``. In this example, each view has a common prefix -- ``'news.views'``.
@ -38,9 +38,9 @@ With this in mind, the above example can be written more concisely as::
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
urlpatterns = patterns('news.views', urlpatterns = patterns('news.views',
url(r'^articles/(\d{4})/$', 'year_archive'), url(r'^articles/([0-9]{4})/$', 'year_archive'),
url(r'^articles/(\d{4})/(\d{2})/$', 'month_archive'), url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'month_archive'),
url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'article_detail'),
) )
Note that you don't put a trailing dot (``"."``) in the prefix. Django puts Note that you don't put a trailing dot (``"."``) in the prefix. Django puts

View File

@ -533,7 +533,7 @@ multiple URLs point at the same view, each URL will be cached separately.
Continuing the ``my_view`` example, if your URLconf looks like this:: Continuing the ``my_view`` example, if your URLconf looks like this::
urlpatterns = [ urlpatterns = [
url(r'^foo/(\d{1,2})/$', my_view), url(r'^foo/([0-9]{1,2})/$', my_view),
] ]
then requests to ``/foo/1/`` and ``/foo/23/`` will be cached separately, as then requests to ``/foo/1/`` and ``/foo/23/`` will be cached separately, as
@ -579,7 +579,7 @@ Doing so is easy: simply wrap the view function with ``cache_page`` when you
refer to it in the URLconf. Here's the old URLconf from earlier:: refer to it in the URLconf. Here's the old URLconf from earlier::
urlpatterns = [ urlpatterns = [
url(r'^foo/(\d{1,2})/$', my_view), url(r'^foo/([0-9]{1,2})/$', my_view),
] ]
Here's the same thing, with ``my_view`` wrapped in ``cache_page``:: Here's the same thing, with ``my_view`` wrapped in ``cache_page``::
@ -587,7 +587,7 @@ Here's the same thing, with ``my_view`` wrapped in ``cache_page``::
from django.views.decorators.cache import cache_page from django.views.decorators.cache import cache_page
urlpatterns = [ urlpatterns = [
url(r'^foo/(\d{1,2})/$', cache_page(60 * 15)(my_view)), url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
] ]
.. templatetag:: cache .. templatetag:: cache

View File

@ -401,7 +401,7 @@ custom view::
urlpatterns = [ urlpatterns = [
#... #...
url(r'^authors/(?P<pk>\d+)/$', AuthorDetailView.as_view(), name='author-detail'), url(r'^authors/(?P<pk>[0-9]+)/$', AuthorDetailView.as_view(), name='author-detail'),
] ]
Then we'd write our new view -- ``get_object`` is the method that retrieves the Then we'd write our new view -- ``get_object`` is the method that retrieves the

View File

@ -147,8 +147,8 @@ Finally, we hook these new views into the URLconf::
urlpatterns = [ urlpatterns = [
# ... # ...
url(r'author/add/$', AuthorCreate.as_view(), name='author_add'), url(r'author/add/$', AuthorCreate.as_view(), name='author_add'),
url(r'author/(?P<pk>\d+)/$', AuthorUpdate.as_view(), name='author_update'), url(r'author/(?P<pk>[0-9]+)/$', AuthorUpdate.as_view(), name='author_update'),
url(r'author/(?P<pk>\d+)/delete/$', AuthorDelete.as_view(), name='author_delete'), url(r'author/(?P<pk>[0-9]+)/delete/$', AuthorDelete.as_view(), name='author_delete'),
] ]
.. note:: .. note::

View File

@ -261,7 +261,7 @@ We can hook this into our URLs easily enough::
urlpatterns = [ urlpatterns = [
#... #...
url(r'^author/(?P<pk>\d+)/interest/$', RecordInterest.as_view(), name='author-interest'), url(r'^author/(?P<pk>[0-9]+)/interest/$', RecordInterest.as_view(), name='author-interest'),
] ]
Note the ``pk`` named group, which Note the ``pk`` named group, which

View File

@ -76,9 +76,9 @@ Here's a sample URLconf::
urlpatterns = [ urlpatterns = [
url(r'^articles/2003/$', 'news.views.special_case_2003'), url(r'^articles/2003/$', 'news.views.special_case_2003'),
url(r'^articles/(\d{4})/$', 'news.views.year_archive'), url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'news.views.article_detail'),
] ]
Notes: Notes:
@ -133,9 +133,9 @@ Here's the above example URLconf, rewritten to use named groups::
urlpatterns = [ urlpatterns = [
url(r'^articles/2003/$', 'news.views.special_case_2003'), url(r'^articles/2003/$', 'news.views.special_case_2003'),
url(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'), url(r'^articles/(?P<year>[0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', 'news.views.article_detail'), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', 'news.views.article_detail'),
] ]
This accomplishes exactly the same thing as the previous example, with one This accomplishes exactly the same thing as the previous example, with one
@ -191,10 +191,10 @@ Each captured argument is sent to the view as a plain Python string, regardless
of what sort of match the regular expression makes. For example, in this of what sort of match the regular expression makes. For example, in this
URLconf line:: URLconf line::
url(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'), url(r'^articles/(?P<year>[0-9]{4})/$', 'news.views.year_archive'),
...the ``year`` argument to ``news.views.year_archive()`` will be a string, not ...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
an integer, even though the ``\d{4}`` will only match integer strings. an integer, even though the ``[0-9]{4}`` will only match integer strings.
Specifying defaults for view arguments Specifying defaults for view arguments
====================================== ======================================
@ -207,7 +207,7 @@ Here's an example URLconf and view::
urlpatterns = [ urlpatterns = [
url(r'^blog/$', 'blog.views.page'), url(r'^blog/$', 'blog.views.page'),
url(r'^blog/page(?P<num>\d+)/$', 'blog.views.page'), url(r'^blog/page(?P<num>[0-9]+)/$', 'blog.views.page'),
] ]
# View (in blog/views.py) # View (in blog/views.py)
@ -291,7 +291,7 @@ Another possibility is to include additional URL patterns by using a list of
from django.conf.urls import include, url from django.conf.urls import include, url
extra_patterns = [ extra_patterns = [
url(r'^reports/(?P<id>\d+)/$', 'credit.views.report'), url(r'^reports/(?P<id>[0-9]+)/$', 'credit.views.report'),
url(r'^charge/$', 'credit.views.charge'), url(r'^charge/$', 'credit.views.charge'),
] ]
@ -377,7 +377,7 @@ For example::
from . import views from . import views
urlpatterns = [ urlpatterns = [
url(r'^blog/(?P<year>\d{4})/$', views.year_archive, {'foo': 'bar'}), url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
] ]
In this example, for a request to ``/blog/2005/``, Django will call In this example, for a request to ``/blog/2005/``, Django will call
@ -558,7 +558,7 @@ Consider again this URLconf entry::
urlpatterns = [ urlpatterns = [
#... #...
url(r'^articles/(\d{4})/$', 'news.views.year_archive'), url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
#... #...
] ]
@ -610,8 +610,8 @@ view::
from mysite.views import archive from mysite.views import archive
urlpatterns = [ urlpatterns = [
url(r'^archive/(\d{4})/$', archive), url(r'^archive/([0-9]{4})/$', archive),
url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}), url(r'^archive-summary/([0-9]{4})/$', archive, {'summary': True}),
] ]
This is completely valid, but it leads to problems when you try to do reverse This is completely valid, but it leads to problems when you try to do reverse
@ -631,8 +631,8 @@ Here's the above example, rewritten to use named URL patterns::
from mysite.views import archive from mysite.views import archive
urlpatterns = [ urlpatterns = [
url(r'^archive/(\d{4})/$', archive, name="full-archive"), url(r'^archive/([0-9]{4})/$', archive, name="full-archive"),
url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, name="arch-summary"), url(r'^archive-summary/([0-9]{4})/$', archive, {'summary': True}, name="arch-summary"),
] ]
With these names in place (``full-archive`` and ``arch-summary``), you can With these names in place (``full-archive`` and ``arch-summary``), you can

View File

@ -4,5 +4,5 @@ from django.conf.urls import url
from django.contrib.contenttypes import views from django.contrib.contenttypes import views
urlpatterns = [ urlpatterns = [
url(r'^shortcut/(\d+)/(.*)/$', views.shortcut), url(r'^shortcut/([0-9]+)/(.*)/$', views.shortcut),
] ]

View File

@ -372,7 +372,7 @@ class TestFixtures(TestCase):
# Get rid of artifacts like '000000002' to eliminate the differences # Get rid of artifacts like '000000002' to eliminate the differences
# between different Python versions. # between different Python versions.
data = re.sub('0{6,}\d', '', data) data = re.sub('0{6,}[0-9]', '', data)
animals_data = sorted([ animals_data = sorted([
{"pk": 1, "model": "fixtures_regress.animal", "fields": {"count": 3, "weight": 1.2, "name": "Lion", "latin_name": "Panthera leo"}}, {"pk": 1, "model": "fixtures_regress.animal", "fields": {"count": 3, "weight": 1.2, "name": "Lion", "latin_name": "Panthera leo"}},

View File

@ -118,7 +118,7 @@ class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s', 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s',
'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s', 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s',
} }
f = RegexField(r'^\d+$', min_length=5, max_length=10, error_messages=e) f = RegexField(r'^[0-9]+$', min_length=5, max_length=10, error_messages=e)
self.assertFormErrors(['REQUIRED'], f.clean, '') self.assertFormErrors(['REQUIRED'], f.clean, '')
self.assertFormErrors(['INVALID'], f.clean, 'abcde') self.assertFormErrors(['INVALID'], f.clean, 'abcde')
self.assertFormErrors(['LENGTH 4, MIN LENGTH 5'], f.clean, '1234') self.assertFormErrors(['LENGTH 4, MIN LENGTH 5'], f.clean, '1234')

View File

@ -600,7 +600,7 @@ class FieldsTests(SimpleTestCase):
# RegexField ################################################################## # RegexField ##################################################################
def test_regexfield_1(self): def test_regexfield_1(self):
f = RegexField('^\d[A-F]\d$') f = RegexField('^[0-9][A-F][0-9]$')
self.assertEqual('2A2', f.clean('2A2')) self.assertEqual('2A2', f.clean('2A2'))
self.assertEqual('3F3', f.clean('3F3')) self.assertEqual('3F3', f.clean('3F3'))
self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '3G3') self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '3G3')
@ -609,14 +609,14 @@ class FieldsTests(SimpleTestCase):
self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, '') self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, '')
def test_regexfield_2(self): def test_regexfield_2(self):
f = RegexField('^\d[A-F]\d$', required=False) f = RegexField('^[0-9][A-F][0-9]$', required=False)
self.assertEqual('2A2', f.clean('2A2')) self.assertEqual('2A2', f.clean('2A2'))
self.assertEqual('3F3', f.clean('3F3')) self.assertEqual('3F3', f.clean('3F3'))
self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '3G3') self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '3G3')
self.assertEqual('', f.clean('')) self.assertEqual('', f.clean(''))
def test_regexfield_3(self): def test_regexfield_3(self):
f = RegexField(re.compile('^\d[A-F]\d$')) f = RegexField(re.compile('^[0-9][A-F][0-9]$'))
self.assertEqual('2A2', f.clean('2A2')) self.assertEqual('2A2', f.clean('2A2'))
self.assertEqual('3F3', f.clean('3F3')) self.assertEqual('3F3', f.clean('3F3'))
self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '3G3') self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '3G3')
@ -624,13 +624,13 @@ class FieldsTests(SimpleTestCase):
self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '2A2 ') self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, '2A2 ')
def test_regexfield_4(self): def test_regexfield_4(self):
f = RegexField('^\d\d\d\d$', error_message='Enter a four-digit number.') f = RegexField('^[0-9][0-9][0-9][0-9]$', error_message='Enter a four-digit number.')
self.assertEqual('1234', f.clean('1234')) self.assertEqual('1234', f.clean('1234'))
self.assertRaisesMessage(ValidationError, "'Enter a four-digit number.'", f.clean, '123') self.assertRaisesMessage(ValidationError, "'Enter a four-digit number.'", f.clean, '123')
self.assertRaisesMessage(ValidationError, "'Enter a four-digit number.'", f.clean, 'abcd') self.assertRaisesMessage(ValidationError, "'Enter a four-digit number.'", f.clean, 'abcd')
def test_regexfield_5(self): def test_regexfield_5(self):
f = RegexField('^\d+$', min_length=5, max_length=10) f = RegexField('^[0-9]+$', min_length=5, max_length=10)
self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 5 characters (it has 3).'", f.clean, '123') self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 5 characters (it has 3).'", f.clean, '123')
six.assertRaisesRegex(self, ValidationError, "'Ensure this value has at least 5 characters \(it has 3\)\.', u?'Enter a valid value\.'", f.clean, 'abc') six.assertRaisesRegex(self, ValidationError, "'Ensure this value has at least 5 characters \(it has 3\)\.', u?'Enter a valid value\.'", f.clean, 'abc')
self.assertEqual('12345', f.clean('12345')) self.assertEqual('12345', f.clean('12345'))
@ -648,7 +648,7 @@ class FieldsTests(SimpleTestCase):
def test_change_regex_after_init(self): def test_change_regex_after_init(self):
f = RegexField('^[a-z]+$') f = RegexField('^[a-z]+$')
f.regex = '^\d+$' f.regex = '^[0-9]+$'
self.assertEqual('1234', f.clean('1234')) self.assertEqual('1234', f.clean('1234'))
self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, 'abcd') self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, 'abcd')

View File

@ -1918,7 +1918,7 @@ class FormsTestCase(TestCase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
fields = ( fields = (
CharField(label='Country Code', validators=[ CharField(label='Country Code', validators=[
RegexValidator(r'^\+\d{1,2}$', message='Enter a valid country code.')]), RegexValidator(r'^\+[0-9]{1,2}$', message='Enter a valid country code.')]),
CharField(label='Phone Number'), CharField(label='Phone Number'),
CharField(label='Extension', error_messages={'incomplete': 'Enter an extension.'}), CharField(label='Extension', error_messages={'incomplete': 'Enter an extension.'}),
CharField(label='Label', required=False, help_text='E.g. home, work.'), CharField(label='Label', required=False, help_text='E.g. home, work.'),

View File

@ -4,5 +4,5 @@ from .views import ArticleFormView
urlpatterns = [ urlpatterns = [
url(r'^model_form/(?P<pk>\d+)/$', ArticleFormView.as_view(), name="article_form"), url(r'^model_form/(?P<pk>[0-9]+)/$', ArticleFormView.as_view(), name="article_form"),
] ]

View File

@ -23,27 +23,27 @@ urlpatterns = [
# DetailView # DetailView
url(r'^detail/obj/$', url(r'^detail/obj/$',
views.ObjectDetail.as_view()), views.ObjectDetail.as_view()),
url(r'^detail/artist/(?P<pk>\d+)/$', url(r'^detail/artist/(?P<pk>[0-9]+)/$',
views.ArtistDetail.as_view(), views.ArtistDetail.as_view(),
name="artist_detail"), name="artist_detail"),
url(r'^detail/author/(?P<pk>\d+)/$', url(r'^detail/author/(?P<pk>[0-9]+)/$',
views.AuthorDetail.as_view(), views.AuthorDetail.as_view(),
name="author_detail"), name="author_detail"),
url(r'^detail/author/bycustompk/(?P<foo>\d+)/$', url(r'^detail/author/bycustompk/(?P<foo>[0-9]+)/$',
views.AuthorDetail.as_view(pk_url_kwarg='foo')), views.AuthorDetail.as_view(pk_url_kwarg='foo')),
url(r'^detail/author/byslug/(?P<slug>[\w-]+)/$', url(r'^detail/author/byslug/(?P<slug>[\w-]+)/$',
views.AuthorDetail.as_view()), views.AuthorDetail.as_view()),
url(r'^detail/author/bycustomslug/(?P<foo>[\w-]+)/$', url(r'^detail/author/bycustomslug/(?P<foo>[\w-]+)/$',
views.AuthorDetail.as_view(slug_url_kwarg='foo')), views.AuthorDetail.as_view(slug_url_kwarg='foo')),
url(r'^detail/author/(?P<pk>\d+)/template_name_suffix/$', url(r'^detail/author/(?P<pk>[0-9]+)/template_name_suffix/$',
views.AuthorDetail.as_view(template_name_suffix='_view')), views.AuthorDetail.as_view(template_name_suffix='_view')),
url(r'^detail/author/(?P<pk>\d+)/template_name/$', url(r'^detail/author/(?P<pk>[0-9]+)/template_name/$',
views.AuthorDetail.as_view(template_name='generic_views/about.html')), views.AuthorDetail.as_view(template_name='generic_views/about.html')),
url(r'^detail/author/(?P<pk>\d+)/context_object_name/$', url(r'^detail/author/(?P<pk>[0-9]+)/context_object_name/$',
views.AuthorDetail.as_view(context_object_name='thingy')), views.AuthorDetail.as_view(context_object_name='thingy')),
url(r'^detail/author/(?P<pk>\d+)/dupe_context_object_name/$', url(r'^detail/author/(?P<pk>[0-9]+)/dupe_context_object_name/$',
views.AuthorDetail.as_view(context_object_name='object')), views.AuthorDetail.as_view(context_object_name='object')),
url(r'^detail/page/(?P<pk>\d+)/field/$', url(r'^detail/page/(?P<pk>[0-9]+)/field/$',
views.PageDetail.as_view()), views.PageDetail.as_view()),
url(r'^detail/author/invalid/url/$', url(r'^detail/author/invalid/url/$',
views.AuthorDetail.as_view()), views.AuthorDetail.as_view()),
@ -51,7 +51,7 @@ urlpatterns = [
views.AuthorDetail.as_view(queryset=None)), views.AuthorDetail.as_view(queryset=None)),
url(r'^detail/nonmodel/1/$', url(r'^detail/nonmodel/1/$',
views.NonModelDetail.as_view()), views.NonModelDetail.as_view()),
url(r'^detail/doesnotexist/(?P<pk>\d+)/$', url(r'^detail/doesnotexist/(?P<pk>[0-9]+)/$',
views.ObjectDoesNotExistDetail.as_view()), views.ObjectDoesNotExistDetail.as_view()),
# FormView # FormView
url(r'^contact/$', url(r'^contact/$',
@ -60,7 +60,7 @@ urlpatterns = [
# Create/UpdateView # Create/UpdateView
url(r'^edit/artists/create/$', url(r'^edit/artists/create/$',
views.ArtistCreate.as_view()), views.ArtistCreate.as_view()),
url(r'^edit/artists/(?P<pk>\d+)/update/$', url(r'^edit/artists/(?P<pk>[0-9]+)/update/$',
views.ArtistUpdate.as_view()), views.ArtistUpdate.as_view()),
url(r'^edit/authors/create/naive/$', url(r'^edit/authors/create/naive/$',
@ -76,27 +76,27 @@ urlpatterns = [
url(r'^edit/authors/create/special/$', url(r'^edit/authors/create/special/$',
views.SpecializedAuthorCreate.as_view()), views.SpecializedAuthorCreate.as_view()),
url(r'^edit/author/(?P<pk>\d+)/update/naive/$', url(r'^edit/author/(?P<pk>[0-9]+)/update/naive/$',
views.NaiveAuthorUpdate.as_view()), views.NaiveAuthorUpdate.as_view()),
url(r'^edit/author/(?P<pk>\d+)/update/redirect/$', url(r'^edit/author/(?P<pk>[0-9]+)/update/redirect/$',
views.NaiveAuthorUpdate.as_view(success_url='/edit/authors/create/')), views.NaiveAuthorUpdate.as_view(success_url='/edit/authors/create/')),
url(r'^edit/author/(?P<pk>\d+)/update/interpolate_redirect/$', url(r'^edit/author/(?P<pk>[0-9]+)/update/interpolate_redirect/$',
views.NaiveAuthorUpdate.as_view(success_url='/edit/author/%(id)d/update/')), views.NaiveAuthorUpdate.as_view(success_url='/edit/author/%(id)d/update/')),
url(r'^edit/author/(?P<pk>\d+)/update/$', url(r'^edit/author/(?P<pk>[0-9]+)/update/$',
views.AuthorUpdate.as_view()), views.AuthorUpdate.as_view()),
url(r'^edit/author/update/$', url(r'^edit/author/update/$',
views.OneAuthorUpdate.as_view()), views.OneAuthorUpdate.as_view()),
url(r'^edit/author/(?P<pk>\d+)/update/special/$', url(r'^edit/author/(?P<pk>[0-9]+)/update/special/$',
views.SpecializedAuthorUpdate.as_view()), views.SpecializedAuthorUpdate.as_view()),
url(r'^edit/author/(?P<pk>\d+)/delete/naive/$', url(r'^edit/author/(?P<pk>[0-9]+)/delete/naive/$',
views.NaiveAuthorDelete.as_view()), views.NaiveAuthorDelete.as_view()),
url(r'^edit/author/(?P<pk>\d+)/delete/redirect/$', url(r'^edit/author/(?P<pk>[0-9]+)/delete/redirect/$',
views.NaiveAuthorDelete.as_view(success_url='/edit/authors/create/')), views.NaiveAuthorDelete.as_view(success_url='/edit/authors/create/')),
url(r'^edit/author/(?P<pk>\d+)/delete/interpolate_redirect/$', url(r'^edit/author/(?P<pk>[0-9]+)/delete/interpolate_redirect/$',
views.NaiveAuthorDelete.as_view(success_url='/edit/authors/create/?deleted=%(id)s')), views.NaiveAuthorDelete.as_view(success_url='/edit/authors/create/?deleted=%(id)s')),
url(r'^edit/author/(?P<pk>\d+)/delete/$', url(r'^edit/author/(?P<pk>[0-9]+)/delete/$',
views.AuthorDelete.as_view()), views.AuthorDelete.as_view()),
url(r'^edit/author/(?P<pk>\d+)/delete/special/$', url(r'^edit/author/(?P<pk>[0-9]+)/delete/special/$',
views.SpecializedAuthorDelete.as_view()), views.SpecializedAuthorDelete.as_view()),
# ArchiveIndexView # ArchiveIndexView
@ -134,7 +134,7 @@ urlpatterns = [
name="authors_list"), name="authors_list"),
url(r'^list/authors/paginated/$', url(r'^list/authors/paginated/$',
views.AuthorList.as_view(paginate_by=30)), views.AuthorList.as_view(paginate_by=30)),
url(r'^list/authors/paginated/(?P<page>\d+)/$', url(r'^list/authors/paginated/(?P<page>[0-9]+)/$',
views.AuthorList.as_view(paginate_by=30)), views.AuthorList.as_view(paginate_by=30)),
url(r'^list/authors/paginated-orphaned/$', url(r'^list/authors/paginated-orphaned/$',
views.AuthorList.as_view(paginate_by=30, paginate_orphans=2)), views.AuthorList.as_view(paginate_by=30, paginate_orphans=2)),
@ -162,71 +162,71 @@ urlpatterns = [
# YearArchiveView # YearArchiveView
# Mixing keyword and positional captures below is intentional; the views # Mixing keyword and positional captures below is intentional; the views
# ought to be able to accept either. # ought to be able to accept either.
url(r'^dates/books/(?P<year>\d{4})/$', url(r'^dates/books/(?P<year>[0-9]{4})/$',
views.BookYearArchive.as_view()), views.BookYearArchive.as_view()),
url(r'^dates/books/(?P<year>\d{4})/make_object_list/$', url(r'^dates/books/(?P<year>[0-9]{4})/make_object_list/$',
views.BookYearArchive.as_view(make_object_list=True)), views.BookYearArchive.as_view(make_object_list=True)),
url(r'^dates/books/(?P<year>\d{4})/allow_empty/$', url(r'^dates/books/(?P<year>[0-9]{4})/allow_empty/$',
views.BookYearArchive.as_view(allow_empty=True)), views.BookYearArchive.as_view(allow_empty=True)),
url(r'^dates/books/(?P<year>\d{4})/allow_future/$', url(r'^dates/books/(?P<year>[0-9]{4})/allow_future/$',
views.BookYearArchive.as_view(allow_future=True)), views.BookYearArchive.as_view(allow_future=True)),
url(r'^dates/books/(?P<year>\d{4})/paginated/$', url(r'^dates/books/(?P<year>[0-9]{4})/paginated/$',
views.BookYearArchive.as_view(make_object_list=True, paginate_by=30)), views.BookYearArchive.as_view(make_object_list=True, paginate_by=30)),
url(r'^dates/books/no_year/$', url(r'^dates/books/no_year/$',
views.BookYearArchive.as_view()), views.BookYearArchive.as_view()),
url(r'^dates/books/(?P<year>\d{4})/reverse/$', url(r'^dates/books/(?P<year>[0-9]{4})/reverse/$',
views.BookYearArchive.as_view(queryset=models.Book.objects.order_by('pubdate'))), views.BookYearArchive.as_view(queryset=models.Book.objects.order_by('pubdate'))),
url(r'^dates/booksignings/(?P<year>\d{4})/$', url(r'^dates/booksignings/(?P<year>[0-9]{4})/$',
views.BookSigningYearArchive.as_view()), views.BookSigningYearArchive.as_view()),
# MonthArchiveView # MonthArchiveView
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/$',
views.BookMonthArchive.as_view()), views.BookMonthArchive.as_view()),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>\d{1,2})/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[0-9]{1,2})/$',
views.BookMonthArchive.as_view(month_format='%m')), views.BookMonthArchive.as_view(month_format='%m')),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/allow_empty/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/allow_empty/$',
views.BookMonthArchive.as_view(allow_empty=True)), views.BookMonthArchive.as_view(allow_empty=True)),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/allow_future/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/allow_future/$',
views.BookMonthArchive.as_view(allow_future=True)), views.BookMonthArchive.as_view(allow_future=True)),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/paginated/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/paginated/$',
views.BookMonthArchive.as_view(paginate_by=30)), views.BookMonthArchive.as_view(paginate_by=30)),
url(r'^dates/books/(?P<year>\d{4})/no_month/$', url(r'^dates/books/(?P<year>[0-9]{4})/no_month/$',
views.BookMonthArchive.as_view()), views.BookMonthArchive.as_view()),
url(r'^dates/booksignings/(?P<year>\d{4})/(?P<month>[a-z]{3})/$', url(r'^dates/booksignings/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/$',
views.BookSigningMonthArchive.as_view()), views.BookSigningMonthArchive.as_view()),
# WeekArchiveView # WeekArchiveView
url(r'^dates/books/(?P<year>\d{4})/week/(?P<week>\d{1,2})/$', url(r'^dates/books/(?P<year>[0-9]{4})/week/(?P<week>[0-9]{1,2})/$',
views.BookWeekArchive.as_view()), views.BookWeekArchive.as_view()),
url(r'^dates/books/(?P<year>\d{4})/week/(?P<week>\d{1,2})/allow_empty/$', url(r'^dates/books/(?P<year>[0-9]{4})/week/(?P<week>[0-9]{1,2})/allow_empty/$',
views.BookWeekArchive.as_view(allow_empty=True)), views.BookWeekArchive.as_view(allow_empty=True)),
url(r'^dates/books/(?P<year>\d{4})/week/(?P<week>\d{1,2})/allow_future/$', url(r'^dates/books/(?P<year>[0-9]{4})/week/(?P<week>[0-9]{1,2})/allow_future/$',
views.BookWeekArchive.as_view(allow_future=True)), views.BookWeekArchive.as_view(allow_future=True)),
url(r'^dates/books/(?P<year>\d{4})/week/(?P<week>\d{1,2})/paginated/$', url(r'^dates/books/(?P<year>[0-9]{4})/week/(?P<week>[0-9]{1,2})/paginated/$',
views.BookWeekArchive.as_view(paginate_by=30)), views.BookWeekArchive.as_view(paginate_by=30)),
url(r'^dates/books/(?P<year>\d{4})/week/no_week/$', url(r'^dates/books/(?P<year>[0-9]{4})/week/no_week/$',
views.BookWeekArchive.as_view()), views.BookWeekArchive.as_view()),
url(r'^dates/books/(?P<year>\d{4})/week/(?P<week>\d{1,2})/monday/$', url(r'^dates/books/(?P<year>[0-9]{4})/week/(?P<week>[0-9]{1,2})/monday/$',
views.BookWeekArchive.as_view(week_format='%W')), views.BookWeekArchive.as_view(week_format='%W')),
url(r'^dates/booksignings/(?P<year>\d{4})/week/(?P<week>\d{1,2})/$', url(r'^dates/booksignings/(?P<year>[0-9]{4})/week/(?P<week>[0-9]{1,2})/$',
views.BookSigningWeekArchive.as_view()), views.BookSigningWeekArchive.as_view()),
# DayArchiveView # DayArchiveView
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/$',
views.BookDayArchive.as_view()), views.BookDayArchive.as_view()),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[0-9]{1,2})/(?P<day>[0-9]{1,2})/$',
views.BookDayArchive.as_view(month_format='%m')), views.BookDayArchive.as_view(month_format='%m')),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/allow_empty/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/allow_empty/$',
views.BookDayArchive.as_view(allow_empty=True)), views.BookDayArchive.as_view(allow_empty=True)),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/allow_future/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/allow_future/$',
views.BookDayArchive.as_view(allow_future=True)), views.BookDayArchive.as_view(allow_future=True)),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/allow_empty_and_future/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/allow_empty_and_future/$',
views.BookDayArchive.as_view(allow_empty=True, allow_future=True)), views.BookDayArchive.as_view(allow_empty=True, allow_future=True)),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/paginated/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/paginated/$',
views.BookDayArchive.as_view(paginate_by=True)), views.BookDayArchive.as_view(paginate_by=True)),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/no_day/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/no_day/$',
views.BookDayArchive.as_view()), views.BookDayArchive.as_view()),
url(r'^dates/booksignings/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/$', url(r'^dates/booksignings/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/$',
views.BookSigningDayArchive.as_view()), views.BookSigningDayArchive.as_view()),
# TodayArchiveView # TodayArchiveView
@ -238,22 +238,22 @@ urlpatterns = [
views.BookSigningTodayArchive.as_view()), views.BookSigningTodayArchive.as_view()),
# DateDetailView # DateDetailView
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/(?P<pk>\d+)/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/(?P<pk>[0-9]+)/$',
views.BookDetail.as_view()), views.BookDetail.as_view()),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<pk>\d+)/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[0-9]{1,2})/(?P<day>[0-9]{1,2})/(?P<pk>[0-9]+)/$',
views.BookDetail.as_view(month_format='%m')), views.BookDetail.as_view(month_format='%m')),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/(?P<pk>\d+)/allow_future/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/(?P<pk>[0-9]+)/allow_future/$',
views.BookDetail.as_view(allow_future=True)), views.BookDetail.as_view(allow_future=True)),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/nopk/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/nopk/$',
views.BookDetail.as_view()), views.BookDetail.as_view()),
url(r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/byslug/(?P<slug>[\w-]+)/$', url(r'^dates/books/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/byslug/(?P<slug>[\w-]+)/$',
views.BookDetail.as_view()), views.BookDetail.as_view()),
url(r'^dates/books/get_object_custom_queryset/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/(?P<pk>\d+)/$', url(r'^dates/books/get_object_custom_queryset/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/(?P<pk>[0-9]+)/$',
views.BookDetailGetObjectCustomQueryset.as_view()), views.BookDetailGetObjectCustomQueryset.as_view()),
url(r'^dates/booksignings/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/(?P<pk>\d+)/$', url(r'^dates/booksignings/(?P<year>[0-9]{4})/(?P<month>[a-z]{3})/(?P<day>[0-9]{1,2})/(?P<pk>[0-9]+)/$',
views.BookSigningDetail.as_view()), views.BookSigningDetail.as_view()),
# Useful for testing redirects # Useful for testing redirects

View File

@ -1078,7 +1078,7 @@ class ModelFormsetTest(TestCase):
form = formset.forms[0] form = formset.forms[0]
now = form.fields['date_joined'].initial() now = form.fields['date_joined'].initial()
result = form.as_p() result = form.as_p()
result = re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?', '__DATETIME__', result) result = re.sub(r'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(?:\.[0-9]+)?', '__DATETIME__', result)
self.assertHTMLEqual(result, self.assertHTMLEqual(result,
'<p><label for="id_membership_set-0-date_joined">Date joined:</label> <input type="text" name="membership_set-0-date_joined" value="__DATETIME__" id="id_membership_set-0-date_joined" /><input type="hidden" name="initial-membership_set-0-date_joined" value="__DATETIME__" id="initial-membership_set-0-id_membership_set-0-date_joined" /></p>\n' '<p><label for="id_membership_set-0-date_joined">Date joined:</label> <input type="text" name="membership_set-0-date_joined" value="__DATETIME__" id="id_membership_set-0-date_joined" /><input type="hidden" name="initial-membership_set-0-date_joined" value="__DATETIME__" id="initial-membership_set-0-id_membership_set-0-date_joined" /></p>\n'
'<p><label for="id_membership_set-0-karma">Karma:</label> <input type="number" name="membership_set-0-karma" id="id_membership_set-0-karma" /><input type="hidden" name="membership_set-0-person" value="%d" id="id_membership_set-0-person" /><input type="hidden" name="membership_set-0-id" id="id_membership_set-0-id" /></p>' '<p><label for="id_membership_set-0-karma">Karma:</label> <input type="number" name="membership_set-0-karma" id="id_membership_set-0-karma" /><input type="hidden" name="membership_set-0-person" value="%d" id="id_membership_set-0-person" /><input type="hidden" name="membership_set-0-id" id="id_membership_set-0-id" /></p>'

View File

@ -8,10 +8,10 @@ from . import views
urlpatterns = [ urlpatterns = [
# Test urls for testing reverse lookups # Test urls for testing reverse lookups
url(r'^$', views.index), url(r'^$', views.index),
url(r'^client/([\d,]+)/$', views.client), url(r'^client/([0-9,]+)/$', views.client),
url(r'^client/(?P<id>\d+)/(?P<action>[^/]+)/$', views.client_action), url(r'^client/(?P<id>[0-9]+)/(?P<action>[^/]+)/$', views.client_action),
url(r'^client/(?P<client_id>\d+)/(?P<action>[^/]+)/$', views.client_action), url(r'^client/(?P<client_id>[0-9]+)/(?P<action>[^/]+)/$', views.client_action),
url(r'^named-client/(\d+)/$', views.client2, name="named.client"), url(r'^named-client/([0-9]+)/$', views.client2, name="named.client"),
# Unicode strings are permitted everywhere. # Unicode strings are permitted everywhere.
url(r'^Юникод/(\w+)/$', views.client2, name="метка_оператора"), url(r'^Юникод/(\w+)/$', views.client2, name="метка_оператора"),

View File

@ -4,6 +4,6 @@ from . import views
urlpatterns = [ urlpatterns = [
url(r'^test_utils/get_person/(\d+)/$', views.get_person), url(r'^test_utils/get_person/([0-9]+)/$', views.get_person),
url(r'^test_utils/no_template_used/$', views.no_template_used), url(r'^test_utils/no_template_used/$', views.no_template_used),
] ]

View File

@ -8,7 +8,7 @@ from .views import empty_view
urlpatterns = [ urlpatterns = [
url(r'^e-places/(\d+)/$', empty_view, name='extra-places'), url(r'^e-places/([0-9]+)/$', empty_view, name='extra-places'),
url(r'^e-people/(?P<name>\w+)/$', empty_view, name="extra-people"), url(r'^e-people/(?P<name>\w+)/$', empty_view, name="extra-people"),
url('', include('urlpatterns_reverse.included_urls2')), url('', include('urlpatterns_reverse.included_urls2')),
url(r'^prefix/(?P<prefix>\w+)/', include('urlpatterns_reverse.included_urls2')), url(r'^prefix/(?P<prefix>\w+)/', include('urlpatterns_reverse.included_urls2')),

View File

@ -6,6 +6,6 @@ from .views import empty_view
urlpatterns = [ urlpatterns = [
url(r'^$', empty_view, name="named-url3"), url(r'^$', empty_view, name="named-url3"),
url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url4"), url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url4"),
url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view), url(r'^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view),
url(r'^included/', include('urlpatterns_reverse.included_named_urls2')), url(r'^included/', include('urlpatterns_reverse.included_named_urls2')),
] ]

View File

@ -6,5 +6,5 @@ from .views import empty_view
urlpatterns = [ urlpatterns = [
url(r'^$', empty_view, name="named-url5"), url(r'^$', empty_view, name="named-url5"),
url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url6"), url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url6"),
url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view), url(r'^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view),
] ]

View File

@ -14,14 +14,14 @@ with warnings.catch_warnings(record=True) as w:
urlpatterns = patterns('urlpatterns_reverse.views', urlpatterns = patterns('urlpatterns_reverse.views',
url(r'^normal/$', 'empty_view', name='inc-normal-view'), url(r'^normal/$', 'empty_view', name='inc-normal-view'),
url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='inc-normal-view'), url(r'^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', 'empty_view', name='inc-normal-view'),
url(r'^\+\\\$\*/$', 'empty_view', name='inc-special-view'), url(r'^\+\\\$\*/$', 'empty_view', name='inc-special-view'),
url(r'^mixed_args/(\d+)/(?P<arg2>\d+)/$', 'empty_view', name='inc-mixed-args'), url(r'^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$', 'empty_view', name='inc-mixed-args'),
url(r'^no_kwargs/(\d+)/(\d+)/$', 'empty_view', name='inc-no-kwargs'), url(r'^no_kwargs/([0-9]+)/([0-9]+)/$', 'empty_view', name='inc-no-kwargs'),
url(r'^view_class/(?P<arg1>\d+)/(?P<arg2>\d+)/$', view_class_instance, name='inc-view-class'), url(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', view_class_instance, name='inc-view-class'),
(r'^test3/', include(testobj3.urls)), (r'^test3/', include(testobj3.urls)),
(r'^ns-included3/', include('urlpatterns_reverse.included_urls', namespace='inc-ns3')), (r'^ns-included3/', include('urlpatterns_reverse.included_urls', namespace='inc-ns3')),

View File

@ -4,5 +4,5 @@ from .views import empty_view
urlpatterns = [ urlpatterns = [
url(r'^inner-no-kwargs/(\d+)/', empty_view, name="inner-no-kwargs") url(r'^inner-no-kwargs/([0-9]+)/', empty_view, name="inner-no-kwargs")
] ]

View File

@ -6,5 +6,5 @@ from .views import empty_view
urlpatterns = [ urlpatterns = [
url(r'^$', empty_view, name="inner-nothing"), url(r'^$', empty_view, name="inner-nothing"),
url(r'^extra/(?P<extra>\w+)/$', empty_view, name="inner-extra"), url(r'^extra/(?P<extra>\w+)/$', empty_view, name="inner-extra"),
url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view, name="inner-disjunction"), url(r'^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view, name="inner-disjunction"),
] ]

View File

@ -6,6 +6,6 @@ from .views import empty_view
urlpatterns = [ urlpatterns = [
url(r'^$', empty_view, name="named-url1"), url(r'^$', empty_view, name="named-url1"),
url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url2"), url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url2"),
url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view), url(r'^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view),
url(r'^included/', include('urlpatterns_reverse.included_named_urls')), url(r'^included/', include('urlpatterns_reverse.included_named_urls')),
] ]

View File

@ -11,7 +11,7 @@ class URLObject(object):
def urls(self): def urls(self):
return ([ return ([
url(r'^inner/$', 'empty_view', name='urlobject-view'), url(r'^inner/$', 'empty_view', name='urlobject-view'),
url(r'^inner/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='urlobject-view'), url(r'^inner/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', 'empty_view', name='urlobject-view'),
url(r'^inner/\+\\\$\*/$', 'empty_view', name='urlobject-special-view'), url(r'^inner/\+\\\$\*/$', 'empty_view', name='urlobject-special-view'),
], self.app_name, self.namespace) ], self.app_name, self.namespace)
urls = property(urls) urls = property(urls)
@ -25,18 +25,18 @@ otherobj2 = URLObject('nodefault', 'other-ns2')
urlpatterns = [ urlpatterns = [
url(r'^normal/$', views.empty_view, name='normal-view'), url(r'^normal/$', views.empty_view, name='normal-view'),
url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', views.empty_view, name='normal-view'), url(r'^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='normal-view'),
url(r'^resolver_match/$', views.pass_resolver_match_view, name='test-resolver-match'), url(r'^resolver_match/$', views.pass_resolver_match_view, name='test-resolver-match'),
url(r'^\+\\\$\*/$', views.empty_view, name='special-view'), url(r'^\+\\\$\*/$', views.empty_view, name='special-view'),
url(r'^mixed_args/(\d+)/(?P<arg2>\d+)/$', views.empty_view, name='mixed-args'), url(r'^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='mixed-args'),
url(r'^no_kwargs/(\d+)/(\d+)/$', views.empty_view, name='no-kwargs'), url(r'^no_kwargs/([0-9]+)/([0-9]+)/$', views.empty_view, name='no-kwargs'),
url(r'^view_class/(?P<arg1>\d+)/(?P<arg2>\d+)/$', views.view_class_instance, name='view-class'), url(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.view_class_instance, name='view-class'),
url(r'^unnamed/normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', views.empty_view), url(r'^unnamed/normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view),
url(r'^unnamed/view_class/(?P<arg1>\d+)/(?P<arg2>\d+)/$', views.view_class_instance), url(r'^unnamed/view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.view_class_instance),
url(r'^test1/', include(testobj1.urls)), url(r'^test1/', include(testobj1.urls)),
url(r'^test2/', include(testobj2.urls)), url(r'^test2/', include(testobj2.urls)),
@ -49,9 +49,9 @@ urlpatterns = [
url(r'^ns-included2/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns2')), url(r'^ns-included2/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns2')),
url(r'^included/', include('urlpatterns_reverse.included_namespace_urls')), url(r'^included/', include('urlpatterns_reverse.included_namespace_urls')),
url(r'^inc(?P<outer>\d+)/', include('urlpatterns_reverse.included_urls', namespace='inc-ns5')), url(r'^inc(?P<outer>[0-9]+)/', include('urlpatterns_reverse.included_urls', namespace='inc-ns5')),
url(r'^ns-outer/(?P<outer>\d+)/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-outer')), url(r'^ns-outer/(?P<outer>[0-9]+)/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-outer')),
url(r'^\+\\\$\*/', include('urlpatterns_reverse.namespace_urls', namespace='special')), url(r'^\+\\\$\*/', include('urlpatterns_reverse.namespace_urls', namespace='special')),
] ]

View File

@ -14,15 +14,15 @@ with warnings.catch_warnings(record=True):
warnings.filterwarnings('ignore', module='django.conf.urls') warnings.filterwarnings('ignore', module='django.conf.urls')
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^places/(\d+)/$', empty_view, name='places'), url(r'^places/([0-9]+)/$', empty_view, name='places'),
url(r'^places?/$', empty_view, name="places?"), url(r'^places?/$', empty_view, name="places?"),
url(r'^places+/$', empty_view, name="places+"), url(r'^places+/$', empty_view, name="places+"),
url(r'^places*/$', empty_view, name="places*"), url(r'^places*/$', empty_view, name="places*"),
url(r'^(?:places/)?$', empty_view, name="places2?"), url(r'^(?:places/)?$', empty_view, name="places2?"),
url(r'^(?:places/)+$', empty_view, name="places2+"), url(r'^(?:places/)+$', empty_view, name="places2+"),
url(r'^(?:places/)*$', empty_view, name="places2*"), url(r'^(?:places/)*$', empty_view, name="places2*"),
url(r'^places/(\d+|[a-z_]+)/', empty_view, name="places3"), url(r'^places/([0-9]+|[a-z_]+)/', empty_view, name="places3"),
url(r'^places/(?P<id>\d+)/$', empty_view, name="places4"), url(r'^places/(?P<id>[0-9]+)/$', empty_view, name="places4"),
url(r'^people/(?P<name>\w+)/$', empty_view, name="people"), url(r'^people/(?P<name>\w+)/$', empty_view, name="people"),
url(r'^people/(?:name/)', empty_view, name="people2"), url(r'^people/(?:name/)', empty_view, name="people2"),
url(r'^people/(?:name/(\w+)/)?', empty_view, name="people2a"), url(r'^people/(?:name/(\w+)/)?', empty_view, name="people2a"),
@ -31,26 +31,26 @@ with warnings.catch_warnings(record=True):
url(r'^hardcoded/$', empty_view, name="hardcoded"), url(r'^hardcoded/$', empty_view, name="hardcoded"),
url(r'^hardcoded/doc\.pdf$', empty_view, name="hardcoded2"), url(r'^hardcoded/doc\.pdf$', empty_view, name="hardcoded2"),
url(r'^people/(?P<state>\w\w)/(?P<name>\w+)/$', empty_view, name="people3"), url(r'^people/(?P<state>\w\w)/(?P<name>\w+)/$', empty_view, name="people3"),
url(r'^people/(?P<state>\w\w)/(?P<name>\d)/$', empty_view, name="people4"), url(r'^people/(?P<state>\w\w)/(?P<name>[0-9])/$', empty_view, name="people4"),
url(r'^people/((?P<state>\w\w)/test)?/(\w+)/$', empty_view, name="people6"), url(r'^people/((?P<state>\w\w)/test)?/(\w+)/$', empty_view, name="people6"),
url(r'^character_set/[abcdef0-9]/$', empty_view, name="range"), url(r'^character_set/[abcdef0-9]/$', empty_view, name="range"),
url(r'^character_set/[\w]/$', empty_view, name="range2"), url(r'^character_set/[\w]/$', empty_view, name="range2"),
url(r'^price/\$(\d+)/$', empty_view, name="price"), url(r'^price/\$([0-9]+)/$', empty_view, name="price"),
url(r'^price/[$](\d+)/$', empty_view, name="price2"), url(r'^price/[$]([0-9]+)/$', empty_view, name="price2"),
url(r'^price/[\$](\d+)/$', empty_view, name="price3"), url(r'^price/[\$]([0-9]+)/$', empty_view, name="price3"),
url(r'^product/(?P<product>\w+)\+\(\$(?P<price>\d+(\.\d+)?)\)/$', empty_view, name="product"), url(r'^product/(?P<product>\w+)\+\(\$(?P<price>[0-9]+(\.[0-9]+)?)\)/$', empty_view, name="product"),
url(r'^headlines/(?P<year>\d+)\.(?P<month>\d+)\.(?P<day>\d+)/$', empty_view, name="headlines"), url(r'^headlines/(?P<year>[0-9]+)\.(?P<month>[0-9]+)\.(?P<day>[0-9]+)/$', empty_view, name="headlines"),
url(r'^windows_path/(?P<drive_name>[A-Z]):\\(?P<path>.+)/$', empty_view, name="windows"), url(r'^windows_path/(?P<drive_name>[A-Z]):\\(?P<path>.+)/$', empty_view, name="windows"),
url(r'^special_chars/(?P<chars>.+)/$', empty_view, name="special"), url(r'^special_chars/(?P<chars>.+)/$', empty_view, name="special"),
url(r'^(?P<name>.+)/\d+/$', empty_view, name="mixed"), url(r'^(?P<name>.+)/[0-9]+/$', empty_view, name="mixed"),
url(r'^repeats/a{1,2}/$', empty_view, name="repeats"), url(r'^repeats/a{1,2}/$', empty_view, name="repeats"),
url(r'^repeats/a{2,4}/$', empty_view, name="repeats2"), url(r'^repeats/a{2,4}/$', empty_view, name="repeats2"),
url(r'^repeats/a{2}/$', empty_view, name="repeats3"), url(r'^repeats/a{2}/$', empty_view, name="repeats3"),
url(r'^(?i)CaseInsensitive/(\w+)', empty_view, name="insensitive"), url(r'^(?i)CaseInsensitive/(\w+)', empty_view, name="insensitive"),
url(r'^test/1/?', empty_view, name="test"), url(r'^test/1/?', empty_view, name="test"),
url(r'^(?i)test/2/?$', empty_view, name="test2"), url(r'^(?i)test/2/?$', empty_view, name="test2"),
url(r'^outer/(?P<outer>\d+)/', include('urlpatterns_reverse.included_urls')), url(r'^outer/(?P<outer>[0-9]+)/', include('urlpatterns_reverse.included_urls')),
url(r'^outer-no-kwargs/(\d+)/', include('urlpatterns_reverse.included_no_kwargs_urls')), url(r'^outer-no-kwargs/([0-9]+)/', include('urlpatterns_reverse.included_no_kwargs_urls')),
url('', include('urlpatterns_reverse.extra_urls')), url('', include('urlpatterns_reverse.extra_urls')),
# This is non-reversible, but we shouldn't blow up when parsing it. # This is non-reversible, but we shouldn't blow up when parsing it.
@ -58,13 +58,13 @@ with warnings.catch_warnings(record=True):
# Regression views for #9038. See tests for more details # Regression views for #9038. See tests for more details
url(r'arg_view/$', 'kwargs_view'), url(r'arg_view/$', 'kwargs_view'),
url(r'arg_view/(?P<arg1>\d+)/$', 'kwargs_view'), url(r'arg_view/(?P<arg1>[0-9]+)/$', 'kwargs_view'),
url(r'absolute_arg_view/(?P<arg1>\d+)/$', absolute_kwargs_view), url(r'absolute_arg_view/(?P<arg1>[0-9]+)/$', absolute_kwargs_view),
url(r'absolute_arg_view/$', absolute_kwargs_view), url(r'absolute_arg_view/$', absolute_kwargs_view),
# Tests for #13154. Mixed syntax to test both ways of defining URLs. # Tests for #13154. Mixed syntax to test both ways of defining URLs.
url(r'defaults_view1/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 1}, name='defaults'), url(r'defaults_view1/(?P<arg1>[0-9]+)/', 'defaults_view', {'arg2': 1}, name='defaults'),
(r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'), (r'defaults_view2/(?P<arg1>[0-9]+)/', 'defaults_view', {'arg2': 2}, 'defaults'),
url('^includes/', include(other_patterns)), url('^includes/', include(other_patterns)),
) )

View File

@ -63,16 +63,16 @@ class JsTokensTest(TestCase):
(r"""/\[[^\]]+\]/gi""", [r"""regex /\[[^\]]+\]/gi"""]), (r"""/\[[^\]]+\]/gi""", [r"""regex /\[[^\]]+\]/gi"""]),
(""" ("""
rexl.re = { rexl.re = {
NAME: /^(?!\d)(?:\w)+|^"(?:[^"]|"")+"/, NAME: /^(?![0-9])(?:\w)+|^"(?:[^"]|"")+"/,
UNQUOTED_LITERAL: /^@(?:(?!\d)(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/, UNQUOTED_LITERAL: /^@(?:(?![0-9])(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/,
QUOTED_LITERAL: /^'(?:[^']|'')*'/, QUOTED_LITERAL: /^'(?:[^']|'')*'/,
NUMERIC_LITERAL: /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/, NUMERIC_LITERAL: /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/,
SYMBOL: /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/ SYMBOL: /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/
}; };
""", """,
["id rexl", "punct .", "id re", "punct =", "punct {", ["id rexl", "punct .", "id re", "punct =", "punct {",
"id NAME", "punct :", r"""regex /^(?!\d)(?:\w)+|^"(?:[^"]|"")+"/""", "punct ,", "id NAME", "punct :", r"""regex /^(?![0-9])(?:\w)+|^"(?:[^"]|"")+"/""", "punct ,",
"id UNQUOTED_LITERAL", "punct :", r"""regex /^@(?:(?!\d)(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/""", "punct ,", "id UNQUOTED_LITERAL", "punct :", r"""regex /^@(?:(?![0-9])(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/""", "punct ,",
"id QUOTED_LITERAL", "punct :", r"""regex /^'(?:[^']|'')*'/""", "punct ,", "id QUOTED_LITERAL", "punct :", r"""regex /^'(?:[^']|'')*'/""", "punct ,",
"id NUMERIC_LITERAL", "punct :", r"""regex /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/""", "punct ,", "id NUMERIC_LITERAL", "punct :", r"""regex /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/""", "punct ,",
"id SYMBOL", "punct :", r"""regex /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/""", "id SYMBOL", "punct :", r"""regex /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/""",
@ -81,8 +81,8 @@ class JsTokensTest(TestCase):
(""" ("""
rexl.re = { rexl.re = {
NAME: /^(?!\d)(?:\w)+|^"(?:[^"]|"")+"/, NAME: /^(?![0-9])(?:\w)+|^"(?:[^"]|"")+"/,
UNQUOTED_LITERAL: /^@(?:(?!\d)(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/, UNQUOTED_LITERAL: /^@(?:(?![0-9])(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/,
QUOTED_LITERAL: /^'(?:[^']|'')*'/, QUOTED_LITERAL: /^'(?:[^']|'')*'/,
NUMERIC_LITERAL: /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/, NUMERIC_LITERAL: /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/,
SYMBOL: /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/ SYMBOL: /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/
@ -90,8 +90,8 @@ class JsTokensTest(TestCase):
str = '"'; str = '"';
""", """,
["id rexl", "punct .", "id re", "punct =", "punct {", ["id rexl", "punct .", "id re", "punct =", "punct {",
"id NAME", "punct :", r"""regex /^(?!\d)(?:\w)+|^"(?:[^"]|"")+"/""", "punct ,", "id NAME", "punct :", r"""regex /^(?![0-9])(?:\w)+|^"(?:[^"]|"")+"/""", "punct ,",
"id UNQUOTED_LITERAL", "punct :", r"""regex /^@(?:(?!\d)(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/""", "punct ,", "id UNQUOTED_LITERAL", "punct :", r"""regex /^@(?:(?![0-9])(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/""", "punct ,",
"id QUOTED_LITERAL", "punct :", r"""regex /^'(?:[^']|'')*'/""", "punct ,", "id QUOTED_LITERAL", "punct :", r"""regex /^'(?:[^']|'')*'/""", "punct ,",
"id NUMERIC_LITERAL", "punct :", r"""regex /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/""", "punct ,", "id NUMERIC_LITERAL", "punct :", r"""regex /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/""", "punct ,",
"id SYMBOL", "punct :", r"""regex /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/""", "id SYMBOL", "punct :", r"""regex /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/""",

View File

@ -11,7 +11,7 @@ class VersionTests(TestCase):
# This will return a different result when it's run within or outside # This will return a different result when it's run within or outside
# of a git clone: 1.4.devYYYYMMDDHHMMSS or 1.4. # of a git clone: 1.4.devYYYYMMDDHHMMSS or 1.4.
ver_string = get_version(ver_tuple) ver_string = get_version(ver_tuple)
six.assertRegex(self, ver_string, r'1\.4(\.dev\d+)?') six.assertRegex(self, ver_string, r'1\.4(\.dev[0-9]+)?')
def test_releases(self): def test_releases(self):
tuples_to_strings = ( tuples_to_strings = (

View File

@ -94,7 +94,7 @@ class DebugViewTests(TestCase):
match = re.search(b'<div class="context" id="(?P<id>[^"]+)">', response.content) match = re.search(b'<div class="context" id="(?P<id>[^"]+)">', response.content)
self.assertFalse(match is None) self.assertFalse(match is None)
id_repr = match.group('id') id_repr = match.group('id')
self.assertFalse(re.search(b'[^c\d]', id_repr), self.assertFalse(re.search(b'[^c0-9]', id_repr),
"Numeric IDs in debug response HTML page shouldn't be localized (value: %s)." % id_repr) "Numeric IDs in debug response HTML page shouldn't be localized (value: %s)." % id_repr)
def test_template_exceptions(self): def test_template_exceptions(self):

View File

@ -72,8 +72,8 @@ urlpatterns = [
] ]
urlpatterns += [ urlpatterns += [
url(r'view_exception/(?P<n>\d+)/$', views.view_exception, name='view_exception'), url(r'view_exception/(?P<n>[0-9]+)/$', views.view_exception, name='view_exception'),
url(r'template_exception/(?P<n>\d+)/$', views.template_exception, name='template_exception'), url(r'template_exception/(?P<n>[0-9]+)/$', views.template_exception, name='template_exception'),
url(r'^raises_template_does_not_exist/(?P<path>.+)$', views.raises_template_does_not_exist, name='raises_template_does_not_exist'), url(r'^raises_template_does_not_exist/(?P<path>.+)$', views.raises_template_does_not_exist, name='raises_template_does_not_exist'),
url(r'^render_no_template/$', views.render_no_template, name='render_no_template'), url(r'^render_no_template/$', views.render_no_template, name='render_no_template'),
] ]