Django: How do I override app-supplied urls in my project urlconf?

Chris Acheson picture Chris Acheson · Feb 16, 2012 · Viewed 9.3k times · Source

Let's say I have a Django project with three apps: foo, bar, and glue. I'm trying to follow reusable app conventions, so foo and bar are not dependent on (and don't know anything about) each other or on glue. Glue contains code to integrate the other two apps into the site.

Foo supplies a template tag that I want to include in one of the pages supplied by bar. The view for bar's page can be passed an alternate template. I make a template in glue that extends bar's template and includes the template tag from foo. In order to pass my new template to bar's view, I need to modify the urlconf entry that points to it.

My project urlconf looks something like this:

urlpatterns = patterns('',
  (r'^$', include('glue.urls')),
  (r'^foo/', include('foo.urls')),
  (r'^bar/', include('bar.urls')),
)

What's the most elegant way to pass the alternate template (or any other arbitrary view arguments, for that matter) to the view in bar? I don't want to modify bar's urlconf directly, as that would make it dependent on glue.

The only other method I can think of is to remove include('bar.urls'), copy the url patterns in bar's urlconf into the project urlconf, and modify the pattern I'm interested in. That approach violates the DRY principle though. Is there some other solution that I'm missing?

Answer

Chris Acheson picture Chris Acheson · Feb 18, 2012

Apparently duplicate URLs are allowed in the urlconf, and the first match listed will have priority:

urlpatterns = patterns('',
  (r'^$', include('glue.urls')),
  (r'^foo/', include('foo.urls')),

  # This will override the same URL in bar's urlconf:
  (r'^bar/stuff/$', 'glue.views.new_bar_stuff', {'arg': 'yarrgh'}, 'bar_stuff'),

  (r'^bar/', include('bar.urls')),
)