Подтвердить что ты не робот

Показать undefined переменные ошибки в шаблонах Django?

Как я могу попросить Django рассказать мне, когда он сталкивается, например, с переменной ошибкой undefined при отображении шаблонов?

Я пробовал очевидные DEBUG = True и TEMPLATE_DEBUG = True, но они не помогают.

4b9b3361

Ответ 1

Согласно документации django, По умолчанию переменные undefined обрабатываются как '' (пустая строка). В то время как в случае перегруппировки это None. Если вы собираетесь идентифицировать переменную undefined, измените параметр TEMPLATE_STRING_IF_INVALID в настройках. '% s' делает недопустимую переменную отображаемой в качестве ее имени переменной, таким образом, вы можете легко идентифицировать. как недействительные-переменные-обрабатываются

Ответ 2

Поместите это в свои настройки отладки:

class InvalidString(str):
    def __mod__(self, other):
        from django.template.base import TemplateSyntaxError
        raise TemplateSyntaxError(
            "Undefined variable or unknown value for: \"%s\"" % other)

TEMPLATE_STRING_IF_INVALID = InvalidString("%s")

Это должно вызвать ошибку, когда механизм шаблона видит или находит значение undefined.

Ответ 3

Как зарегистрировать предупреждение в переменной undefined в шаблоне

Кажется, что Django полагается на переменные undefined, являющиеся простой пустой строкой. Поэтому вместо того, чтобы изменять это поведение или заставить его генерировать исключение, пусть оно остается прежним, но вместо этого он регистрирует предупреждение!

В вашем файле settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # ...
        'OPTIONS': {
            # ...
            'string_if_invalid': InvalidStringShowWarning("%s"),
        },
    }
]

(string_if_invalid заменяет TEMPLATE_STRING_IF_INVALID в новых версиях Django.)

И далее вам нужно определить класс InvalidStringShowWarning, чтобы он вел себя при регистрации предупреждения:

class InvalidStringShowWarning(str):
    def __mod__(self, other):
        import logging
        logger = logging.getLogger(__name__)
        logger.warning("Undefined variable or unknown value for: '%s'" % (other,))
        return ""

Вы должны увидеть предупреждение на выходе python manage.py runserver.

Ответ 5

Я считаю, что основной надзор над частью Django и основная причина, по которой я предпочитаю не использовать свой механизм шаблонов по умолчанию. Печальная истина заключается в том, что, по крайней мере на данный момент (Django 1.9), , вы не можете надежно выполнить этот эффект.

  • может заставить Django создавать исключение, если встречается {{ undefined_variable }} - используя "хак", описанный в ответном ответе.
  • не может сделать Django одним и тем же исключением на {% if undefined_variable %} или {% for x in undefined_variable %} и т.д. "Хак" не работает в таких случаях.
  • Даже в тех случаях, когда вы можете, разработчикам Django настоятельно рекомендуется использовать этот метод в производственной среде. Если вы не уверены, что не используете встроенные шаблоны Django в своем приложении, вы должны использовать "взломать" только в режиме DEBUG.

Однако, если вы застряли с шаблонами Django, я бы рекомендовал использовать ответ slacy, просто убедитесь, что вы находитесь в режиме DEBUG.

Ответ 6

Поиск переменных шаблона, которые не существовали в контексте, был важен для меня, поскольку несколько раз ошибки превращали его в производство, поскольку представления изменились, но шаблоны не имели.

Я использовал эту технику, реализованную в manage.py, чтобы добиться эффекта отрыва тестов, когда использовались переменные шаблона, не найденные в контексте. Обратите внимание, что этот метод работает с инструкциями for и if, а не только {{ variables }}.

import sys

# sometimes it OK if a variable is undefined:
allowed_undefined_variables = [
    'variable_1',
    'variable_2',
]

if 'test' in sys.argv:
    import django.template.base as template_base

    old_resolve = template_base.Variable.resolve

    def new_resolve(self, context):
        try:
            value = old_resolve(self, context)
        except template_base.VariableDoesNotExist as e:
            # if it not a variable that allowed to not exist then raise a
            # base Exception so Nodes can't catch it (which will make the test
            # fail)
            if self.var not in allowed_undefined_variables:
                raise Exception(e)

            # re-raise the original and let the individual Nodes deal with it
            # however they'd like
            raise e

        return value

    template_base.Variable.resolve = new_resolve

Ответ 7

Я использую следующее:

import logging

from django.utils.html import format_html
from django.utils.safestring import mark_safe


class InvalidTemplateVariable(str):
    """
    Class for override output that the Django template system
    determinated as invalid (e.g. misspelled) variables.
    """

    # styles for display message in HTML`s pages
    styles = mark_safe('style="color: red; font-weight: bold;"')

    def __mod__(self, variable):
        """Overide a standart output here."""

        # access to current settings
        from django.conf import settings

        # display the message on page in make log it only on stage development
        if settings.DEBUG is True:

            # format message with captured variable
            msg = 'Attention! A variable "{}" does not exists.'.format(variable)

            # get logger and make
            logger = self.get_logger()
            logger.warning(msg)

            # mark text as non-escaped in HTML
            return format_html('<i {}>{}</i>', self.styles, msg)

        # on production it will be not displayed
        return ''

    def get_logger(self):
        """Create own logger with advanced error`s details."""

        logger = logging.getLogger(self.__class__.__name__)

        logger.setLevel(logging.DEBUG)

        handler = logging.StreamHandler()
        handler.setLevel(logging.DEBUG)

        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

        handler.setFormatter(formatter)

        logger.addHandler(handler)

        return logger

Использование в файле настроек (по умолчанию это settings.py):

TEMPLATES = [
    {
        ......
        'OPTIONS': {
            .....................
            'string_if_invalid': InvalidTemplateVariable('%s'),
            .....................
        },

    },
]

или напрямую

TEMPLATES[0]['OPTIONS']['string_if_invalid'] = InvalidTemplateVariable('%s')

Результат, если DEBUG = True:

На странице

введите описание изображения здесь

В консоли

> System check identified 1 issue (0 silenced). October 03, 2016 -
> 12:21:40 Django version 1.10.1, using settings 'settings.development'
> Starting development server at http://127.0.0.1:8000/ Quit the server
> with CONTROL-C. 2016-10-03 12:21:44,472 - InvalidTemplateVariable -
> WARNING - Attention! A variable "form.media" does not exists.

Ответ 8

Если в шаблонах есть переменная undefined, django не скажет вам.

Вы можете напечатать эту переменную в поле зрения.