I have an online documentation Django app that has a base URI:
/path/to/docs/<DOMAIN>/
This allows you to see a list of docs within that DOMAIN. It uses the GCBV ListView. You can request the DetailView of a DOCNAME by using the following:
/path/to/docs/<DOMAIN>/<SLUG>/
where SLUG is pretty self explanatory and returns one record as a good slug should. There are child pages to these, with their own templates, along the lines of:
/path/to/docs/<DOMAIN>/<SLUG>/foo/
/path/to/docs/<DOMAIN>/<SLUG>/bar/
/path/to/docs/<DOMAIN>/<SLUG>/baz/
This is simple in the case of unversioned docs. However, in another DOMAIN (lets call it “federated”) I do have different versions of the DOCNAMEs available:
/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>/
and
/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>/foo/
/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>/bar/
/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>//baz/
In this case, if a user requests:
/path/to/docs/<DOMAIN>/<SLUG>/
I don’t want the user to be presented with a DetailView – I want them to be presented with a ListView of each of the VERSIONs that have documentation available:
Fantastic docs - Version 1 (/path/to/docs/federated/fantastic/1/)
Fantastic docs - Version 2 (/path/to/docs/federated/fantastic/2/)
Fantastic docs - Version 3 (/path/to/docs/federated/fantastic/3/)
I have done some pretty extensive reading on GCBV and subclassed many of them before in different apps, but I have the suspicion that I can’t have a single entry in urls.py to handle both these types of queries (Detail and ListView). Indeed, Django docs warns about mixing GCBV, especially w.r.t. get_context_data().
What I can do internal to my Mixin is look at the DOMAIN name, and on that basis, fork the request off to either a ListView (for versioned docs) or a DetailView (for non-versioned docs). I have searched all over the Django docs, and don’t see any examples of this. Can anyone help me out?
Note:
One thought does occur to me: In urls.py I could actually hard-code the DOMAIN name in the pattern. So instead of using the kwarg <domain>:
urlpatterns = patterns('',
url(r'^(?P<domain>[\w-]+)/(?P<slug>[\w-]+)/(?P<version>\d{1})/$', MyMixin.as_view(
queryset=Docs.objects.all()
),
)),
)
and using the domain kwarg as a logic determiner (to an if/else) in the view, I could do something like:
urlpatterns = patterns('',
url(r'^federated/(?P<slug>[\w-]+)/(?P<version>\d{1})/$', MyListViewMixin.as_view(
queryset=Docs.objects.all()
),
)),
url(r'^nonfederated/(?P<slug>[\w-]+)/$', MyDetailViewMixin.as_view(
queryset=Docs.objects.all()
),
)),
)
However, I don’t know how many documents DOMAINs are going to be versioned, and how many won’t. I need to be as generic as possible (excuse the pun). Thanks in advance.
Instead of mixing
ListViewandDetailViewinto one view (which would conceptually be a mess and difficult to maintain), I suggest designing all your views as if they were versioned and treating the unversioned ones as those with version1(or a similar unspecified version number).In the unfederated websites, the URL
/path/to/docs/<DOMAIN>/<SLUG>/would behave the same as visiting/path/to/docs/<DOMAIN>/1/<SLUG>/.In the federated websites, the URL
/path/to/docs/<DOMAIN>/<SLUG>/would present a list of the available versions (as aListView).You can implement the above behaviour with a view that does the following:
/path/to/docs/<DOMAIN>/<LATEST_VERSION>/<SLUG>/.The unfederated websites would simply be websites that only have one version of the docs. If this changes in the future then you can easily turn them into versioned docs as well.