mirror of
https://github.com/jazzband/django-dbtemplates.git
synced 2026-04-27 10:14:55 +00:00
Use the cache to remember which templates were not found in the database.
Also reverse the logic of the database lookup. First check if there is site-specific template in the database and only if that fails try to load the global template. This should cut down the number of database queries that need to be executed, especially in a loop that includes a given template that does not exist in the database. Signed-off-by: Stephan Peijnik <spe@anexia.at>
This commit is contained in:
parent
29cedc5271
commit
4a0ebb640e
3 changed files with 75 additions and 3 deletions
29
LICENSE
29
LICENSE
|
|
@ -28,6 +28,35 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Parts are (c) 2011 ANEXIA Internetdienstleistungs GmbH.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of the author nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
This software includes CodeMirror released under the following license:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
# Parts of this file are (c) 2011 ANEXIA Internetdienstleistungs GmbH.
|
||||
# For further copyrights and licensing information see the LICENSE
|
||||
# file that was distributed with this file.
|
||||
from django.contrib.sites.models import Site
|
||||
from django.template import TemplateDoesNotExist
|
||||
|
||||
from dbtemplates.conf import settings
|
||||
from dbtemplates.models import Template
|
||||
from dbtemplates.utils.cache import cache, get_cache_key, set_and_return
|
||||
from dbtemplates.utils.cache import get_cache_notfound_key
|
||||
from django.template.loader import BaseLoader
|
||||
|
||||
|
||||
|
|
@ -19,6 +23,18 @@ class Loader(BaseLoader):
|
|||
is_usable = True
|
||||
|
||||
def load_template_source(self, template_name, template_dirs=None):
|
||||
# The logic should work like this:
|
||||
# * Try to find the template in the cache. If found, return it.
|
||||
# * Now check the cache if a lookup for the given template
|
||||
# has failed lately and hand over control to the next template
|
||||
# loader waiting in line.
|
||||
# * If this still did not fail we first try to find a site-specific
|
||||
# template in the database.
|
||||
# * On a failure from our last attempt we try to load the global
|
||||
# template from the database.
|
||||
# * If all of the above steps have failed we generate a new key
|
||||
# in the cache indicating that queries failed, with the current
|
||||
# timestamp.
|
||||
site = Site.objects.get_current()
|
||||
display_name = 'dbtemplates:%s:%s:%s' % (settings.DATABASE_ENGINE,
|
||||
template_name, site.domain)
|
||||
|
|
@ -30,15 +46,32 @@ class Loader(BaseLoader):
|
|||
return backend_template, template_name
|
||||
except:
|
||||
pass
|
||||
|
||||
# Not found in cache, move on.
|
||||
cache_notfound_key = get_cache_notfound_key(template_name)
|
||||
if cache:
|
||||
try:
|
||||
notfound = cache.get(cache_notfound_key)
|
||||
if notfound:
|
||||
raise TemplateDoesNotExist(template_name)
|
||||
except:
|
||||
raise TemplateDoesNotExist(template_name)
|
||||
|
||||
# Not marked as not-found, move on...
|
||||
|
||||
try:
|
||||
template = Template.objects.get(name__exact=template_name)
|
||||
template = Template.objects.get(name__exact=template_name,
|
||||
sites__in=[site.id])
|
||||
return set_and_return(cache_key, template.content, display_name)
|
||||
except (Template.MultipleObjectsReturned, Template.DoesNotExist):
|
||||
except Template.DoesNotExist:
|
||||
try:
|
||||
template = Template.objects.get(
|
||||
name__exact=template_name, sites__in=[site.id])
|
||||
name__exact=template_name)
|
||||
return set_and_return(
|
||||
cache_key, template.content, display_name)
|
||||
except Template.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Mark as not-found in cache.
|
||||
cache.set(cache_notfound_key, '1')
|
||||
raise TemplateDoesNotExist(template_name)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# Parts of this file are (c) 2011 ANEXIA Internetdienstleistungs GmbH.
|
||||
# For further copyrights and licensing information see the LICENSE
|
||||
# file that was distributed with this file.
|
||||
from django.core.cache import get_cache
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
|
|
@ -15,6 +18,12 @@ def get_cache_key(name):
|
|||
current_site = Site.objects.get_current()
|
||||
return 'dbtemplates::%s::%s' % (name, current_site.pk)
|
||||
|
||||
def get_cache_notfound_key(name):
|
||||
return get_cache_key(name)+'::notfound'
|
||||
|
||||
def remove_notfound_key(instance):
|
||||
# Remove notfound key as soon as we save the template.
|
||||
cache.delete(get_cache_notfound_key(instance.name))
|
||||
|
||||
def set_and_return(cache_key, content, display_name):
|
||||
# Save in cache backend explicitly if manually deleted or invalidated
|
||||
|
|
@ -29,6 +38,7 @@ def add_template_to_cache(instance, **kwargs):
|
|||
in the database was added or changed.
|
||||
"""
|
||||
remove_cached_template(instance)
|
||||
remove_notfound_key(instance)
|
||||
cache.set(get_cache_key(instance.name), instance.content)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue