summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt7
-rw-r--r--docs/api/request.rst15
-rw-r--r--docs/narr/urldispatch.rst4
-rw-r--r--pyramid/request.py57
-rw-r--r--pyramid/tests/test_request.py56
-rw-r--r--pyramid/traversal.py8
6 files changed, 145 insertions, 2 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 15819b257..da4a8d324 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -13,6 +13,10 @@ Features
- New API method: ``pyramid.settings.asbool``.
+- New API methods for ``pyramid.request.Request``: ``model_url`` and
+ ``route_url``. These are simple passthroughs for their respective
+ functions in ``pyramid.url``.
+
Bug Fixes
---------
@@ -32,6 +36,9 @@ Documentation
- ZODB+traversal wiki (``wiki``) tutorial updated due to changes to
``pyramid_zodb`` paster template.
+- Documented the ``matchdict`` and ``matched_route`` attributes of the
+ request object in the Request API documentation.
+
1.0a2 (2010-11-09)
==================
diff --git a/docs/api/request.rst b/docs/api/request.rst
index 90dc2e26e..acd66ccf8 100644
--- a/docs/api/request.rst
+++ b/docs/api/request.rst
@@ -97,4 +97,19 @@
The template context for Pylons-style applications.
+ .. attribute:: matchdict
+
+ If a :term:`route` has matched during this request, this attribute will
+ be a dictionary containing the values matched by the URL pattern
+ associated with the route. If a route has not matched during this
+ request, the value of this attribute will be ``None``. See
+ :ref:`matchdict`.
+
+ .. attribute:: matched_route
+
+ If a :term:`route` has matched during this request, this attribute will
+ be an obect representing the route matched by the URL pattern
+ associated with the route. If a route has not matched during this
+ request, the value of this attribute will be ``None``. See
+ :ref:`matched_route`.
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index c1e4b28e3..4442be355 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -763,6 +763,8 @@ finding` and :term:`view lookup`.
.. index::
single: matchdict
+.. _matchdict:
+
The Matchdict
~~~~~~~~~~~~~
@@ -781,6 +783,8 @@ strings. The values will be Unicode objects.
.. index::
single: matched_route
+.. _matched_route:
+
The Matched Route
~~~~~~~~~~~~~~~~~
diff --git a/pyramid/request.py b/pyramid/request.py
index a5f3597b6..891c33fff 100644
--- a/pyramid/request.py
+++ b/pyramid/request.py
@@ -8,6 +8,8 @@ from pyramid.interfaces import ISessionFactory
from pyramid.exceptions import ConfigurationError
from pyramid.decorator import reify
+from pyramid.url import route_url
+from pyramid.url import model_url
class TemplateContext(object):
pass
@@ -163,6 +165,61 @@ class Request(WebobRequest):
'(see the Session Objects chapter of the documentation)')
return factory(self)
+ def route_url(self, route_name, *elements, **kw):
+ """ Return the URL for the route named ``route_name``, using
+ ``*elements`` and ``**kw`` as modifiers.
+
+ This is a convenience method. The result of calling
+ :meth:`pyramid.request.Request.route_url` is the same as calling
+ :func:`pyramid.url.route_url` with an explicit ``request``
+ parameter.
+
+ The :meth:`pyramid.request.Request.route_url` method calls the
+ :func:`pyramid.url.route_url` function using the Request object as
+ the ``request`` argument. The ``route_name``, ``*elements`` and
+ ``*kw`` arguments passed to :meth:`pyramid.request.Request.route_url`
+ are passed through to :func:`pyramid.url.route_url` unchanged and its
+ result is returned.
+
+ This call to :meth:`pyramid.request.Request.route_url`::
+
+ request.route_url('route_name')
+
+ Is completely equivalent to calling :func:`pyramid.url.route_url`
+ like this::
+
+ from pyramid.url import route_url
+ route_url('route_name', request)
+ """
+ return route_url(route_name, self, *elements, **kw)
+
+ def model_url(self, model, *elements, **kw):
+ """ Return the URL for the model object named ``model``, using
+ ``*elements`` and ``**kw`` as modifiers.
+
+ This is a convenience method. The result of calling
+ :meth:`pyramid.request.Request.model_url` is the same as calling
+ :func:`pyramid.url.model_url` with an explicit ``request`` parameter.
+
+ The :meth:`pyramid.request.Request.model_url` method calls the
+ :func:`pyramid.url.model_url` function using the Request object as
+ the ``request`` argument. The ``model``, ``*elements`` and ``*kw``
+ arguments passed to :meth:`pyramid.request.Request.model_url` are
+ passed through to :func:`pyramid.url.model_url` unchanged and its
+ result is returned.
+
+ This call to :meth:`pyramid.request.Request.model_url`::
+
+ request.route_url(mymodel)
+
+ Is completely equivalent to calling :func:`pyramid.url.model_url`
+ like this::
+
+ from pyramid.url import model_url
+ route_url(model, request)
+ """
+ return model_url(model, self, *elements, **kw)
+
# override default WebOb "environ['adhoc_attr']" mutation behavior
__getattr__ = object.__getattribute__
__setattr__ = object.__setattr__
diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py
index d9ddf5cde..d12b47642 100644
--- a/pyramid/tests/test_request.py
+++ b/pyramid/tests/test_request.py
@@ -16,6 +16,18 @@ class TestRequest(unittest.TestCase):
from pyramid.request import Request
return Request
+ def _registerContextURL(self):
+ from pyramid.interfaces import IContextURL
+ from zope.interface import Interface
+ class DummyContextURL(object):
+ def __init__(self, context, request):
+ pass
+ def __call__(self):
+ return 'http://example.com/context/'
+ self.config.registry.registerAdapter(
+ DummyContextURL, (Interface, Interface),
+ IContextURL)
+
def test_charset_defaults_to_utf8(self):
r = self._makeOne({'PATH_INFO':'/'})
self.assertEqual(r.charset, 'UTF-8')
@@ -229,6 +241,31 @@ class TestRequest(unittest.TestCase):
self.assertEqual(inst.called2, True)
self.assertEqual(inst.finished_callbacks, [])
+ def test_model_url(self):
+ self._registerContextURL()
+ inst = self._makeOne({})
+ root = DummyContext()
+ result = inst.model_url(root)
+ self.assertEqual(result, 'http://example.com/context/')
+
+ def test_route_url(self):
+ environ = {
+ 'PATH_INFO':'/',
+ 'SERVER_NAME':'example.com',
+ 'SERVER_PORT':'5432',
+ 'QUERY_STRING':'la=La%20Pe%C3%B1a',
+ 'wsgi.url_scheme':'http',
+ }
+ from pyramid.interfaces import IRoutesMapper
+ inst = self._makeOne(environ)
+ mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3'))
+ self.config.registry.registerUtility(mapper, IRoutesMapper)
+ result = inst.route_url('flub', 'extra1', 'extra2',
+ a=1, b=2, c=3, _query={'a':1},
+ _anchor=u"foo")
+ self.assertEqual(result,
+ 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo')
+
class Test_route_request_iface(unittest.TestCase):
def _callFUT(self, name):
from pyramid.request import route_request_iface
@@ -267,3 +304,22 @@ class DummyResponse:
self.headerlist = []
+class DummyContext:
+ pass
+
+class DummyRoutesMapper:
+ raise_exc = None
+ def __init__(self, route=None, raise_exc=False):
+ self.route = route
+
+ def get_route(self, route_name):
+ return self.route
+
+class DummyRoute:
+ pregenerator = None
+ def __init__(self, result='/1/2/3'):
+ self.result = result
+
+ def generate(self, kw):
+ self.kw = kw
+ return self.result
diff --git a/pyramid/traversal.py b/pyramid/traversal.py
index 515260ac2..e928c33f7 100644
--- a/pyramid/traversal.py
+++ b/pyramid/traversal.py
@@ -13,7 +13,6 @@ from pyramid.interfaces import VH_ROOT_KEY
from pyramid.encode import url_quote
from pyramid.exceptions import URLDecodeError
from pyramid.location import lineage
-from pyramid.request import Request
from pyramid.threadlocal import get_current_registry
def find_root(model):
@@ -277,7 +276,12 @@ def traverse(model, path):
model = find_root(model)
reg = get_current_registry()
- request_factory = reg.queryUtility(IRequestFactory, default=Request)
+
+ request_factory = reg.queryUtility(IRequestFactory)
+ if request_factory is None:
+ from pyramid.request import Request # avoid circdep
+ request_factory = Request
+
request = request_factory.blank(path)
request.registry = reg
traverser = reg.queryAdapter(model, ITraverser)