Ticket #13635: 13635.diff

File 13635.diff, 6.5 KB (added by Ben Firshman, 14 years ago)
  • django/conf/urls/defaults.py

    diff --git a/django/conf/urls/defaults.py b/django/conf/urls/defaults.py
    index 3ab8bab..1f6c71f 100644
    a b def patterns(prefix, *args):  
    2828    return pattern_list
    2929
    3030def url(regex, view, kwargs=None, name=None, prefix=''):
    31     if isinstance(view, (list,tuple)):
     31    if isinstance(view, (list, tuple)):
    3232        # For include(...) processing.
    3333        urlconf_module, app_name, namespace = view
    3434        return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
  • django/core/urlresolvers.py

    diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
    index cad57a5..06e61ba 100644
    a b def get_mod_func(callback):  
    8181    return callback[:dot], callback[dot+1:]
    8282
    8383class RegexURLPattern(object):
     84    """
     85    Represents a single pattern in a URLconf.
     86    """
    8487    def __init__(self, regex, callback, default_args=None, name=None):
    8588        # regex is a string representing a regular expression.
    8689        # callback is either a string like 'foo.views.news.stories.story_detail'
    class RegexURLPattern(object):  
    119122                args = match.groups()
    120123            # In both cases, pass any extra_kwargs as **kwargs.
    121124            kwargs.update(self.default_args)
    122 
    123             return self.callback, args, kwargs
     125           
     126            # Instantiate classes each time the pattern is resolved
     127            callback = self.callback
     128            if isinstance(callback, type):
     129                callback = callback()
     130            return callback, args, kwargs
    124131
    125132    def _get_callback(self):
    126133        if self._callback is not None:
    class RegexURLPattern(object):  
    137144    callback = property(_get_callback)
    138145
    139146class RegexURLResolver(object):
     147    """
     148    Resolves and reverses URLs in a URLconf.
     149    """
    140150    def __init__(self, regex, urlconf_name, default_kwargs=None, app_name=None, namespace=None):
    141151        # regex is a string representing a regular expression.
    142152        # urlconf_name is a string representing the module containing URLconfs.
  • docs/topics/http/urls.txt

    diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt
    index 5a2980f..68c260d 100644
    a b The style you use is up to you.  
    631631Note that if you use this technique -- passing objects rather than strings --
    632632the view prefix (as explained in "The view prefix" above) will have no effect.
    633633
     634Passing classes as views
     635========================
     636
     637If you write your views as classes with a ``__call__()`` method, they may not be
     638thread safe if you pass them as instances to your URLconf. To ensure your
     639class-based views work correctly, you may pass a class which will be
     640instantiated on each request before being called::
     641
     642    urlpatterns = patterns('',
     643        (r'^contact/$', 'mysite.views.ContactView'),
     644    )
     645
     646You may also pass classes directly::
     647
     648    from mysite.views import ContactView
     649   
     650    urlpatterns = patterns('',
     651        (r'^contact/$', ContactView),
     652    )
     653
    634654.. _naming-url-patterns:
    635655
    636656Naming URL patterns
  • new file tests/regressiontests/urlpatterns/tests.py

    diff --git a/tests/regressiontests/urlpatterns/__init__.py b/tests/regressiontests/urlpatterns/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/urlpatterns/models.py b/tests/regressiontests/urlpatterns/models.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/urlpatterns/tests.py b/tests/regressiontests/urlpatterns/tests.py
    new file mode 100644
    index 0000000..4be7708
    - +  
     1from django.test import TestCase
     2
     3class TestResolver(TestCase):
     4    urls = 'regressiontests.urlpatterns.urls'
     5   
     6    def test_callable_view(self):
     7        response = self.client.get('/callable-view/')
     8        self.assertEqual(response.status_code, 200)
     9        self.assertEqual(response.content, 'callable_view')
     10   
     11    def test_string_view(self):
     12        response = self.client.get('/string-view/')
     13        self.assertEqual(response.status_code, 200)
     14        self.assertEqual(response.content, 'string_view')
     15   
     16    def test_new_instance_of_class_for_request(self):
     17        """
     18        When a class is passed as a view, ensure a new instance is created for
     19        each request.
     20        """
     21        response = self.client.get('/class/new-instance/')
     22        self.assertEqual(response.status_code, 200)
     23        self.assertEqual(response.content, 'OneTimeView')
     24        # This view will 404 if it is called a second time
     25        self.assertEqual(
     26            self.client.get('/class/new-instance/').status_code,
     27            200
     28        )
     29   
     30    def test_class_string_view(self):
     31        """
     32        Test class views can be passed as strings.
     33        """
     34        response = self.client.get('/class/string/')
     35        self.assertEqual(response.status_code, 200)
     36        self.assertEqual(response.content, 'StringView')
     37        # Ensure new instances are creating for string views too
     38        self.assertEqual(self.client.get('/class/string/').status_code, 200)
     39
  • new file tests/regressiontests/urlpatterns/urls.py

    diff --git a/tests/regressiontests/urlpatterns/urls.py b/tests/regressiontests/urlpatterns/urls.py
    new file mode 100644
    index 0000000..7e6e0db
    - +  
     1from django.conf.urls.defaults import *
     2from views import OneTimeView, callable_view
     3
     4urlpatterns = patterns('',
     5    url(r'^callable-view/$', callable_view),
     6    url(r'^string-view/$', 'regressiontests.urlpatterns.views.string_view'),
     7    url(r'^class/new-instance/$', OneTimeView),
     8    url(r'^class/string/$', 'regressiontests.urlpatterns.views.StringView'),
     9)
  • new file tests/regressiontests/urlpatterns/views.py

    diff --git a/tests/regressiontests/urlpatterns/views.py b/tests/regressiontests/urlpatterns/views.py
    new file mode 100644
    index 0000000..009824e
    - +  
     1from django.http import HttpResponse, Http404
     2
     3def callable_view(request):
     4    return HttpResponse('callable_view')
     5
     6def string_view(request):
     7    return HttpResponse('string_view')
     8
     9class OneTimeView(object):
     10    """
     11    A view that will 404 the second time it is called.
     12    """
     13   
     14    def __init__(self, *args, **kwargs):
     15        super(OneTimeView, self).__init__(*args, **kwargs)
     16        self.call_count = 0
     17   
     18    def __call__(self, request):
     19        if self.call_count > 0:
     20            raise Http404
     21        self.call_count += 1
     22        return HttpResponse(self.__class__.__name__)
     23
     24
     25class StringView(OneTimeView):
     26    pass
     27
Back to Top