stephenmcd/mezzanine — pull request #653 by rockymeza (2013-05-06 16:11:26+00:00)
Title: Preview the unpublished child of an unpublished parent

Hi @stephenmcd,

We wrote a custom preview view that calls the `mezzanine.pages.views.page` view with extra context. We're running into a problem where if you try to preview the unpublished child of an unpublished page. Here is the error and a slightly redacted traceback.

```
Traceback (most recent call last):
File "XXXXXXXX/lib/python2.6/site-packages/django/contrib/staticfiles/handlers.py", line 72, in __call__
return self.application(environ, start_response)
File "XXXXXXXX/lib/python2.6/site-packages/django/core/handlers/wsgi.py", line 255, in __call__
response = self.get_response(request)
File "XXXXXXXX/lib/python2.6/site-packages/django/core/handlers/base.py", line 178, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "XXXXXXXX/lib/python2.6/site-packages/django/core/handlers/base.py", line 217, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "XXXXXXXX/lib/python2.6/site-packages/django/core/handlers/base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "ZZZZZZZZ.py", line 62, in preview
return page_view(request, page.slug, extra_context=context)
File "YYYYYYYY/src/mezzanine/mezzanine/pages/views.py", line 81, in page
for parent in page.get_ascendants():
File "YYYYYYYY/src/mezzanine/mezzanine/pages/models.py", line 112, in get_ascendants
self._ascendants = pages[0]._ascendants
IndexError: list index out of range
```

Our custom view basically does this:
```python
page = get_object_or_404(CustomPage.objects.distinct(), ...)

context = {
'page': page,
...
}

return page_view(request, page.slug, extra_context=context)
```

I've overridden the get_ascendants method so that it doesn't throw that error, but I'm not sure what the side-effects of it are.

```python
class CustomPage(Page):
...
def get_ascendants(self, for_user=None):
if not self.parent_id:
return []
if not hasattr(self, "_ascendants"):
self._ascendants = []
if self.slug:
kwargs = {"for_user": for_user}
pages = Page.objects.with_ascendants_for_slug(self.slug,
**kwargs)
# this try catches that error, earlier we set self._ascendants to [] so there is no failure.
try:
self._ascendants = pages[0]._ascendants
except IndexError:
pass
return super(CustomPage, self).get_ascendants(for_user)
```

I think the problem lies with `Page.objects.with_ascendants_for_slug` limiting the ascendants to those that are published. I don't think this is necessary, because if we can't every look at a page that has a parent that isn't published on the front end, only in preview. Is that assumption right?

I would submit this as a pull request, but I don't know the side-effects of doing this or the assumptions behind `with_ascendants_for_slug`.