Prefetch generic relations
See the function docstring.
- generic
- performance
- prefetch
See the function docstring.
Django 1.3 has an assertNumQueries method which will allows you to simply specify the number of queries you expect. Sometimes, however, specifying the exact number of queries is overkill, and makes the test too brittle. This code provides a way to make more forgiving tests. See http://lukeplant.me.uk/blog/posts/fuzzy-testing-with-assertnumqueries/
This middleware makes the page load faster because it moves all tags <script> to the end of document. When a tag <script> loads, it blocks parallel loading, so, the best practice is load them after load CSS and images. To use it, just put in a file and add to your setting MIDDLEWARE_CLASSES.
Based *very heavily* on the middleware in [this snippet](http://www.djangosnippets.org/snippets/727/). As with that one, append '?prof' to the URL to see profiling output instead of page output. The big change is that you can also pass an argument to control sorting. For example, you can append '?prof=cumulative' to sort the results by the cumulative time consumed. See the [documentation on the Stats class](http://docs.python.org/library/profile.html#pstats.Stats.sort_stats) for all the options.
Similar to [Profiling Middleware](http://www.djangosnippets.org/snippets/186/), but uses cProfile instead of hotshot. Append ?prof to the URL to see profiling output instead of page output.
Put this code somewhere in one of your INSTALLED_APPS `__init__.py` file. This code will replace the django.template.loader.get_template with cached version. Standard get_template function from django reads and parses the template code every time it's called. This version calls (if DEBUG set to False) it only once per template. After that it gets a Template object from template_cache dictionary. On django http server with template code like that: {% extends "index.html" %} {% block content %} {% if form.has_errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} <form method="post" action="."> <table> <tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr> <tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr> </table> <input type="submit" value="login" /> <input type="hidden" name="next" value="{{ next }}" /> </form> {% endblock %} ab -n 100 on mac os x 10.5 core 2 duo 2 ghz with 2 GB of RAM gives forge-macbook:~ forge$ ab -n 100 http://127.0.0.1:8000/login/ This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: WSGIServer/0.1 Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: /login/ Document Length: 934 bytes Concurrency Level: 1 Time taken for tests: 0.432934 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 120200 bytes HTML transferred: 93400 bytes Requests per second: 230.98 [#/sec] (mean) Time per request: 4.329 [ms] (mean) Time per request: 4.329 [ms] (mean, across all concurrent requests) Transfer rate: 270.25 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 3 3 1.5 4 12 Waiting: 3 3 1.2 3 12 Total: 3 3 1.5 4 12 Percentage of the requests served within a certain time (ms) 50% 4 66% 4 75% 4 80% 4 90% 4 95% 5 98% 10 99% 12 100% 12 (longest request) without template caching, and forge-macbook:~ forge$ ab -n 100 http://127.0.0.1:8000/login/ This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: WSGIServer/0.1 Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: /login/ Document Length: 934 bytes Concurrency Level: 1 Time taken for tests: 0.369860 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 120200 bytes HTML transferred: 93400 bytes Requests per second: 270.37 [#/sec] (mean) Time per request: 3.699 [ms] (mean) Time per request: 3.699 [ms] (mean, across all concurrent requests) Transfer rate: 316.34 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 3 3 0.9 3 9 Waiting: 2 3 0.9 3 8 Total: 3 3 0.9 3 9 Percentage of the requests served within a certain time (ms) 50% 3 66% 3 75% 3 80% 3 90% 3 95% 5 98% 8 99% 9 100% 9 (longest request) with caching enabled. In both cases DEBUG is set to False.
Watch out! Previous versions of this snippet (without the values list) were vulnerable to SQL injection attacks. The "correct" solution is probably to wait until [ticket 4102](http://code.djangoproject.com/ticket/4102) hits the trunk. But here's my temporary fix while we wait for that happy day. Django's model.save() method is a PITA: 1. It does a SELECT first to see if the instance is already in the database. 2. It has additional database performance overhead because it writes all fields, not just the ones that have been changed. 3. It overwrites other model fields with data that may be out of date. This is a real problem in concurrent applications, like almost all web apps. If you just want to update a field or two on a model instance which is already in the database, try this: update_fields(user, email='[email protected]', is_staff=True, last_login=datetime.now()) Or you can add it to your models (see below) and then do this: user.update_fields( email='[email protected]', is_staff=True, last_login=datetime.now()) To add it to your model, put it in a module called granular_update, then write this in your models.py: import granular_update class User(models.Model): email = models.EmailField() is_staff = models.BooleanField() last_login = models.DateTimeField() update_fields = granular_update.update_fields
The script that can be used to profile any Django-powered web-site and find how many SQL-queries are used per page, how heavy html-pages are, etc. To use the the script it's enough to put django-profile.py somewhere in PYTHONPATH and call it from the directory that holds projects' settings.py. For more info and examples please see: [www.mysoftparade.com/blog/django-profile-sql-performance/](http://www.mysoftparade.com/blog/django-profile-sql-performance/)
Use this to display a split of page execution time between python and the db in your base template when debugging. I originally got the base of this code from another snippet, but I can't find it anymore and want to share with new folks because I find this handy.
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 * You should probably use this one instead: http://djangosnippets.org/snippets/2126/
10 snippets posted so far.