ProfileMiddleware LoginRequiredMiddleware UserBasedExceptionMiddleware
try:
# Python 2.x
from urlparse import urlsplit, urlunsplit
except ImportError:
# Python 3.x
from urllib.parse import urlsplit
from urllib.parse import urlunsplit
from django.conf import settings
from django.http import HttpResponsePermanentRedirect
try:
# Django 1.10
from django.utils.deprecation import MiddlewareMixin
except ImportError:
# Django <1.10
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
class SSLifyMiddleware(MiddlewareMixin):
"""Force all requests to use HTTPs. If we get an HTTP request, we'll just
force a redirect to HTTPs.
.. note::
You can also disable this middleware when testing by setting
``settings.SSLIFY_DISABLE`` to True.
"""
@staticmethod
def process_request(request):
# If the user has explicitly disabled SSLify, do nothing.
if getattr(settings, 'SSLIFY_DISABLE', False):
return None
# Evaluate callables that can disable SSL for the current request
per_request_disables = getattr(settings, 'SSLIFY_DISABLE_FOR_REQUEST', [])
for should_disable in per_request_disables:
if should_disable(request):
return None
# If we get here, proceed as normal.
if not request.is_secure():
url = request.build_absolute_uri(request.get_full_path())
url_split = urlsplit(url)
scheme = 'https' if url_split.scheme == 'http' else url_split.scheme
ssl_port = getattr(settings, 'SSLIFY_PORT', 443)
url_secure_split = (scheme, "%s:%d" % (url_split.hostname or '', ssl_port)) + url_split[2:]
secure_url = urlunsplit(url_secure_split)
return HttpResponsePermanentRedirect(secure_url)
import time
from django.dispatch import dispatcher
from django.core.signals import request_started
from django.test.signals import template_rendered
from django.conf import settings
from django.db import connection
from django.utils.encoding import force_unicode
TEMPLATE = """
<div id="debug" style="clear:both;">
<a href="#debugbox"
onclick="this.style.display = 'none';
document.getElementById('debugbox').style.display = 'block';
return false;"
style="font-size: small; color: red; text-decoration: none; display: block; margin: 12px;"
>+</a>
<div style="display: none;clear: both; border: 1px solid red; padding: 12px; margin: 12px; overflow: scroll" id="debugbox">
<p>Server-time taken: {{ server_time|floatformat:"5" }} seconds</p>
<p>Templates used:</p>
{% if templates %}
<ol>
{% for template in templates %}
<li><strong>{{ template.0 }}</strong> loaded from <samp>{{ template.1 }}</samp></li>
{% endfor %}
</ol>
{% else %}
None
{% endif %}
<p>Template path:</p>
{% if template_dirs %}
<ol>
{% for template in template_dirs %}
<li>{{ template }}</li>
{% endfor %}
</ol>
{% else %}
None
{% endif %}
<p>SQL executed:</p>
{% if sql %}
<ol>
{% for query in sql %}
<li><pre>{{ query.sql|linebreaksbr }}</pre><p>took {{ query.time|floatformat:"3" }} seconds</p></li>
{% endfor %}
</ol>
<p>Total SQL time: {{ sql_total }}</p>
{% else %}
None
{% endif %}
</div>
</div>
</body>
"""
# Monkeypatch instrumented test renderer from django.test.utils - we could use
# django.test.utils.setup_test_environment for this but that would also set up
# e-mail interception, which we don't want
from django.test.utils import instrumented_test_render
from django.template import Template, Context
if Template.render != instrumented_test_render:
Template.original_render = Template.render
Template.render = instrumented_test_render
# MONSTER monkey-patch
old_template_init = Template.__init__
def new_template_init(self, template_string, origin=None, name='<Unknown Template>'):
old_template_init(self, template_string, origin, name)
self.origin = origin
Template.__init__ = new_template_init
class DebugFooter:
def process_request(self, request):
self.time_started = time.time()
self.templates_used = []
self.contexts_used = []
self.sql_offset_start = len(connection.queries)
dispatcher.connect(
self._storeRenderedTemplates, signal=template_rendered
)
def process_response(self, request, response):
# Only include debug info for text/html pages not accessed via Ajax
if 'text/html' not in response['Content-Type']:
return response
if request.is_ajax():
return response
if not settings.DEBUG:
return response
if response.status_code != 200:
return response
templates = [
(t.name, t.origin and t.origin.name or 'No origin')
for t in self.templates_used
]
sql_queries = connection.queries[self.sql_offset_start:]
# Reformat sql queries a bit
sql_total = 0.0
for query in sql_queries:
query['sql'] = reformat_sql(query['sql'])
sql_total += float(query['time'])
#import pdb; pdb.set_trace()
debug_content = Template(TEMPLATE).render(Context({
'server_time': time.time() - self.time_started,
'templates': templates,
'sql': sql_queries,
'sql_total': sql_total,
'template_dirs': settings.TEMPLATE_DIRS,
}))
content = response.content
response.content = force_unicode(content).replace('</body>', debug_content)
#import pdb; pdb.set_trace()
return response
def _storeRenderedTemplates(self, signal, sender, template, context):
self.templates_used.append(template)
self.contexts_used.append(context)
def reformat_sql(sql):
sql = sql.replace('`,`', '`, `')
sql = sql.replace('` FROM `', '` \n FROM `')
sql = sql.replace('` WHERE ', '` \n WHERE ')
sql = sql.replace(' ORDER BY ', ' \n ORDER BY ')
return sql
from django.conf import settings
from django.http import HttpResponseRedirect
from django.utils.deprecation import MiddlewareMixin
from re import compile
EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
class LoginRequiredMiddleware(MiddlewareMixin):
def process_request(self, request):
assert hasattr(request, 'user'), "The Login Required middleware\
requires authentication middleware to be installed. Edit your\
MIDDLEWARE_CLASSES setting to insert\
'django.contrib.auth.middlware.AuthenticationMiddleware'. If that doesn't\
work, ensure your TEMPLATE_CONTEXT_PROCESSORS setting includes\
'django.core.context_processors.auth'."
if not request.user.is_authenticated:
path = request.path_info.lstrip('/')
if not any(m.match(path) for m in EXEMPT_URLS):
return HttpResponseRedirect(settings.LOGIN_URL)
# from django.contrib.auth.decorators import login_required
# from django.utils.deprecation import MiddlewareMixin
# from django.conf import settings
# public_paths = [
# '/login',
# '/login/logout',
# ]
# class AuthRequiredMiddleware(MiddlewareMixin):
# def __init__(self, get_response):
# self.get_response = get_response
# def __call__(self, request):
# return self.get_response(request)
# def process_view(self, request, view_func, view_args, view_kwargs):
# if request.path.startswith(settings.MEDIA_URL) or request.path in public_paths:
# return None
# else:
# return login_required(view_func)(request, *view_args, **view_kwargs)
import sys
import tempfile
import hotshot
import hotshot.stats
from django.conf import settings
from cStringIO import StringIO
class ProfileMiddleware(object):
"""
Displays hotshot profiling for any view.
http://yoursite.com/yourview/?prof
Add the "prof" key to query string by appending ?prof (or &prof=)
and you'll see the profiling results in your browser.
It's set up to only be available in django's debug mode,
but you really shouldn't add this middleware to any production configuration.
* Only tested on Linux
FWIW for me this didn't work on windows.
I needed to switch to mkstemp since NamedTemporaryFile
doesn't seem to like you re-opening the file on windows.
After making that change and adding os.unlink its all good now.
"""
def process_request(self, request):
if settings.DEBUG and request.GET.has_key('prof'):
self.tmpfile = tempfile.NamedTemporaryFile()
self.prof = hotshot.Profile(self.tmpfile.name)
def process_view(self, request, callback, callback_args, callback_kwargs):
if settings.DEBUG and request.GET.has_key('prof'):
return self.prof.runcall(callback, request, *callback_args, **callback_kwargs)
def process_response(self, request, response):
if settings.DEBUG and request.GET.has_key('prof'):
self.prof.close()
out = StringIO()
old_stdout = sys.stdout
sys.stdout = out
stats = hotshot.stats.load(self.tmpfile.name)
#stats.strip_dirs()
stats.sort_stats('time', 'calls')
stats.print_stats()
sys.stdout = old_stdout
stats_str = out.getvalue()
if response and response.content and stats_str:
response.content = "<pre>" + stats_str + "</pre>"
return response
import sys
from django.conf import settings
from django.views.debug import technical_500_response
from django.utils.deprecation import MiddlewareMixin
class UserBasedExceptionMiddleware(MiddlewareMixin):
def process_exception(self, request, exception):
if request.user.is_superuser or request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
return technical_500_response(request, *sys.exc_info())
try:
from threading import local
except ImportError:
from django.utils._threading_local import local
_thread_locals = local()
class CurrentUserMiddleware(object):
"""
Standard middleware that gets user object from the request object and saves
it in thread local storage so that it can be retrieved from contexts where
no ``request`` instance is available.
Whether the use of thread locals is good or bad is subject to debate due to
possible `security issues, or opaqueness of the resulting code for that
matter <http://stackoverflow.com/questions/3227180>`_, as opposed to
`explicitly passing the user object to a function
<http://stackoverflow.com/questions/2087531>`_. However, there are some
contexts when a ``request`` and/or ``user`` instance are simply not
available, such as some ``ModelAdmin`` methods, and thus the careful use of
thread locals is justified.
.. note::
Installing :class:`CurrentUserMiddleware` is currently a requirement when
using django-user-profiles.
"""
def process_request(self, request):
_thread_locals.user = getattr(request, 'user', None)
@staticmethod
def get_current_user():
"""
Returns a ``User`` instance representing the user associated with the
current request.
"""
return getattr(_thread_locals, 'user', None)
@staticmethod
def get_current_user_groups():
"""
Returns a ``QuerySet`` containing all groups the the user associated
with the current request belongs to.
"""
return CurrentUserMiddleware.get_current_user().groups.all()
import pytz
from django.utils import timezone
# make sure you add `TimezoneMiddleware` appropriately in settings.py
class TimezoneMiddleware(object):
"""
Middleware to properly handle the users timezone
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# make sure they are authenticated so we know we have their tz info.
if request.user.is_authenticated():
# we are getting the users timezone that in this case is stored in
# a user's profile
tz_str = request.user.profile.timezone
timezone.activate(pytz.timezone(tz_str))
# otherwise deactivate and the default time zone will be used anyway
else:
timezone.deactivate()
response = self.get_response(request)
return response
'''
{% load tz %}
{% localtime on %}
{# this time will be respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}
{% localtime off %}
{# this will not respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}
'''