Commit 85c58dc5 by benjaoming

Merge branch 'master' of github.com:benjaoming/django-wiki

parents 3edd2867 2d7c9870
......@@ -45,15 +45,7 @@ def get_article(func=None, can_read=True, can_write=False, deleted_contents=Fals
path = kwargs.pop('path', None)
article_id = kwargs.pop('article_id', None)
articles = models.Article.objects
# TODO: Is this the way to do it?
# https://docs.djangoproject.com/en/1.4/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related
# This is not the way to go... optimize below statements to behave
# according to normal prefetching.
articles = articles.prefetch_related()
urlpath = None
# fetch by urlpath.path
......@@ -72,7 +64,8 @@ def get_article(func=None, can_read=True, can_write=False, deleted_contents=Fals
# TODO: Make a nice page
return HttpResponseNotFound("This article was not found, and neither was the parent. This page should look nicer.")
if urlpath.article:
article = get_object_or_404(articles, id=urlpath.article.id)
# urlpath is already smart about prefetching items on article (like current_revision), so we don't have to
article = urlpath.article
else:
# Be robust: Somehow article is gone but urlpath exists... clean up
return_url = reverse('wiki:get', kwargs={'path': urlpath.parent.path})
......@@ -82,6 +75,9 @@ def get_article(func=None, can_read=True, can_write=False, deleted_contents=Fals
# fetch by article.id
elif article_id:
#TODO We should try to grab the article form URLPath so the caching is good, and fall back to grabbing it from Article.objects if not
articles = models.Article.objects
article = get_object_or_404(articles, id=article_id)
try:
urlpath = models.URLPath.objects.get(articles__article=article)
......
......@@ -15,6 +15,8 @@ from wiki.core.exceptions import NoRootURL, MultipleRootURLs
from wiki.models.article import ArticleRevision, ArticleForObject, Article
from django.contrib.contenttypes.models import ContentType
URLPATH_PREFECTED_PROPERTIES = ["parent", "article__current_revision", "article__owner"]
class URLPath(MPTTModel):
"""
Strategy: Very few fields go here, as most has to be managed through an
......@@ -36,16 +38,29 @@ class URLPath(MPTTModel):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
@property
def cached_ancestors(self):
if not hasattr(self, "_cached_ancestors"):
self._cached_ancestors = list(self.get_ancestors().select_related(*URLPATH_PREFECTED_PROPERTIES) )
return self._cached_ancestors
@cached_ancestors.setter
def cached_ancestors(self, ancestors):
self._cached_ancestors = ancestors
@property
def path(self):
if not self.parent: return ""
if not hasattr(self, '_cachedpath'):
self._cachedpath = "/".join([obj.slug if obj.slug else "" for obj in self.get_ancestors(include_self=True).exclude(parent=None)]) + "/"
return self._cachedpath
ancestors = filter(lambda ancestor: ancestor.parent is not None, self.cached_ancestors)
slugs = [obj.slug if obj.slug else "" for obj in ancestors + [self] ]
return "/".join(slugs) + "/"
@classmethod
def root(cls):
site = Site.objects.get_current()
root_nodes = list(cls.objects.root_nodes().filter(site=site))
root_nodes = list(cls.objects.root_nodes().filter(site=site).select_related(*URLPATH_PREFECTED_PROPERTIES))
# We fetch the nodes as a list and use len(), not count() because we need
# to get the result out anyway. This only takes one sql query
no_paths = len(root_nodes)
......@@ -108,9 +123,13 @@ class URLPath(MPTTModel):
parent = cls.root()
for slug in slugs:
if settings.URL_CASE_SENSITIVE:
parent = parent.get_children().get(slug=slug)
child = parent.get_children().select_related(*URLPATH_PREFECTED_PROPERTIES).get(slug=slug)
child.cached_ancestors = parent.cached_ancestors + [parent]
parent = child
else:
parent = parent.get_children().get(slug__iexact=slug)
child = parent.get_children().select_related(*URLPATH_PREFECTED_PROPERTIES).get(slug__iexact=slug)
child.cached_ancestors = parent.cached_ancestors + [parent]
parent = child
level += 1
return parent
......
{% load i18n %}{% load url from future %}
{% if urlpath %}
<ul class="breadcrumb pull-left" class="">
{% for ancestor in urlpath.get_ancestors.all %}
{% for ancestor in urlpath.cached_ancestors %}
<span class="divider">/</span>
<li><a href="{% url 'wiki:get' path=ancestor.path %}">{{ ancestor.article.current_revision.title }}</a></li>
{% endfor %}
......
......@@ -12,9 +12,10 @@ class ArticleMixin(TemplateResponseMixin):
self.urlpath = kwargs.pop('urlpath', None)
self.article = article
self.children_slice = []
for child in self.article.get_children(max_num=settings.SHOW_MAX_CHILDREN+1,
articles__article__current_revision__deleted=False):
self.children_slice.append(child)
if settings.SHOW_MAX_CHILDREN > 0:
for child in self.article.get_children(max_num=settings.SHOW_MAX_CHILDREN+1,
articles__article__current_revision__deleted=False):
self.children_slice.append(child)
return super(ArticleMixin, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment