Advertisement
Guest User

Untitled

a guest
Jun 27th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.65 KB | None | 0 0
  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)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement