SHARE
TWEET

Untitled

a guest Jun 27th, 2019 55 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import contextlib
  2. import json
  3.  
  4. from django.db import connection
  5. from django import template
  6.  
  7. register = template.Library()
  8.  
  9. @contextlib.contextmanager
  10. def assert_num_queries(number: int):
  11.     """
  12.     Контекстный менеджер, который ломается, если его вложенный код
  13.     делает лишние запросы к БД
  14.     :param number: сколько запросов разрешено сделать внутри менеджера
  15.     (если 0 - то ни одного не разрешено)
  16.     """
  17.  
  18.     current_query_len = len(connection.queries)
  19.  
  20.     try:
  21.         yield
  22.  
  23.     finally:
  24.         new_query_len = len(connection.queries)
  25.  
  26.         if new_query_len - current_query_len > number:
  27.             details = connection.queries[new_query_len-1:]
  28.             details_str = json.dumps(details, indent=4, ensure_ascii=False)
  29.             raise Exception(
  30.                 f'Found unexpected query! {details_str}'
  31.             )
  32.  
  33.  
  34. class NoDbAccessNode(template.Node):
  35.  
  36.     def __init__(self, nodelist):
  37.         self.nodelist = nodelist
  38.  
  39.     def render(self, context):
  40.         with assert_num_queries(0):
  41.             output = self.nodelist.render(context)
  42.         return output
  43.  
  44.  
  45. @register.tag('nodb')
  46. def nodb(parser, token):
  47.     """
  48.     Тег, который выкидывает исключение, если внутри него есть запросы к БД
  49.  
  50.         {% nodb %}
  51.             ... код, который мы хотим изолировать от доступа к БД
  52.         {% endnodb %}
  53.  
  54.     """
  55.  
  56.     nodelist = parser.parse(('endnodb',))
  57.     parser.delete_first_token()
  58.  
  59.     return NoDbAccessNode(nodelist)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top