Commit b37e140b by benjaoming

Move add_select_related so it isn't a class method but an instance method of the…

Move add_select_related so it isn't a class method but an instance method of the URLPath's querysets.
Fix error in permission lookup of users in a group.
parent 0a273eeb
...@@ -24,7 +24,7 @@ def get_extensions(article): ...@@ -24,7 +24,7 @@ def get_extensions(article):
url = reverse_lazy('wiki:get', kwargs={'path': urlpath.path}) url = reverse_lazy('wiki:get', kwargs={'path': urlpath.path})
except URLPath.DoesNotExist: except URLPath.DoesNotExist:
url = reverse_lazy('wiki:get', kwargs={'article_id': article.id}) url = reverse_lazy('wiki:get', kwargs={'article_id': article.id})
return ['extra', 'wikilinks(base_url=%s)' % url, 'codehilite(force_linenos=True)', 'toc'] return ['extra', 'wikilinks(base_url=%s)' % url, 'codehilite', 'toc']
MARKDOWN_EXTENSIONS = getattr( MARKDOWN_EXTENSIONS = getattr(
django_settings, django_settings,
'WIKI_MARKDOWN_EXTENSIONS', 'WIKI_MARKDOWN_EXTENSIONS',
......
...@@ -86,17 +86,16 @@ def get_article(func=None, can_read=True, can_write=False, deleted_contents=Fals ...@@ -86,17 +86,16 @@ def get_article(func=None, can_read=True, can_write=False, deleted_contents=Fals
else: else:
# TODO: Return something??
raise TypeError('You should specify either article_id or path') raise TypeError('You should specify either article_id or path')
if can_read and not article.can_read(request.user): if can_read and not article.can_read(user=request.user):
if request.user.is_anonymous(): if request.user.is_anonymous():
return redirect(django_settings.LOGIN_URL) return redirect(django_settings.LOGIN_URL)
else: else:
c = RequestContext(request, {'urlpath' : urlpath}) c = RequestContext(request, {'urlpath' : urlpath})
return HttpResponseForbidden(render_to_string("wiki/permission_denied.html", context_instance=c)) return HttpResponseForbidden(render_to_string("wiki/permission_denied.html", context_instance=c))
if can_write and not article.can_write(request.user): if can_write and not article.can_write(user=request.user):
if request.user.is_anonymous(): if request.user.is_anonymous():
return redirect(django_settings.LOGIN_URL) return redirect(django_settings.LOGIN_URL)
else: else:
......
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from mptt.managers import TreeManager
class ArticleQuerySet(QuerySet): class ArticleQuerySet(QuerySet):
...@@ -88,3 +89,17 @@ class ArticleFkManager(models.Manager): ...@@ -88,3 +89,17 @@ class ArticleFkManager(models.Manager):
def can_write(self, user): def can_write(self, user):
return self.get_query_set().can_write(user) return self.get_query_set().can_write(user)
class URLPathQuerySet(QuerySet):
def select_related_common(self):
return self.select_related("parent", "article__current_revision", "article__owner")
class URLPathManager(TreeManager):
def get_query_set(self):
"""Return a QuerySet with the same ordering as the TreeManager."""
return URLPathQuerySet(self.model, using=self._db).order_by(
self.tree_id_attr, self.left_attr)
def select_related_common(self):
return self.get_query_set().common_select_related()
...@@ -48,7 +48,7 @@ class Article(models.Model): ...@@ -48,7 +48,7 @@ class Article(models.Model):
if self.group_read: if self.group_read:
if self.group and group == self.group: if self.group and group == self.group:
return True return True
if self.group and user and user.groups.filter(group=group): if self.group and user and user.groups.filter(id=self.group.id):
return True return True
if user and user.has_perm('wiki_moderator'): if user and user.has_perm('wiki_moderator'):
return True return True
...@@ -63,7 +63,7 @@ class Article(models.Model): ...@@ -63,7 +63,7 @@ class Article(models.Model):
if self.group_write: if self.group_write:
if self.group and group == self.group: if self.group and group == self.group:
return True return True
if self.group and user and user.groups.filter(group=group): if self.group and user and user.groups.filter(id=self.group.id):
return True return True
if user and user.has_perm('wiki_moderator'): if user and user.has_perm('wiki_moderator'):
return True return True
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
...@@ -10,10 +11,10 @@ from django.utils.translation import ugettext_lazy as _, ugettext ...@@ -10,10 +11,10 @@ from django.utils.translation import ugettext_lazy as _, ugettext
from mptt.fields import TreeForeignKey from mptt.fields import TreeForeignKey
from mptt.models import MPTTModel from mptt.models import MPTTModel
from wiki import managers
from wiki.conf import settings from wiki.conf import settings
from wiki.core.exceptions import NoRootURL, MultipleRootURLs from wiki.core.exceptions import NoRootURL, MultipleRootURLs
from wiki.models.article import ArticleRevision, ArticleForObject, Article from wiki.models.article import ArticleRevision, ArticleForObject, Article
from django.contrib.contenttypes.models import ContentType
class URLPath(MPTTModel): class URLPath(MPTTModel):
""" """
...@@ -23,7 +24,9 @@ class URLPath(MPTTModel): ...@@ -23,7 +24,9 @@ class URLPath(MPTTModel):
# Tells django-wiki that permissions from a this object's article # Tells django-wiki that permissions from a this object's article
# should be inherited to children's articles. In this case, it's a static # should be inherited to children's articles. In this case, it's a static
# property.. but you can also use a BooleanField. # property.. but you can also use a BooleanField.
INHERIT_PERMISSIONS = True INHERIT_PERMISSIONS = True
objects = managers.URLPathManager()
articles = generic.GenericRelation(ArticleForObject) articles = generic.GenericRelation(ArticleForObject)
...@@ -47,7 +50,7 @@ class URLPath(MPTTModel): ...@@ -47,7 +50,7 @@ class URLPath(MPTTModel):
the database. the database.
""" """
if not hasattr(self, "_cached_ancestors"): if not hasattr(self, "_cached_ancestors"):
self._cached_ancestors = list(self.__class__.add_select_related(self.get_ancestors()) ) self._cached_ancestors = list(self.get_ancestors().select_related_common() )
return self._cached_ancestors return self._cached_ancestors
...@@ -65,17 +68,11 @@ class URLPath(MPTTModel): ...@@ -65,17 +68,11 @@ class URLPath(MPTTModel):
return "/".join(slugs) + "/" return "/".join(slugs) + "/"
@classmethod @classmethod
def add_select_related(cls, urlpath_queryset):
"""
Before using a queryset that retrieves urlpaths, run it through this first. It
adds a select_related with a list of foreign keys often retrieved from a urlpath.
"""
return urlpath_queryset.select_related("parent", "article__current_revision", "article__owner")
@classmethod
def root(cls): def root(cls):
site = Site.objects.get_current() site = Site.objects.get_current()
root_nodes = list( cls.add_select_related(cls.objects.root_nodes().filter(site=site)) ) root_nodes = list(
cls.objects.root_nodes().filter(site=site).select_related_common()
)
# We fetch the nodes as a list and use len(), not count() because we need # 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 # to get the result out anyway. This only takes one sql query
no_paths = len(root_nodes) no_paths = len(root_nodes)
...@@ -138,11 +135,11 @@ class URLPath(MPTTModel): ...@@ -138,11 +135,11 @@ class URLPath(MPTTModel):
parent = cls.root() parent = cls.root()
for slug in slugs: for slug in slugs:
if settings.URL_CASE_SENSITIVE: if settings.URL_CASE_SENSITIVE:
child = cls.add_select_related(parent.get_children()).get(slug=slug) child = parent.get_children().select_related_common().get(slug=slug)
child.cached_ancestors = parent.cached_ancestors + [parent] child.cached_ancestors = parent.cached_ancestors + [parent]
parent = child parent = child
else: else:
child = cls.add_select_related(parent.get_children()).get(slug__iexact=slug) child = parent.get_children().select_related_common().get(slug__iexact=slug)
child.cached_ancestors = parent.cached_ancestors + [parent] child.cached_ancestors = parent.cached_ancestors + [parent]
parent = child parent = child
level += 1 level += 1
......
...@@ -399,7 +399,7 @@ class List(ListView, ArticleMixin): ...@@ -399,7 +399,7 @@ class List(ListView, ArticleMixin):
paginate_by = 50 paginate_by = 50
def get_queryset(self): def get_queryset(self):
return models.URLPath.add_select_related(self.urlpath.get_children().order_by('slug')) return self.urlpath.get_children().order_by('slug').select_related_common()
def get_context_data(self, **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