reversing URLs

3 views
Skip to first unread message

Tim Valenta

unread,
Nov 24, 2009, 4:49:14 PM11/24/09
to Django users
Ever since day one, I've never had a firm grasp on what the heck URL
reversing can do. I understand the concepts involved, even the admin
namespacing that can occur with different admin sites, and I know that
the admin uses it regularly, but it seems like a crazy unpredictable
wildcard when I try to use it manually.

For instance, I'm trying to get the permalink decorator to work on a
"get_absolute_url()" method on my model, and I haven't got the
slightest clue what the hell it's doing. I'm getting errors about it
not being able to reverse it properly when I try to click on the admin-
generated "View on site ->" link from the change form. It says that
it can't find the view.

Basically, I've tried making the method refer to the view object, a
view name as a string (explicitly setting the name in the url conf),
an absolute module-path string ("myproject.myapp.views.my_view"), and
nothing works. It can never find it, even on a view with just a
single required keyword argument.

Is there any amazing breakdown on how to better wrap my brain around
how this url reversing thing works? I typically don't think of myself
as an idiot, but I really cannot even begin to feel like I can use it
proficiently.

Thanks in advance.

Karen Tracey

unread,
Nov 24, 2009, 10:52:39 PM11/24/09
to django...@googlegroups.com

I could point you to the doc (http://docs.djangoproject.com/en/dev/ref/models/instances/#the-permalink-decorator) but it sounds like you have already read that.

Alternatively I could try to explain the errors you are getting for the various things you have tried, but there aren't enough specifics here to do that.  Spell out the URLConf info, exactly what you have tried for the permalink/ger_abosolute_url code, and exactly what the error is, and someone can likely help.

I'm assuming you are getting NoReverseMatch and that's what you mean when you say "It says that it can't find the view"?  Those can be frustrating to debug, but they tend be right and mean exactly what they say: given the URLConf in place, there is no URL pattern in there that would result in the specified view being called with the noted parameters.  The trick then is to figure out why, since clearly you're expecting the URLConf to contain a pattern that would result in that view being called with those parameters....but without specifics on what you're trying it's hard to say what, exactly, is going wrong with what you are trying.

Karen

Tim Valenta

unread,
Nov 24, 2009, 11:20:41 PM11/24/09
to Django users
Thanks for the reply. Yes, I can give a bit more info on it.

So, for starters, my (abbreviated) main url conf looks like this:

urlpatterns = patterns('',
(r'^surveys/', include('servicetrac.surveys.urls')),
)

... which links over to the app's urls:

urlpatterns = patterns('servicetrac.surveys.views',
(r'^(?P<company_slug>[^/]+)/(?P<event_id>\d+)/web/take/(?
P<page>\d+)', 'take_survey', {
'name': 'this_is_a_name',
}),
(r'^(?P<company_slug>[^/]+)/(?P<event_id>\d+)/web/take',
'take_survey', {'page': 1}),
)

And the "take_survey" view signature:

take_survey(request, company_slug, event_id, page=1)

The default parameter for 'page' is a little redundant to what the
urls define, but it's self-documenting, in my mind.

So, up to this point, everything works as expected. Absolutely no
problems. The view works great, tested under both of the possible
urls to get there. But of course, I wanted to partake of the niceness
of having a "View on site ->" link on the admin page for the object,
so I began to implement the "get_absolute_url" method, employing the
decorator "models.permalink", as described previously:

# in my "Event" model
@models.permalink
def get_absolute_url(self):
return ('this_is_a_name', (), {
'company_slug': self.company.slug
'event_id': self.id
'page': 1
})


Now, my case doesn't seem too abnormal, but I find it difficult to
even track what happens after this. Using my wishful "View on site"
link yields the same result as calling the method in the manage.py
shell:

>>> event.get_aboslute_url()
Traceback (most recent call last):
................snip...............
NoReverseMatch: Reverse for 'this_is_a_name' with arguments '()' and
keyword arguments '{'event_id': 1L, 'company_slug': u'mycompany',
'page': 1}' not found.



Now, I've tried to simplify my task as much as possible, by naming the
view and everything. I thought maybe some funny-business was going on
with the optional parameter, but changes don't seem to make any
difference.

Any thoughts? I'm pretty sure there's no more info to give... the
full traceback stays in Django files, never directly touching my own,
and doesn't reveal anything more than I've posted.

Thanks,

Tim

On Nov 24, 8:52 pm, Karen Tracey <kmtra...@gmail.com> wrote:
> On Tue, Nov 24, 2009 at 4:49 PM, Tim Valenta <tonightslasts...@gmail.com>wrote:
>
>
>
>
>
> > Ever since day one, I've never had a firm grasp on what the heck URL
> > reversing can do.  I understand the concepts involved, even the admin
> > namespacing that can occur with different admin sites, and I know that
> > the admin uses it regularly, but it seems like a crazy unpredictable
> > wildcard when I try to use it manually.
>
> > For instance, I'm trying to get the permalink decorator to work on a
> > "get_absolute_url()" method on my model, and I haven't got the
> > slightest clue what the hell it's doing.  I'm getting errors about it
> > not being able to reverse it properly when I try to click on the admin-
> > generated "View on site ->" link from the change form.  It says that
> > it can't find the view.
>
> > Basically, I've tried making the method refer to the view object, a
> > view name as a string (explicitly setting the name in the url conf),
> > an absolute module-path string ("myproject.myapp.views.my_view"), and
> > nothing works.  It can never find it, even on a view with just a
> > single required keyword argument.
>
> > Is there any amazing breakdown on how to better wrap my brain around
> > how this url reversing thing works?  I typically don't think of myself
> > as an idiot, but I really cannot even begin to feel like I can use it
> > proficiently.
>
> I could point you to the doc (http://docs.djangoproject.com/en/dev/ref/models/instances/#the-permal...)

Karen Tracey

unread,
Nov 25, 2009, 12:33:16 AM11/25/09
to django...@googlegroups.com
On Tue, Nov 24, 2009 at 11:20 PM, Tim Valenta <tonights...@gmail.com> wrote:
Thanks for the reply.  Yes, I can give a bit more info on it.

So, for starters, my (abbreviated) main url conf looks like this:

   urlpatterns = patterns('',
       (r'^surveys/', include('servicetrac.surveys.urls')),
   )

... which links over to the app's urls:

   urlpatterns = patterns('servicetrac.surveys.views',
       (r'^(?P<company_slug>[^/]+)/(?P<event_id>\d+)/web/take/(?
P<page>\d+)', 'take_survey', {
           'name': 'this_is_a_name',
       }),

From what you have below it sounds like you are intending to name this url pattern 'this_is_a_name'.  But that is not what you have done here -- rather, you are passing an additional keyword parameter, name, with value 'this_is_a_name', to your take_survey view.  (Which is going to cause an error an any use of this pattern, since your view isn't expecting that keyword parameter.)

To name this pattern, you would either do:

      (r'^(?P<company_slug>[^/]+)/(?P<event_id>\d+)/web/take/(?P<page>\d+)', 'take_survey', {}, 'this_is_a_name'),

That is, specify the name as the 4th item in the tuple -- you must include an empty optional dictionary as the 3rd item since there is no way to specify a 4th item without a 3rd using the tuple format.  Or use the url function, and specify the name keyword argument to it:

    url(r'^(?P<company_slug>[^/]+)/(?P<event_id>\d+)/web/take/(?P<page>\d+)', 'take_survey'. name='this_is_a_name'),

 
       (r'^(?P<company_slug>[^/]+)/(?P<event_id>\d+)/web/take',
'take_survey', {'page': 1}),
   )

And the "take_survey" view signature:

   take_survey(request, company_slug, event_id, page=1)

The default parameter for 'page' is a little redundant to what the
urls define, but it's self-documenting, in my mind.

So, up to this point, everything works as expected.  Absolutely no
problems.  The view works great, tested under both of the possible
urls to get there.  But of course, I wanted to partake of the niceness
of having a "View on site ->" link on the admin page for the object,
so I began to implement the "get_absolute_url" method, employing the
decorator "models.permalink", as described previously:

   # in my "Event" model
   @models.permalink
   def get_absolute_url(self):
       return ('this_is_a_name', (), {
           'company_slug': self.company.slug
           'event_id': self.id
           'page': 1
       })



Once you get the naming working, I'd expect this to work,assuming you have commas on the end of a couple of those lines.  Alternatively, don't use the name but rather specify 'servicetrac.surveys.views.take_survey' -- that is the full name, including prefix from the patterns() call.

Karen

Tim Valenta

unread,
Nov 25, 2009, 12:39:35 AM11/25/09
to django...@googlegroups.com
Holy cow you're right.  That was an extreme case of needing another pair of eyes.  I thought I had tested the view after using that syntax, but I must not have tested the right scenario.

Many thanks. I will check it out in the morning :)

Tim

Sent from my iPod; pardon any typos and poor grammar!

--

You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Tim Valenta

unread,
Nov 25, 2009, 11:23:35 AM11/25/09
to Django users
I thank you, Karen, for the pointer on that user-issue I had :)

For the sake of putting this information on the same thread, I wanted
to make note of the following:

I had not realized that models.permalink depends on the `sites`
application. I had removed this for the sake of simplifying the admin
options as much as possible for those who would use it. But, having
removed that app a long time ago, I now get a different exception.

'servicetrac.django_site' doesn't exist

A patch to the docs on permalink might be worthwhile, to point out
simply that this dependency. ... or... is it a "reverse" method
dependency? Given my confusion over how to use it in the past, I've
never really checked specifically to see if `sites` was required for
reversing to begin with. Either way, I'm not seeing docs which state
this.

I'll correct the issue, now that I'm on the right track, but is there
anything else that you could add about the dependency I've noted?

Thanks,

Tim

On Nov 24, 10:39 pm, Tim Valenta <tonightslasts...@gmail.com> wrote:
> Holy cow you're right.  That was an extreme case of needing another pair of
> eyes.  I thought I had tested the view after using that syntax, but I must
> not have tested the right scenario.
>
> Many thanks. I will check it out in the morning :)
>
> Tim
>
> Sent from my iPod; pardon any typos and poor grammar!
>
> On Nov 24, 2009, at 10:33 PM, Karen Tracey <kmtra...@gmail.com> wrote:

Karen Tracey

unread,
Nov 25, 2009, 11:33:51 PM11/25/09
to django...@googlegroups.com
On Wed, Nov 25, 2009 at 11:23 AM, Tim Valenta <tonights...@gmail.com> wrote:

I had not realized that models.permalink depends on the `sites`
application.  I had removed this for the sake of simplifying the admin
options as much as possible for those who would use it.  But, having
removed that app a long time ago, I now get a different exception.

   'servicetrac.django_site' doesn't exist


It's not permalink that requires sites, it's the "view on site" function.  There's a ticket open on that:

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

Karen
Reply all
Reply to author
Forward
0 new messages