def test_backend_names_must_be_unique(self): msg = ( "Template engine aliases aren't unique, duplicates: django. Set " "a unique NAME for each engine in settings.TEMPLATES." ) with self.assertRaisesMessage(ImproperlyConfigured, msg): engines.all()
def test_backend_import_error(self): """ Failing to import a backend keeps raising the original import error (#24265). """ with self.assertRaisesRegex(ImportError, "No module named '?raise"): engines.all() with self.assertRaisesRegex(ImportError, "No module named '?raise"): engines.all()
def test_backend_import_error(self): """ Failing to import a backend keeps raising the original import error. Regression test for #24265. """ with self.assertRaises(ImportError): engines.all() with self.assertRaises(ImportError): engines.all()
def test_backend_improperly_configured(self): """ Failing to initialize a backend keeps raising the original exception (#24265). """ msg = 'app_dirs must not be set when loaders is defined.' with self.assertRaisesMessage(ImproperlyConfigured, msg): engines.all() with self.assertRaisesMessage(ImproperlyConfigured, msg): engines.all()
def test_backend_improperly_configured(self): """ Failing to initialize a backend keeps raising the original exception. Regression test for #24265. """ with self.assertRaises(ImproperlyConfigured): engines.all() with self.assertRaises(ImproperlyConfigured): engines.all()
def test_django_session_csrf(self): """test that we're correctly using session CSRF tokens (as opposed to cookies) for all template engines""" import session_csrf import django.template.context_processors for engine in engines.all(): # ensure that session_csrf comes after django.template... processors = engine.engine.template_context_processors self.assertEqual( processors.count(django.template.context_processors.csrf), 1) self.assertEqual( processors.count(session_csrf.context_processor), 1) self.assertLess( processors.index(django.template.context_processors.csrf), processors.index(session_csrf.context_processor), msg='sessions_csrf needs to be after django default') self.assertIn( 'session_csrf.CsrfMiddleware', settings.MIDDLEWARE_CLASSES) self.assertNotIn( 'django.middleware.csrf.CsrfViewMiddleware', settings.MIDDLEWARE_CLASSES) self.assertIn('session_csrf', settings.INSTALLED_APPS)
def get_default(): """ When only one DjangoTemplates backend is configured, returns it. Raises ImproperlyConfigured otherwise. This is required for preserving historical APIs that rely on a globally available, implicitly configured engine such as: >>> from django.template import Context, Template >>> template = Template("Hello {{ name }}!") >>> context = Context({'name': "world"}) >>> template.render(context) 'Hello world!' """ # Since Engine is imported in django.template and since # DjangoTemplates is a wrapper around this Engine class, # local imports are required to avoid import loops. from django.template import engines from django.template.backends.django import DjangoTemplates django_engines = [engine for engine in engines.all() if isinstance(engine, DjangoTemplates)] if len(django_engines) == 1: # Unwrap the Engine instance inside DjangoTemplates return django_engines[0].engine elif len(django_engines) == 0: raise ImproperlyConfigured( "No DjangoTemplates backend is configured.") else: raise ImproperlyConfigured( "Several DjangoTemplates backends are configured. " "You must select one explicitly.")
def test_clear_template_caches(self): """Testing clear_template_caches""" # Load a template to populate the cache. get_template('avatars/avatar.html') if engines is not None: # Django >= 1.8 template_loader = engines.all()[0].engine.template_loaders[0] else: # Django >= 1.6, <= 1.7 # # We need to import this here in order to get the latest copy # of this variable. from django.template.loader import template_source_loaders template_loader = template_source_loaders[0] self.assertTrue(isinstance(template_loader, CachedLoader)) if hasattr(template_loader, 'get_template'): self.assertNotEqual(template_loader.get_template_cache, {}) else: self.assertNotEqual(template_loader.template_cache, {}) clear_template_caches() if hasattr(template_loader, 'get_template'): self.assertEqual(template_loader.get_template_cache, {}) else: self.assertEqual(template_loader.template_cache, {})
def get_loaders(self): template_source_loaders = [] for e in engines.all(): if hasattr(e, 'engine'): template_source_loaders.extend( e.engine.get_template_loaders(e.engine.loaders)) loaders = [] # If template loader is CachedTemplateLoader, return the loaders # that it wraps around. So if we have # TEMPLATE_LOADERS = ( # ('django.template.loaders.cached.Loader', ( # 'django.template.loaders.filesystem.Loader', # 'django.template.loaders.app_directories.Loader', # )), # ) # The loaders will return django.template.loaders.filesystem.Loader # and django.template.loaders.app_directories.Loader # The cached Loader and similar ones include a 'loaders' attribute # so we look for that. for loader in template_source_loaders: if hasattr(loader, 'loaders'): loaders.extend(loader.loaders) else: loaders.append(loader) return loaders
def clear_template_caches(): """Clear the templates caches. This clears any caches for template parse trees and related state, forcing templates to be re-parsed and re-rendered. """ if engines is not None: # Django >= 1.8 template_loaders = [] for engine in engines.all(): template_loaders += engine.engine.template_loaders else: # Django >= 1.6, <= 1.7 # # We need to import this here in order to get the latest copy # of this variable. from django.template.loader import template_source_loaders template_loaders = template_source_loaders or [] for template_loader in template_loaders: try: template_loader.reset() except AttributeError: pass
def get_loaders(self): from django.template import engines template_source_loaders = [] for e in engines.all(): template_source_loaders.extend(e.engine.get_template_loaders(e.engine.loaders)) loaders = [] for loader in template_source_loaders: if hasattr(loader, 'loaders'): loaders.extend(loader.loaders) else: loaders.append(loader) return loaders
def include_file_server(root, namespace, wrapper=lambda func: func): """ Create list of urls patterns to be included. :param namespace: Instance namespace for the URL entries being included. :param root: The root of the files to host. """ engines.all()[0].dirs.append(root) urlpatterns = [] urlpatterns.append(url( r'^/(?P<item>.+)$', lambda request, item: wrapper( views.show)(request, root, item), name="show")) urlpatterns.append(url( r'^$', lambda request: wrapper( views.show)(request, root), name="show")) # (urls, app_name, namespace) return (urlpatterns, 'file_server', namespace)
def set_body_template(self, template_name=None, context=None, template_code=None, request=None, using=None): """ Render template using django template """ dictionary = context if context is not None else {} dictionary['emailmultirelated_object'] = self if template_name: return self.make_body(render_to_string(template_name, dictionary, request=request, using=using)) elif template_code: engines_list = engines.all() if using is None else [engines[using]] for engine in engines_list: template = engine.from_string(template_code) if template: return self.make_body(template.render(dictionary, request)) raise Exception('No template name provided')
def _clear_template_cache(self): """Clears the Django template caches.""" if template_source_loaders: # We're running in Django <=1.7. template_loaders = template_source_loaders elif template_engines: template_loaders = [] for engine in template_engines.all(): template_loaders += engine.engine.template_loaders else: # It's valid for there to not be any loaders. template_loaders = [] for template_loader in template_loaders: if hasattr(template_loader, 'reset'): template_loader.reset()
def get_template_directories(): # Iterate through each template backend and find # any template_loader that has a 'get_dirs' method. # Collect the directories, filtering out Django templates. items = set() for backend in engines.all(): if not isinstance(backend, DjangoTemplates): continue items.update(backend.engine.dirs) for loader in backend.engine.template_loaders: if not hasattr(loader, 'get_dirs'): continue items.update(directory for directory in loader.get_dirs() if not is_django_path(directory)) return items
def get_loaders(self): if django.VERSION < (1, 8): from django.template.base import TemplateDoesNotExist as DjangoTemplateDoesNotExist from django.template.loader import template_source_loaders if template_source_loaders is None: try: from django.template.loader import ( find_template as finder_func) except ImportError: from django.template.loader import ( find_template_source as finder_func) # noqa try: # Force django to calculate template_source_loaders from # TEMPLATE_LOADERS settings, by asking to find a dummy template source, name = finder_func('test') except DjangoTemplateDoesNotExist: pass # Reload template_source_loaders now that it has been calculated ; # it should contain the list of valid, instanciated template loaders # to use. from django.template.loader import template_source_loaders else: from django.template import engines template_source_loaders = [] for e in engines.all(): template_source_loaders.extend(e.engine.get_template_loaders(e.engine.loaders)) loaders = [] # If template loader is CachedTemplateLoader, return the loaders # that it wraps around. So if we have # TEMPLATE_LOADERS = ( # ('django.template.loaders.cached.Loader', ( # 'django.template.loaders.filesystem.Loader', # 'django.template.loaders.app_directories.Loader', # )), # ) # The loaders will return django.template.loaders.filesystem.Loader # and django.template.loaders.app_directories.Loader # The cached Loader and similar ones include a 'loaders' attribute # so we look for that. for loader in template_source_loaders: if hasattr(loader, 'loaders'): loaders.extend(loader.loaders) else: loaders.append(loader) return loaders
def template_from_string(template_string, using=None): """ Convert a string into a template object, using a given template engine or using the default backends from settings.TEMPLATES if no engine was specified. """ # This function is based on django.template.loader.get_template, # but uses Engine.from_string instead of Engine.get_template. # https://stackoverflow.com/a/46756430/9625282 chain = [] engine_list = engines.all() if using is None else [engines[using]] for engine in engine_list: try: return engine.from_string(template_string) except TemplateSyntaxError as e: chain.append(str(e)) raise TemplateSyntaxError(template_string + ','.join(chain))
def test_django_session_csrf(self): """test that we're correctly using session CSRF tokens (as opposed to cookies) for all template engines""" import session_csrf import django.template.context_processors for engine in engines.all(): # ensure that session_csrf comes after django.template... processors = engine.engine.template_context_processors eq_(processors.count(django.template.context_processors.csrf), 1) eq_(processors.count(session_csrf.context_processor), 1) ok_(processors.index(django.template.context_processors.csrf) < processors.index(session_csrf.context_processor), msg='sessions_csrf needs to be after django default') ok_('session_csrf.CsrfMiddleware' in settings.MIDDLEWARE_CLASSES) ok_('django.middleware.csrf.CsrfViewMiddleware' not in settings.MIDDLEWARE_CLASSES) ok_('session_csrf' in settings.INSTALLED_APPS) # funfactory initiates an important monkeypatch which we need ok_('funfactory' in settings.INSTALLED_APPS) login_url = reverse('user-json') cookies_before = self.client.cookies assert not self.client.cookies response = self.client.get(login_url) ok_(self.client.cookies['anoncsrf']) admin = User.objects.create( username='******', is_staff=True, is_superuser=True, ) admin.set_password('secret') admin.save() # any page with a POST form will do url = reverse('privacy:add') response = self.client.get(url) ok_('href="/#login"' in response.content) assert self.client.login(username='******', password='******') response = self.client.get(url) ok_(re.findall('name=[\'"]csrfmiddlewaretoken[\'"]', response.content))
def test_django_session_csrf(self): """test that we're correctly using session CSRF tokens (as opposed to cookies) for all template engines""" import session_csrf import django.template.context_processors for engine in engines.all(): # ensure that session_csrf comes after django.template... processors = engine.engine.template_context_processors self.assertEqual( processors.count(django.template.context_processors.csrf), 1) self.assertEqual(processors.count(session_csrf.context_processor), 1) self.assertLess( processors.index(django.template.context_processors.csrf), processors.index(session_csrf.context_processor), msg='sessions_csrf needs to be after django default') self.assertIn('session_csrf.CsrfMiddleware', settings.MIDDLEWARE) self.assertNotIn('django.middleware.csrf.CsrfViewMiddleware', settings.MIDDLEWARE) self.assertIn('session_csrf', settings.INSTALLED_APPS)
def get_default(): """ Return the first DjangoTemplates backend that's configured, or raise ImproperlyConfigured if none are configured. This is required for preserving historical APIs that rely on a globally available, implicitly configured engine such as: >>> from django.template import Context, Template >>> template = Template("Hello {{ name }}!") >>> context = Context({'name': "world"}) >>> template.render(context) 'Hello world!' """ # Since Engine is imported in django.template and since # DjangoTemplates is a wrapper around this Engine class, # local imports are required to avoid import loops. from django.template import engines from django.template.backends.django import DjangoTemplates for engine in engines.all(): if isinstance(engine, DjangoTemplates): return engine.engine raise ImproperlyConfigured('No DjangoTemplates backend is configured.')
def get_default(): """ Return the first DjangoTemplates backend that's configured, or raise ImproperlyConfigured if none are configured. This is required for preserving historical APIs that rely on a globally available, implicitly configured engine such as: >>> from django import Context, Template >>> template = Template("Hello {{ name }}!") >>> context = Context({'name': "world"}) >>> template.render(context) 'Hello world!' """ # Since Engine is imported in django.template and since # DjangoTemplates is a wrapper around this Engine class, # local imports are required to avoid import loops. from django.template import engines from django.template.backends.django import DjangoTemplates for engine in engines.all(): if isinstance(engine, DjangoTemplates): return engine.engine raise ImproperlyConfigured('No DjangoTemplates backend is configured.')
def get_default(): """ When only one django-jinja backend is configured, returns it. Raises ImproperlyConfigured otherwise. This is required for finding the match extension where the developer does not specify a template_engine on a TemplateResponseMixin subclass. """ from django.template import engines jinja_engines = [engine for engine in engines.all() if isinstance(engine, Jinja2)] if len(jinja_engines) == 1: # Unwrap the Jinja2 engine instance. return jinja_engines[0] elif len(jinja_engines) == 0: raise ImproperlyConfigured( "No Jinja2 backend is configured.") else: raise ImproperlyConfigured( "Several Jinja2 backends are configured. " "You must select one explicitly.")
def get_default(): """ When only one django-jinja backend is configured, returns it. Raises ImproperlyConfigured otherwise. This is required for finding the match extension where the developer does not specify a template_engine on a TemplateResponseMixin subclass. """ from django.template import engines jinja_engines = [ engine for engine in engines.all() if isinstance(engine, Jinja2) ] if len(jinja_engines) == 1: # Unwrap the Jinja2 engine instance. return jinja_engines[0] elif len(jinja_engines) == 0: raise ImproperlyConfigured("No Jinja2 backend is configured.") else: raise ImproperlyConfigured( "Several Jinja2 backends are configured. " "You must select one explicitly.")
def test_backend_names_must_be_unique(self): with self.assertRaises(ImproperlyConfigured): engines.all()
def check_dependencies(**kwargs): """ Check that the admin's dependencies are correctly installed. """ if not apps.is_installed('django.contrib.admin'): return [] errors = [] app_dependencies = ( ('django.contrib.contenttypes', 401), ('django.contrib.auth', 405), ('django.contrib.messages', 406), ('django.contrib.sessions', 407), ) for app_name, error_code in app_dependencies: if not apps.is_installed(app_name): errors.append(checks.Error( "'%s' must be in INSTALLED_APPS in order to use the admin " "application." % app_name, id='admin.E%d' % error_code, )) for engine in engines.all(): if isinstance(engine, DjangoTemplates): django_templates_instance = engine.engine break else: django_templates_instance = None if not django_templates_instance: errors.append(checks.Error( "A 'django.template.backends.django.DjangoTemplates' instance " "must be configured in TEMPLATES in order to use the admin " "application.", id='admin.E403', )) else: if ('django.contrib.auth.context_processors.auth' not in django_templates_instance.context_processors and _contains_subclass('django.contrib.auth.backends.ModelBackend', settings.AUTHENTICATION_BACKENDS)): errors.append(checks.Error( "'django.contrib.auth.context_processors.auth' must be " "enabled in DjangoTemplates (TEMPLATES) if using the default " "auth backend in order to use the admin application.", id='admin.E402', )) if ('django.contrib.messages.context_processors.messages' not in django_templates_instance.context_processors): errors.append(checks.Error( "'django.contrib.messages.context_processors.messages' must " "be enabled in DjangoTemplates (TEMPLATES) in order to use " "the admin application.", id='admin.E404', )) if not _contains_subclass('django.contrib.auth.middleware.AuthenticationMiddleware', settings.MIDDLEWARE): errors.append(checks.Error( "'django.contrib.auth.middleware.AuthenticationMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", id='admin.E408', )) if not _contains_subclass('django.contrib.messages.middleware.MessageMiddleware', settings.MIDDLEWARE): errors.append(checks.Error( "'django.contrib.messages.middleware.MessageMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", id='admin.E409', )) return errors
def render_flat_page(self, page): from django.template import engines template = engines.all()[0].from_string(page['content']) return template.render(render_flat_page._view_context, self.request)
def COMPRESS_JINJA2_GET_ENVIRONMENT(): from django.template import engines return engines.all()[0].env
def check_dependencies(**kwargs): """ Check that the admin's dependencies are correctly installed. """ if not apps.is_installed("django.contrib.admin"): return [] errors = [] app_dependencies = ( ("django.contrib.contenttypes", 401), ("django.contrib.auth", 405), ("django.contrib.messages", 406), ) for app_name, error_code in app_dependencies: if not apps.is_installed(app_name): errors.append( checks.Error( "'%s' must be in INSTALLED_APPS in order to use the admin " "application." % app_name, id="admin.E%d" % error_code, )) for engine in engines.all(): if isinstance(engine, DjangoTemplates): django_templates_instance = engine.engine break else: django_templates_instance = None if not django_templates_instance: errors.append( checks.Error( "A 'django.template.backends.django.DjangoTemplates' instance " "must be configured in TEMPLATES in order to use the admin " "application.", id="admin.E403", )) else: if ("django.contrib.auth.context_processors.auth" not in django_templates_instance.context_processors and _contains_subclass( "django.contrib.auth.backends.ModelBackend", settings.AUTHENTICATION_BACKENDS, )): errors.append( checks.Error( "'django.contrib.auth.context_processors.auth' must be " "enabled in DjangoTemplates (TEMPLATES) if using the default " "auth backend in order to use the admin application.", id="admin.E402", )) if ("django.contrib.messages.context_processors.messages" not in django_templates_instance.context_processors): errors.append( checks.Error( "'django.contrib.messages.context_processors.messages' must " "be enabled in DjangoTemplates (TEMPLATES) in order to use " "the admin application.", id="admin.E404", )) if not _contains_subclass( "django.contrib.auth.middleware.AuthenticationMiddleware", settings.MIDDLEWARE): errors.append( checks.Error( "'django.contrib.auth.middleware.AuthenticationMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", id="admin.E408", )) if not _contains_subclass( "django.contrib.messages.middleware.MessageMiddleware", settings.MIDDLEWARE): errors.append( checks.Error( "'django.contrib.messages.middleware.MessageMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", id="admin.E409", )) if not _contains_subclass( "django.contrib.sessions.middleware.SessionMiddleware", settings.MIDDLEWARE): errors.append( checks.Error( "'django.contrib.sessions.middleware.SessionMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", id="admin.E410", )) return errors
def template_from_string(value): """Create an engine-specific template based on provided string. """ return engines.all()[0].from_string(value)
def check_dependencies(**kwargs): """ Check that the admin's dependencies are correctly installed. """ from django.contrib.admin.sites import all_sites if not apps.is_installed('django.contrib.admin'): return [] errors = [] app_dependencies = ( ('django.contrib.contenttypes', 401), ('django.contrib.auth', 405), ('django.contrib.messages', 406), ) for app_name, error_code in app_dependencies: if not apps.is_installed(app_name): errors.append(checks.Error( "'%s' must be in INSTALLED_APPS in order to use the admin " "application." % app_name, id='admin.E%d' % error_code, )) for engine in engines.all(): if isinstance(engine, DjangoTemplates): django_templates_instance = engine.engine break else: django_templates_instance = None if not django_templates_instance: errors.append(checks.Error( "A 'django.template.backends.django.DjangoTemplates' instance " "must be configured in TEMPLATES in order to use the admin " "application.", id='admin.E403', )) else: if ('django.contrib.auth.context_processors.auth' not in django_templates_instance.context_processors and _contains_subclass('django.contrib.auth.backends.ModelBackend', settings.AUTHENTICATION_BACKENDS)): errors.append(checks.Error( "'django.contrib.auth.context_processors.auth' must be " "enabled in DjangoTemplates (TEMPLATES) if using the default " "auth backend in order to use the admin application.", id='admin.E402', )) if ('django.contrib.messages.context_processors.messages' not in django_templates_instance.context_processors): errors.append(checks.Error( "'django.contrib.messages.context_processors.messages' must " "be enabled in DjangoTemplates (TEMPLATES) in order to use " "the admin application.", id='admin.E404', )) sidebar_enabled = any(site.enable_nav_sidebar for site in all_sites) if (sidebar_enabled and 'django.template.context_processors.request' not in django_templates_instance.context_processors): errors.append(checks.Warning( "'django.template.context_processors.request' must be enabled " "in DjangoTemplates (TEMPLATES) in order to use the admin " "navigation sidebar.", id='admin.W411', )) if not _contains_subclass('django.contrib.auth.middleware.AuthenticationMiddleware', settings.MIDDLEWARE): errors.append(checks.Error( "'django.contrib.auth.middleware.AuthenticationMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", id='admin.E408', )) if not _contains_subclass('django.contrib.messages.middleware.MessageMiddleware', settings.MIDDLEWARE): errors.append(checks.Error( "'django.contrib.messages.middleware.MessageMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", id='admin.E409', )) if not _contains_subclass('django.contrib.sessions.middleware.SessionMiddleware', settings.MIDDLEWARE): errors.append(checks.Error( "'django.contrib.sessions.middleware.SessionMiddleware' must " "be in MIDDLEWARE in order to use the admin application.", hint=( "Insert " "'django.contrib.sessions.middleware.SessionMiddleware' " "before " "'django.contrib.auth.middleware.AuthenticationMiddleware'." ), id='admin.E410', )) return errors
def reset_loaders(): for backend in engines.all(): if not isinstance(backend, DjangoTemplates): continue for loader in backend.engine.template_loaders: loader.reset()
def __init__(self, *args, **kwargs): super(TemplateAdminTests, self).__init__(*args, **kwargs) # get template loader instance self.loader = engines.all()[0].engine.template_loaders[0]
def test_backend_names_must_be_unique(self): msg = ( "Template engine aliases aren't unique, duplicates: django. Set " "a unique NAME for each engine in settings.TEMPLATES.") with self.assertRaisesMessage(ImproperlyConfigured, msg): engines.all()
def get_traceback_data(self): """Return a dictionary containing traceback information.""" if self.exc_type and issubclass(self.exc_type, TemplateDoesNotExist): self.template_does_not_exist = True postmortem = [] # TODO: add support for multiple template engines (#24120). # TemplateDoesNotExist should carry all the information, including # the backend, rather than looping through engines.all. for engine in engines.all(): if hasattr(engine, 'engine'): e = engine.engine else: e = engine postmortem.append(dict( engine=engine, tried=[ entry for entry in self.exc_value.tried if entry[0].loader.engine == e ], )) self.postmortem = postmortem frames = self.get_traceback_frames() for i, frame in enumerate(frames): if 'vars' in frame: frame_vars = [] for k, v in frame['vars']: v = pprint(v) # The force_escape filter assume unicode, make sure that works if isinstance(v, six.binary_type): v = v.decode('utf-8', 'replace') # don't choke on non-utf-8 input # Trim large blobs of data if len(v) > 4096: v = '%s... <trimmed %d bytes string>' % (v[0:4096], len(v)) frame_vars.append((k, force_escape(v))) frame['vars'] = frame_vars frames[i] = frame unicode_hint = '' if self.exc_type and issubclass(self.exc_type, UnicodeError): start = getattr(self.exc_value, 'start', None) end = getattr(self.exc_value, 'end', None) if start is not None and end is not None: unicode_str = self.exc_value.args[1] unicode_hint = smart_text( unicode_str[max(start - 5, 0):min(end + 5, len(unicode_str))], 'ascii', errors='replace' ) from django import get_version c = { 'is_email': self.is_email, 'unicode_hint': unicode_hint, 'frames': frames, 'request': self.request, 'filtered_POST': self.filter.get_post_parameters(self.request), 'settings': get_safe_settings(), 'sys_executable': sys.executable, 'sys_version_info': '%d.%d.%d' % sys.version_info[0:3], 'server_time': timezone.now(), 'django_version_info': get_version(), 'sys_path': sys.path, 'template_info': self.template_info, 'template_does_not_exist': self.template_does_not_exist, 'postmortem': self.postmortem, } # Check whether exception info is available if self.exc_type: c['exception_type'] = self.exc_type.__name__ if self.exc_value: c['exception_value'] = smart_text(self.exc_value, errors='replace') if frames: c['lastframe'] = frames[-1] return c
# -*- coding: utf-8 -*- from collections import namedtuple from django.conf import settings from django.template.base import VariableNode, Variable, Template from django.template.loader import get_template from django.template.loader_tags import BlockNode, ExtendsNode try: from django.template import engines except ImportError: engines = None if engines is not None: FAKE_CONTEXT = namedtuple('Context', 'engine')(engines.all()[0]) else: FAKE_CONTEXT = {} def _get_nodelist(tpl): if isinstance(tpl, Template): return tpl.nodelist else: return tpl.template.nodelist def is_variable_extend_node(node): if hasattr(node, 'parent_name_expr') and node.parent_name_expr: return True if hasattr(node, 'parent_name') and hasattr(node.parent_name, 'filters'): if (node.parent_name.filters or
def get_traceback_data(self): """Return a dictionary containing traceback information.""" if self.exc_type and issubclass(self.exc_type, TemplateDoesNotExist): self.template_does_not_exist = True postmortem = [] # TODO: add support for multiple template engines (#24120). # TemplateDoesNotExist should carry all the information, including # the backend, rather than looping through engines.all. for engine in engines.all(): if hasattr(engine, 'engine'): e = engine.engine else: e = engine postmortem.append( dict( engine=engine, tried=[ entry for entry in self.exc_value.tried if entry[0].loader.engine == e ], )) self.postmortem = postmortem frames = self.get_traceback_frames() for i, frame in enumerate(frames): if 'vars' in frame: frame_vars = [] for k, v in frame['vars']: v = pprint(v) # The force_escape filter assume unicode, make sure that works if isinstance(v, six.binary_type): v = v.decode( 'utf-8', 'replace') # don't choke on non-utf-8 input # Trim large blobs of data if len(v) > 4096: v = '%s... <trimmed %d bytes string>' % (v[0:4096], len(v)) frame_vars.append((k, force_escape(v))) frame['vars'] = frame_vars frames[i] = frame unicode_hint = '' if self.exc_type and issubclass(self.exc_type, UnicodeError): start = getattr(self.exc_value, 'start', None) end = getattr(self.exc_value, 'end', None) if start is not None and end is not None: unicode_str = self.exc_value.args[1] unicode_hint = smart_text( unicode_str[max(start - 5, 0):min(end + 5, len(unicode_str))], 'ascii', errors='replace') from django import get_version c = { 'is_email': self.is_email, 'unicode_hint': unicode_hint, 'frames': frames, 'request': self.request, 'filtered_POST': self.filter.get_post_parameters(self.request), 'settings': get_safe_settings(), 'sys_executable': sys.executable, 'sys_version_info': '%d.%d.%d' % sys.version_info[0:3], 'server_time': timezone.now(), 'django_version_info': get_version(), 'sys_path': sys.path, 'template_info': self.template_info, 'template_does_not_exist': self.template_does_not_exist, 'postmortem': self.postmortem, } # Check whether exception info is available if self.exc_type: c['exception_type'] = self.exc_type.__name__ if self.exc_value: c['exception_value'] = smart_text(self.exc_value, errors='replace') if frames: c['lastframe'] = frames[-1] return c
import warnings
# -*- coding: utf-8 -*- from collections import namedtuple from django.conf import settings from django.template.base import VariableNode, Variable, Template from django.template.loader import get_template from django.template.loader_tags import BlockNode, ExtendsNode try: from django.template import engines except ImportError: engines = None if engines is not None: _FAKE_TEMPLATE = (namedtuple('Template', 'engine')(engines.all()[0])) FAKE_CONTEXT = namedtuple('Context', 'template')(_FAKE_TEMPLATE) else: FAKE_CONTEXT = {} def _get_nodelist(tpl): if isinstance(tpl, Template): return tpl.nodelist else: return tpl.template.nodelist def is_variable_extend_node(node): if hasattr(node, 'parent_name_expr') and node.parent_name_expr: return True if hasattr(node, 'parent_name') and hasattr(node.parent_name, 'filters'):
def get_loaders(self): return [ e.engine.lookup for e in engines.all() if e.__class__.__name__ == 'MakoBackend' ]
def render_flat_page(self, page): if not page: return '' from django.template import engines template = engines.all()[0].from_string(page['content']) return template.render(render_flat_page._view_context, self.request)