import contextlib from django.db import transaction from django.db.models.expressions import OrderBy class DummyRollbackException(Exception): pass @contextlib.contextmanager def rolledback_transaction(): """ This context manager runs your code in a database transaction that will be rolled back in the end. This can come in handy to simulate the effects of a database operation that you do not actually want to perform. Note that rollbacks are a very slow operation on most database backends. Also, long-running transactions can slow down other operations currently running and you should not use this in a place that is called frequently. """ try: with transaction.atomic(): yield raise DummyRollbackException() except DummyRollbackException: pass else: raise Exception('Invalid state, should have rolled back.') @contextlib.contextmanager def casual_reads(): """ Kept for backwards compatibility. """ yield class FixedOrderBy(OrderBy): # Workaround for https://code.djangoproject.com/ticket/28848 template = '%(expression)s %(ordering)s' def as_sql(self, compiler, connection, template=None, **extra_context): if not template: if self.nulls_last: template = '%s NULLS LAST' % self.template elif self.nulls_first: template = '%s NULLS FIRST' % self.template connection.ops.check_expression_support(self) expression_sql, params = compiler.compile(self.expression) placeholders = { 'expression': expression_sql, 'ordering': 'DESC' if self.descending else 'ASC', } placeholders.update(extra_context) template = template or self.template params = params * template.count('%(expression)s') return (template % placeholders).rstrip(), params