Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Reversing URL for a view with namespaces
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  8 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Ivan Sagalaev  
View profile  
 More options Oct 19, 5:34 pm
From: Ivan Sagalaev <man...@softwaremaniacs.org>
Date: Tue, 20 Oct 2009 01:34:51 +0400
Local: Mon, Oct 19 2009 5:34 pm
Subject: Reversing URL for a view with namespaces
Hello!

I've just stumbled upon a difficult to understand problem. I have an app
  that has an urlconf which is included in a project under a namespace:

     (r'^blog/', include('app.urls', namespace='blog')),

This namespace allows things like {% url blog:article ... %} which is
very nice. But reversing doesn't work when an app itself tries to
reverse its own urls having a callable at hand:

     reverse(views.article, args=[...])

It doesn't work because namespaced URLs are basically excluded from
resolver's reverse_dict and are put in their own resolvers under
namespace_dict. And reverse doesn't traverse those when it gets a callable.

On one hand I can see logic here: trying to reverse a namespaced URL
without specifying a namespace can lead to ambiguous results. But in
practice it means that one can break any third-party app that reverses
its URLs (using models.permalink, redirect, or reverse) just by
including its urlconf under a namespace. Because an app doesn't know its
namespace and then has no way of constructing a correct URL.

Am I missing something or is it an evil bug?


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Oct 20, 9:28 am
From: Russell Keith-Magee <freakboy3...@gmail.com>
Date: Tue, 20 Oct 2009 21:28:57 +0800
Local: Tues, Oct 20 2009 9:28 am
Subject: Re: Reversing URL for a view with namespaces
On Tue, Oct 20, 2009 at 5:34 AM, Ivan Sagalaev

A little bit of both.

On the 'missing something' front, reverse() now takes a 'current_app'
argument that gives context to the app lookup, which resolves the
ambiguity from the point of view of the reverse() function.

This solves the problem as long as applications have been built to
provide a namespace. However, this doesn't fully address the 'bug' you
describe - an application that hasn't been built to accept namespaces
will have problems if it is deployed in a namespace. contrib.comments
is one example of an application that you just can't deploy in a
namespace. It hasn't been written to allow this mode of deployment.

I'm not sure of the best solution to this problem, though.

This is at least partially a documentation problem. contrib.comments
simply isn't namespace-ready. The docs should probably say so, as
should the docs for any other app that provides an URLpattern that
needs be deployed.

However, it isn't *just* a documentation problem. We should probably
also provide some API-level protection to make sure that mistakes like
this aren't made by accident.

One possible approach would be to allow an application to mark its URL
patterns as "namespace safe"; include() would then raise an error if
the URLpattern that is included with a namespace doesn't have this
flag set (and/or raise an error if the urls are included without a
namespace and the flag *is* set).

The default would need to be 'not safe', so this would be a backwards
incompatible change for anyone that is currently using include with a
namespace on an app that doesn't have the flag set. This would be
slightly backwards incompatible for any existing uses that don't use
reverse() internally, or ship with sample templates that use {% url
%}.

However, I'm open to any other suggestions.

Yours,
Russ Magee %-)


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ivan Sagalaev  
View profile  
 More options Oct 20, 11:38 am
From: Ivan Sagalaev <man...@softwaremaniacs.org>
Date: Tue, 20 Oct 2009 19:38:18 +0400
Local: Tues, Oct 20 2009 11:38 am
Subject: Re: Reversing URL for a view with namespaces

Russell Keith-Magee wrote:
> On the 'missing something' front, reverse() now takes a 'current_app'
> argument that gives context to the app lookup, which resolves the
> ambiguity from the point of view of the reverse() function.

I saw this one. It doesn't work in this case exactly beacuse of this:

> This solves the problem as long as applications have been built to
> provide a namespace.

Which means an app knows its exact namespace.

> However, this doesn't fully address the 'bug' you
> describe - an application that hasn't been built to accept namespaces
> will have problems if it is deployed in a namespace.

There's important detail here.

One thing is a namespace-ignorant application that just uses reversing
the old way. I don't think we can fix it in any way except saying
somehow "don't install this app under a namespace" (as you suggested).

Another thing is an application that is being written now and that wants
to be namespace-aware. The problem is that while an application knows
that it can be included under a namespace it doesn't care under which
one exactly.

As far as I can tell it can be solved by keeping views in
resolver.reverse_dict as it was before namespaces were introduced as
well as in namespace_dict and app_dict. This way they could be found
both by specifying a name with or without namespace. However it doesn't
solve the problem when you have two instances of the same application.
For this we should have a way for an application to know which instance
of it is "current". Which means tying reversing to a request (right?).
At this point I didn't come up with anything more useful...


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Oct 31, 9:58 am
From: Russell Keith-Magee <freakboy3...@gmail.com>
Date: Sat, 31 Oct 2009 21:58:04 +0800
Local: Sat, Oct 31 2009 9:58 am
Subject: Re: Reversing URL for a view with namespaces
On Tue, Oct 20, 2009 at 11:38 PM, Ivan Sagalaev

Apologies for taking so long to get back to you on this.

For this last case - building a new app that you want to be namespace
aware - I think the Django admin already implements the model that
needs to be followed here. I can't think of any obvious way to allow
for an application to be 'namespaceless', as well as potentially one
of many in a namespace. Admin solves this by *always* requiring a
namespace - even if that's just the default application namespace.
Django's URL namespace lookup makes the simple case easy, (i.e.,
admin:named_url works, regardless of how you have deployed admin),
while allowing for multiple namespaces.

Personally, I don't think it's too onerous for us to say that
namespaces won't work unless you write an app to use them, and if you
write an app to use namespaces, then you have to use them when you
deploy.

All this leaves is catching (and preventing) the case of deploying
applications that aren't namespace aware inside a namespace. For
this... patches welcome :-)

Yours,
Russ Magee %-)


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ivan Sagalaev  
View profile  
 More options Nov 1, 3:52 pm
From: Ivan Sagalaev <man...@softwaremaniacs.org>
Date: Sun, 01 Nov 2009 23:52:53 +0300
Local: Sun, Nov 1 2009 3:52 pm
Subject: Re: Reversing URL for a view with namespaces

Russell Keith-Magee wrote:
> Apologies for taking so long to get back to you on this.

No problem :-) Have busy schedule myself :-)

> For this last case - building a new app that you want to be namespace
> aware - I think the Django admin already implements the model that
> needs to be followed here. I can't think of any obvious way to allow
> for an application to be 'namespaceless', as well as potentially one
> of many in a namespace. Admin solves this by *always* requiring a
> namespace - even if that's just the default application namespace.
> Django's URL namespace lookup makes the simple case easy, (i.e.,
> admin:named_url works, regardless of how you have deployed admin),
> while allowing for multiple namespaces.

Ahha! This is the catch I was missing. So in order for an app to place
itself generally in the "namespace-aware" category it should define a
function that will return a triple of (patterns, app_namespace,
instance_namespace) and document it as the only way of including itself
in a project's urlconf.

This makes sense now. Thanks!

> All this leaves is catching (and preventing) the case of deploying
> applications that aren't namespace aware inside a namespace. For
> this... patches welcome :-)

I'll try to look into it when someone reminds of a concept known to
other people as "free time"...

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ivan Sagalaev  
View profile  
 More options Nov 1, 4:44 pm
From: Ivan Sagalaev <man...@softwaremaniacs.org>
Date: Mon, 02 Nov 2009 00:44:49 +0300
Local: Sun, Nov 1 2009 4:44 pm
Subject: Re: Reversing URL for a view with namespaces

Ivan Sagalaev wrote:
> Ahha! This is the catch I was missing. So in order for an app to place
> itself generally in the "namespace-aware" category it should define a
> function that will return a triple of (patterns, app_namespace,
> instance_namespace) and document it as the only way of including itself
> in a project's urlconf.

> This makes sense now. Thanks!

And now with my newly found understanding I think I've found a small bug
(and may be a bigger one). Looks like this:

     include(myapp.urls.urls, app_name='custom_app_name')

is supposed to override whatever myapp provides as an app_name with
user-specified value 'custom_app_name', right?

But now it doesn't. Here's an excerpt from `include`:

     def include(arg, namespace=None, app_name=None):
         if isinstance(arg, tuple):
             # callable returning a namespace hint
             if namespace:
                 raise ImproperlyConfigured('Cannot override ...')
             urlconf_module, app_name, namespace = arg

A final `app_name` here is extracted from `arg` that an application
provides, not from `app_name` parameter. If this is really a bug I'll
happily make a patch (it's small).

A bigger (possible, provided I understand things right) bug is that
include explicitly forbids redefinition of `namespace` for an app that
*does* provide its own namespace. But as we just concluded a
namespace-ignorant app just can't be included under a namespace. So
specifying a namespace in include is a) not possible for "old" apps and
forbidden for "new" ones. How come?


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Nov 1, 8:11 pm
From: Russell Keith-Magee <freakboy3...@gmail.com>
Date: Mon, 2 Nov 2009 09:11:38 +0800
Local: Sun, Nov 1 2009 8:11 pm
Subject: Re: Reversing URL for a view with namespaces
On Mon, Nov 2, 2009 at 5:44 AM, Ivan Sagalaev

I think this falls on the fine lines between bug, badly documented
intentional limitation, and poorly thought out idea :-)

The documentation hints at this problem, if you read it the way I
originally intended - but I'll admit that it isn't clear:

"""
URL Namespaces can be specified in two ways.

Firstly, you can provide the application and instance namespace as
arguments to include() when you construct your URL patterns.
...
Secondly, you can include an object that contains embedded namespace data.
"""

My original intention was that this was an either-or situation - you
can provide namespace arguments to include, *or* you can provide an
embeddable object. What isn't clear from this is what happens if you
specify both. The 'embedded namespace overrides include()' that you
have noticed was intentional.

Of course, the flaw in this plan (which we have already covered) is
the extent to which the include() case is useful, given the difficulty
in finding the 'current' app. It should be possible to determine the
current application during the call to resolve(); the question is how
to return that current application data to the view in a useful form
-- and for an added degree of difficulty, do so without breaking
backwards compatibility on the resolve() API.

However, as noted previously, this requires someone to take the time
to sort of the issues. In the interim, I suppose I'd be advising
people to avoid using the include() technique to build
multi-deployable reusable apps, and use class-based reusable
applications instead.

Yours,
Russ Magee %-)


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tai Lee  
View profile  
 More options Nov 2, 5:17 pm
From: Tai Lee <real.hu...@mrmachine.net>
Date: Mon, 2 Nov 2009 14:17:34 -0800 (PST)
Local: Mon, Nov 2 2009 5:17 pm
Subject: Re: Reversing URL for a view with namespaces
Speaking of the ways in which a namespace can be specified or
provided, #11642 might be relevant here.

http://code.djangoproject.com/ticket/11642

It feels a little cumbersome to me to require users to either manually
specify a namespace or import a different object (than just the usual
urls module) which includes an embedded namespace. The attached patch
allows app authors to specify an "app_name" in their urls module which
will be used as the default app_name and namespace if none are
specified in the users urls module. The user can still specify their
own namespace or tuple with embedded namespace.

Cheers.
Tai.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google