views:

794

answers:

3

I am doing something like this in myproject.myapp.urls:

from django.conf.urls.defaults import *

urlpatterns = patterns('myproject.myapp.views',
    (ur'^$', 'index'),
    (ur'^browse/$', 'browse'),
    (ur'^request/new/$', 'new_request'),
    (ur'^(?P<url_key>[-a-zA-Z0-9]+)/$', 'view1'),
    (ur'^(?P<url_key>[-a-zA-Z0-9]+)/asdf$', 'view2'),
    (ur'^(?P<url_key>[-a-zA-Z0-9]+)/qwer$', 'view3'),
    (ur'^(?P<url_key>[-a-zA-Z0-9]+)/zxcv$', 'view4'),
    (ur'^(?P<url_key>[-a-zA-Z0-9]+)/tyui$', 'view5'),
    (ur'^(?P<url_key>[-a-zA-Z0-9]+)/ghjk$', 'view6'),
    (ur'^(?P<url_key>[-a-zA-Z0-9]+)/bnm/more-looong-url/$', 'view7'),
    ...
)

I've tried to refactor above rules and define them in another file urls2.py like this:

(ur'^(?P<url_key>[-a-zA-Z0-9]+)/', include('myproject.myapp.urls2')),

but it seems to cause problems with unit tests including urlresolvers.

Is there better way to "refactor" the common part of regular expression (<url_key>) here?

+3  A: 

I'm no django expert, but wouldn't the 'view1' item match all of the other entries below it since it doesn't have a '$' at the end? So the other views wouldn't have a chance to get matched.

Dan Breen
+1 put the catch-all at the end or just include $ for every url.
Soviut
Ah, that's my mistake. I give you one vote. :)
Achimnol
A: 

Perhaps you could simplify the expressions in myproject.myapp.urls, and instead pass the information along as a parameter to a function in myproject.myapp.views?

I'm not sure what was going wrong in your tests, but generally speaking you'll be able to do more in myproject.myapp.views since you don't have to base it all on regex logic.

That function in myproject.myapp.views would be a switchboard that calls view1, view2, etc

anschauung
+1  A: 

I don't think you can do what you are trying to do with this line:

(ur'^(?P<url_key>[-a-zA-Z0-9]+)/', include('myproject.myapp.urls2'))

What view is the url_key parameter going to be passed to?

I'm not sure why you want to refactor the urlpatterns to begin with, but maybe this would be better?:

from django.conf.urls.defaults import *

URL_KEY = ur'^(?P<url_key>[-a-zA-Z0-9]+)'

urlpatterns = patterns('myproject.myapp.views',
    (ur'^$', 'index'),
    (ur'^browse/$', 'browse'),
    (ur'^request/new/$', 'new_request'),
    (URL_KEY+ur'/$', 'view1'),
    (URL_KEY+ur'/asdf$', 'view2'),
    (URL_KEY+ur'/qwer$', 'view3'),
    ...etc
)
Wogan
Well, I've fixed my test problems and adopted my original solution still, but this is a good suggestion. So I choose this as answer. :)
Achimnol