Показать неопределенные ошибки переменных в шаблонах Django? - PullRequest
18 голосов
/ 29 ноября 2010

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

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

Ответы [ 8 ]

26 голосов
/ 21 октября 2011

Установите это в настройках отладки:

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")

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

10 голосов
/ 29 ноября 2010

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

4 голосов
/ 16 декабря 2015

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

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

В вашем файле 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.

2 голосов
/ 06 июля 2016

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

import sys

# sometimes it's 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's not a variable that's 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
2 голосов
/ 15 октября 2015

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

  • Вы можете заставить Django вызвать исключение при обнаружении {{ undefined_variable }} - используя "хак", описанный в ответе Слэси.

  • Вы не можете заставить Django поднять то же исключение на {% if undefined_variable %} или {% for x in undefined_variable %} и т. Д. «Хак» не работает в таких случаях.

  • Даже в тех случаях, когда это возможно, авторам Django настоятельно рекомендуется использовать эту технику в производственной среде. Если вы не уверены, что не используете встроенные шаблоны Django в своем приложении, вы должны использовать «hack» only в режиме DEBUG.

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

2 голосов
/ 29 ноября 2010

Читайте , как обрабатываются недопустимые переменные в шаблонах. По сути, просто установите TEMPLATE_STRING_IF_INVALID на что-то в вашем settings.py.

TEMPLATE_STRING_IF_INVALID = "He's dead Jim! [%s]"
0 голосов
/ 03 октября 2016

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

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:

На странице

enter image description here

В консоли

> 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.
0 голосов
/ 29 ноября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...