def get_complete_slug(self, language=None, hideroot=True): """Return the complete slug of this page by concatenating all parent's slugs. :param language: the wanted slug language.""" if not language: language = settings.PAGE_DEFAULT_LANGUAGE if self._complete_slug and language in self._complete_slug: return self._complete_slug[language] self._complete_slug = cache.get(self.PAGE_URL_KEY % (self.id)) if self._complete_slug is None: self._complete_slug = {} elif language in self._complete_slug: return self._complete_slug[language] if hideroot and settings.PAGE_HIDE_ROOT_SLUG and self.is_first_root(): url = '' else: url = '%s' % self.slug(language) key = self.ANCESTORS_KEY % self.id ancestors = cache.get(key, None) if ancestors is None: ancestors = self.get_ancestors(ascending=True) cache.set(key, ancestors) for ancestor in ancestors: url = ancestor.slug(language) + '/' + url self._complete_slug[language] = url cache.set(self.PAGE_URL_KEY % (self.id), self._complete_slug) return url
def invalidate(self): content = self.get_content('slug') for obj in content: cache_key = settings.PAGES_PAGE_CACHE_KEY + obj.language + ':' + obj.slug cache_key_version = settings.PAGES_PAGE_VERSION_KEY + obj.language + ':' + obj.slug cache_version = str(cache.get(cache_key_version)) if cache_version is None: cache.set(cache_key_version, 1, settings.PAGES_PAGE_CACHE_TIMEOUT) cache_version = 1 try: cache.incr(cache_key_version, 1) if settings.PAGES_CACHE_DELETE: # try delete cache for anonymous and authenticated users cache_key_yauth = cache_key + ':' + 'True' cache_key_nauth = cache_key + ':' + 'False' cache.delete(cache_key_yauth, version=cache_version) cache.delete(cache_key_nauth, version=cache_version) cache.delete(cache_key_yauth + 'content', version=cache_version) cache.delete(cache_key_nauth + 'content', version=cache_version) cache.delete(cache_key_yauth + 'ext_content', version=cache_version) cache.delete(cache_key_nauth + 'ext_content', version=cache_version) cache.delete(cache_key_yauth + 'redirect', version=cache_version) cache.delete(cache_key_nauth + 'redirect', version=cache_version) except ValueError: cache.set(cache_key_version, 1, settings.PAGES_PAGE_CACHE_TIMEOUT)
def published_children(self): """Return a :class:`QuerySet` of published children page""" key = self.PUB_CHILDREN_KEY % self.id children = cache.get(key, None) if children is None: children = Page.objects.filter_published(self.get_children()) cache.set(key, children) return children
def get_children(self): """Cache superclass result""" key = self.CHILDREN_KEY % self.id children = cache.get(key, None) if children is None: children = super(Page, self).get_children() cache.set(key, children) return children
def get_pages(self): """Cache the pages we have""" key = self.PAGES_KEY % self.id pages = cache.get(key, None) if pages is None: pages = Page.objects.filter(content__language=self.language, content__type='category', content__body=self.slug) cache.set(key, pages) return pages
def get_timestamp(slug, language): # try get page modification timestamp for http caching page_cache_version_key = settings.PAGES_PAGE_VERSION_KEY + language + ':' + slug timestamp_cache_key = settings.PAGES_PAGE_CACHE_KEY + language + ':' + slug + '_timestamp' cache_version = cache.get(page_cache_version_key) cache_version = 1 if cache_version is None else cache_version timestamp = cache.get(timestamp_cache_key, version=cache_version) if timestamp is None: timestamp = timezone.now().strftime('%Y-%m-%d %H:%M:%S') cache.set(timestamp_cache_key, timestamp, settings.PAGES_PAGE_CACHE_TIMEOUT, version=cache_version) return timestamp
def get_content(self, page, language, ctype, language_fallback=False): """Gets the latest content string for a particular page, language and placeholder. :param page: the concerned page object. :param language: the wanted language. :param ctype: the content type. :param language_fallback: fallback to another language if ``True``. """ if page is None: page = fake_page if " " in ctype: raise ValueError("Ctype cannot contain spaces.") if not language: language = settings.PAGE_DEFAULT_LANGUAGE frozen = int(bool(page.freeze_date)) key = self.PAGE_CONTENT_DICT_KEY % (page.id, ctype, frozen) # Spaces do not work with memcache key = key.replace(' ', '-') if page._content_dict is None: page._content_dict = dict() if page._content_dict.get(key, None): content_dict = page._content_dict.get(key) else: content_dict = cache.get(key) # fill a dict object for each language, that will create # P * L queries. # L == number of language, P == number of placeholder in the page. # Once generated the result is cached. if not content_dict: content_dict = {} for lang in settings.PAGE_LANGUAGES: try: content = self.get_content_object(page, lang[0], ctype) content_dict[lang[0]] = content.body except self.model.DoesNotExist: content_dict[lang[0]] = '' page._content_dict[key] = content_dict cache.set(key, content_dict) if language in content_dict and content_dict[language]: return content_dict[language] if language_fallback: for lang in settings.PAGE_LANGUAGES: if lang[0] in content_dict and content_dict[lang[0]]: return content_dict[lang[0]] return ''
def get_languages(self): """ Return a list of all used languages for this page. """ if self._languages: return self._languages self._languages = cache.get(self.PAGE_LANGUAGES_KEY % (self.id)) if self._languages is not None: return self._languages languages = [c["language"] for c in Content.objects.filter(page=self, type="slug").values("language")] # remove duplicates languages = list(set(languages)) languages.sort() cache.set(self.PAGE_LANGUAGES_KEY % (self.id), languages) self._languages = languages return languages
def get_languages(self): """ Return a list of all used languages for this page. """ if self._languages: return self._languages self._languages = cache.get(self.PAGE_LANGUAGES_KEY % (self.id)) if self._languages is not None: return self._languages languages = [c['language'] for c in Content.objects.filter(page=self, type="slug").values('language')] # remove duplicates languages = list(set(languages)) languages.sort() cache.set(self.PAGE_LANGUAGES_KEY % (self.id), languages) self._languages = languages return languages
def is_first_root(self): """Return ``True`` if this page is the first root pages.""" parent_cache_key = 'PARENT_FOR_%d' % self.id has_parent = cache.get(parent_cache_key, None) if has_parent is None: has_parent = not not self.parent cache.set(parent_cache_key, has_parent) if has_parent: return False if self._is_first_root is not None: return self._is_first_root first_root_id = cache.get('PAGE_FIRST_ROOT_ID') if first_root_id is not None: self._is_first_root = first_root_id == self.id return self._is_first_root try: first_root_id = Page.objects.root().values('id')[0]['id'] except IndexError: first_root_id = None if first_root_id is not None: cache.set('PAGE_FIRST_ROOT_ID', first_root_id) self._is_first_root = self.id == first_root_id return self._is_first_root
def get(self, request, **kwargs): is_authenticated = str(request.user.is_authenticated()) slug = kwargs.get(settings.PAGES_PAGE_SLUG_NAME, None) if slug is None: raise Http404 language = get_language() if settings.PAGES_USE_FALLBACK_LANGUAGE: use_language = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, None) use_fallback_language = request.COOKIES.get(settings.PAGES_FALLBACK_LANGUAGE_COOKIE_NAME, None) if use_fallback_language is not None and use_language != language: translation.activate(settings.PAGES_FALLBACK_LANGUAGE) if slug == settings.PAGES_HOME_PAGE_SLUG: response = HttpResponseRedirect('/') else: response = HttpResponseRedirect(reverse('pages:show', args=(slug,))) response.set_cookie(settings.LANGUAGE_COOKIE_NAME, settings.PAGES_FALLBACK_LANGUAGE) return response page_cache_key = settings.PAGES_PAGE_CACHE_KEY + language + ':' + slug + ':' + is_authenticated page_cache_version_key = settings.PAGES_PAGE_VERSION_KEY + language + ':' + slug # try get cached page cache_version = cache.get(page_cache_version_key) cache_version = 1 if cache_version is None else cache_version page = cache.get(page_cache_key, version=cache_version) if page: # check if login required if page.is_login_required and not request.user.is_authenticated(): return HttpResponseRedirect(settings.LOGIN_URL) # check user view permission if page.is_permission_required: if 'view_page' not in get_perms(request.user, page): if settings.PAGES_RAISE_403: raise PermissionDenied if settings.PAGES_RENDER_403: return render(request, settings.PAGES_TEMPLATE_403, {}) else: return HttpResponseForbidden() # try get pages content from cache page_redirect = cache.get(page_cache_key + 'redirect', version=cache_version) if page_redirect: if page_redirect['permanent']: return HttpResponsePermanentRedirect(page_redirect['url']) else: return HttpResponseRedirect(page_redirect['url']) page_content = cache.get(page_cache_key + 'content', version=cache_version) page_ext_content = cache.get(page_cache_key + 'ext_content', version=cache_version) else: # try request pages from db and store pages content in the cache slugs = PageSlugContent.objects.filter(slug=slug, language=language) if not slugs: if settings.PAGES_USE_FALLBACK_LANGUAGE: # try use fallback language for requested page if settings.PAGES_FALLBACK_LANGUAGE != language: slugs = PageSlugContent.objects.filter(slug=slug, language=settings.PAGES_FALLBACK_LANGUAGE) if slugs: translation.activate(settings.PAGES_FALLBACK_LANGUAGE) if slugs[0].slug == settings.PAGES_HOME_PAGE_SLUG: response = HttpResponseRedirect('/') else: response = HttpResponseRedirect(reverse('pages:show', args=(slugs[0].slug,))) response.set_cookie(settings.LANGUAGE_COOKIE_NAME, settings.PAGES_FALLBACK_LANGUAGE) response.set_cookie(settings.PAGES_FALLBACK_LANGUAGE_COOKIE_NAME, settings.PAGES_FALLBACK_LANGUAGE) return response raise Http404 slug = slugs[0] try: page = Page.objects.published().filter(pk=slug.page_id)[0] # cache pages content cache.set(page_cache_version_key, cache_version, settings.PAGES_PAGE_CACHE_TIMEOUT) cache.set(page_cache_key, page, settings.PAGES_PAGE_CACHE_TIMEOUT, version=cache_version) # check if login required if page.is_login_required and not request.user.is_authenticated(): return HttpResponseRedirect(settings.LOGIN_URL) # check user view permission if page.is_permission_required: if 'view_page' not in get_perms(request.user, page): if settings.PAGES_RAISE_403: raise PermissionDenied if settings.PAGES_RENDER_403: return render(request, settings.PAGES_TEMPLATE_403, {}) else: return HttpResponseForbidden() page_content = {} page_ext_content = {} page_redirect = {} # check if this pages has redirect try: redirect = PageRedirectContent.objects.get(page=page, language=language) page_redirect.update({ 'url': redirect.get_redirect_url(request), 'permanent': redirect.is_permanent }) cache.set(page_cache_key + 'redirect', page_redirect, settings.PAGES_PAGE_CACHE_TIMEOUT, version=cache_version) if page_redirect['permanent']: return HttpResponsePermanentRedirect(page_redirect['url']) else: return HttpResponseRedirect(page_redirect['url']) except PageRedirectContent.DoesNotExist: content_types = PageContentType.objects.filter(is_extended=False) for content_type in content_types: content_class = Page.get_content_class(content_type.type) content = content_class.objects.filter(page=page, language=language) if content: page_content.update({content_type.type: content}) if settings.PAGES_PAGE_USE_EXT_CONTENT_TYPES: ext_content_types = PageContentType.objects.extended() for content_type in ext_content_types: content_class = Page.get_content_class(content_type.type) if content_class: ext_content = content_class.objects.filter(page=page, language=language) if ext_content: page_ext_content.update({content_type.type: ext_content}) if page_content: cache.set(page_cache_key + 'content', page_content, settings.PAGES_PAGE_CACHE_TIMEOUT, version=cache_version) if page_ext_content: cache.set(page_cache_key + 'ext_content', page_ext_content, settings.PAGES_PAGE_CACHE_TIMEOUT, version=cache_version) except IndexError: raise Http404 context = self.get_context_data(**kwargs) context.update({ 'page': { 'page': page, 'slug': slug, 'content': page_content, 'ext_content': page_ext_content, 'cache_key': page_cache_key, 'cache_version': cache_version, 'timeout': settings.PAGES_PAGE_CACHE_TIMEOUT, } }) return render(request, page.get_template(), context)