-
-
Save CyberLight/2fd0a13fa18f83398ba16ce7f6512b31 to your computer and use it in GitHub Desktop.
Django-тег, запрещающий SQL в шаблонах
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import contextlib | |
import json | |
from django.db import connection | |
from django import template | |
register = template.Library() | |
@contextlib.contextmanager | |
def assert_num_queries(number: int): | |
""" | |
Контекстный менеджер, который ломается, если его вложенный код | |
делает лишние запросы к БД | |
:param number: сколько запросов разрешено сделать внутри менеджера | |
(если 0 - то ни одного не разрешено) | |
""" | |
current_query_len = len(connection.queries) | |
try: | |
yield | |
finally: | |
new_query_len = len(connection.queries) | |
if new_query_len - current_query_len > number: | |
details = connection.queries[new_query_len-1:] | |
details_str = json.dumps(details, indent=4, ensure_ascii=False) | |
raise Exception( | |
f'Found unexpected query! {details_str}' | |
) | |
class NoDbAccessNode(template.Node): | |
def __init__(self, nodelist): | |
self.nodelist = nodelist | |
def render(self, context): | |
with assert_num_queries(0): | |
output = self.nodelist.render(context) | |
return output | |
@register.tag('nodb') | |
def nodb(parser, token): | |
""" | |
Тег, который выкидывает исключение, если внутри него есть запросы к БД | |
{% nodb %} | |
... код, который мы хотим изолировать от доступа к БД | |
{% endnodb %} | |
""" | |
nodelist = parser.parse(('endnodb',)) | |
parser.delete_first_token() | |
return NoDbAccessNode(nodelist) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment