Проверьте, есть ли в строке только указанные переменные шаблона Django - PullRequest
2 голосов
/ 20 мая 2019

Я работаю над настраиваемым шаблоном электронной почты, и мне нужно проверить, если в содержимом используется только available_variables. Поэтому, если пользователь введет {{ apple }}, форма должна вернуть ValidationError('This variable is unavailable').

models.py:

email_content = models.TextField()

forms.py:

def clean_email_content(self):
     email_content = self.cleaned_data['email_content']
     available_variables = ['{{ company_name }}', '{{ user_name }}']
     required_variables = ['{{ company_name }}']
     for required_variable in required_variables:
        if not required_variable in email_content:
                raise forms.ValidationError("{} is required".format(required_variable))
     # how to check if there are only `available_variables` in the content?

TL; DR

email_content не может содержать другие переменные (строки, начинающиеся с {{ и заканчивающиеся }}), чем указано в available_variables

Должен ли я использовать регулярные выражения или я могу проверить это с помощью какого-либо метода из Django Template Engine?

Ответы [ 3 ]

3 голосов
/ 20 мая 2019

Вместо этого вы можете использовать лексер движка шаблонов (код nj: django 1.11, возможно, потребуется адаптировать его, если вы используете django 2.x):

from django.template import base
lexer = base.Lexer("{{ var_one }} is one {% if var_two %}{{ var_two|upper }} is two {% endif %}")
tokens = lexer.tokenize()
for t in tokens:
    if t.token_type == base.TOKEN_VAR:
        print("{}: {}".format(t, t.contents)

Я предоставляю вам право прочитать код template.base, чтобы узнать другие полезные функции ...

Также в вашем методе проверки вы определенно хотите отлавливать ВСЕ ошибки сразу (вместо того, чтобы вызывать их, как только вы нашли ошибку), чтобы пользователь мог исправить все ошибки сразу (если вы действительно не хотите сводить с ума своих пользователей, что есть).

И, наконец, как предлагает Гасанов в своем ответе, вы также хотите использовать наборы, чтобы найти как пропущенные, так и недопустимые переменные - это гораздо эффективнее, чем последовательный поиск.

1 голос
/ 20 мая 2019

Мы можем использовать регулярные выражения, чтобы найти все теги из email_content. После этого мы конвертируем их в set и вычитаем из него все available_variables, чтобы найти все неправильные. Если таковой существует - мы кидаем ValidationError.

Обратите внимание, что available_variables само по себе set и содержит только теги без фигурных скобок.
Наше регулярное выражение проверяет любое количество пробелов между скобками и тегом, поэтому ваши пользователи не должны быть в состоянии обмануть.

import re

def clean_email_content(self):
        email_content = self.cleaned_data['email_content']
        available_variables = {'company_name', 'user_name'}
        finds = re.findall(r"{{[ ]*(.*?)[ ]*}}", email_content)
        invalid_tags = set(finds) - available_variables
        if invalid_tags:
            raise forms.ValidationError(
                "Should not contain invalid tags: " + str(invalid_tags)
            )
        return email_content
0 голосов
/ 20 мая 2019

Может быть, вы можете сделать это:

import  re
if any(each not in available_content for each in email_content if re.search("\{\{.*\}\}", each)):
    raise ValidationError("Not present in available_variables")

То, что делает приведенный выше код, заключается в том, что возникает исключение, если в email_content есть какая-либо переменная, которой нет в доступном контенте

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