I'm using django-cms with apphooks to display book detail information. I need the page with the app hook to accept a slug that specifies which book to display.
I created a page called 'books' and added the apphook 'BookDetailApp'.
Here's what my books.cms_app file looks like:
class BooksApp (CMSApp):
name = _('Book Detail Page Application')
urls = ['books.urls']
apphook_pool.register(BooksApp)
Here's what my books.urls looks like:
urlpatterns = patterns('',
url(r'^(?P<slug>[\w\-]+)?', BookDetailView.as_view(), name='book_detail'),
)
And here's what my books.views file looks like:
class BookDetailView (DetailView):
model = Book
template_name = 'layouts/book-detail.html'
context_object_name = 'book'
This all works fine when I go directly to book detail page.
So going to http://localhost:8000/books/the-book-slug/
works exactly how I want to.
The problem is that I need be able to link to specific book detail pages from promos on the home page and none of the expected methods are working for me.
Using the page_url template tag from django-cms doesn't work because it only accepts one argument, so i can't provide the slug needed to determine which book to display:
<a href="{% page_url 'book_detail' %}">go</a>
As expected this only redirects to http://localhost:8000/books/
which throws an error because the required slug was not included.
So my next options are to use the url template tag or defining an get_absolute_url()
function on the model. Neither of these options work:
<a href="{% url book_detail book.slug %}">go</a>
def get_absolute_url(self):
return reverse('book_detail', args=[self.slug])
These both result in a NoReverseMatch: Reverse for 'book_detail' not found
error.
If I include the books.urls conf in my main url conf then it works. So it would appear that if the url is only being used by a cms apphook that it can't be reversed by django.
Including books.urls in my main urls seems like a dirty solution and I definitely do not want to hardcode the urls in the template or the get_absolute_url
function. Neither of those solutions seems very 'pythonesque'.
Any suggestions?
EDIT:
Reverse works only if I use the language namespace. According to documentation specifying language namespace shouldn't be required.
>>> reverse('en:book_detail', args=[book.slug])