1. Procedure
1.1. Use VirtualEnv + pip
1.1.1. VirtualEnv
1.1.1.1. install
1.1.1.2. activate
1.1.2. pip
1.1.2.1. freeze
1.1.2.1.1. deps
1.1.3. Strongly recommend to learn them
1.1.4. Douglas: Once you master VirtualEnv, also try VirtualEnvWrapper
1.2. Upgrade just Django
1.2.1. pip install --upgrade Django
1.2.2. ./manage.py test
1.2.3. Things to watch for (in general)
1.2.3.1. Accessing internals
1.2.3.1.1. such as
1.2.3.1.2. always document doing that
1.2.3.1.3. have tests for that code
1.2.3.2. Arbitrary arguments
1.2.3.2.1. such as
1.2.3.2.2. remember **kwargs
1.2.3.3. Monkeypatches
1.2.3.3.1. Prone to break
1.2.3.4. Deprecated APIs & backward incompatible changes
1.2.3.4.1. Check not getting warnings
1.3. Test
1.4. Upgrade 3rd party apps
1.4.1. Most already support 1.3
1.4.2. Upgrade them 1 by 1
1.4.3. Use pip
1.4.3.1. Declaratively configure dependencies & versions
1.5. Test
1.6. Deploy
1.6.1. command line
1.6.1.1. pip freeze > requirements.txt
1.6.1.2. pip install -r requirements.txt
1.6.2. to deal with inconsistency during upgrade
1.6.2.1. shutdown apache
1.6.2.2. if you have several servers, upgrade them 1 by 1
2. Deprecated & removed
2.1. AdminSite.root()
2.1.1. (r'^admin/', include(admin.site.urls)),
2.1.1.1. part of a large refactoring to make the admin more customizable
2.2. Auth backends that don't support anonymous
2.2.1. now they must
2.2.1.1. class MyAuthBackend(object):
2.2.1.1.1. support_object_permissions = False
2.2.1.1.2. support_anonymous_user = False
2.2.1.1.3. support_inactive_user = False
2.2.1.1.4. def authenticate(self, *kw): ...
2.3. more here:
2.3.1. http://django.me/deprecation
3. Backwards-incompatible changes
3.1. Usually due to
3.1.1. security fixes
3.1.2. data-loss bugs
3.2. Security fixes
3.2.1. Added CSRF validation for AJAX requests
3.2.1.1. prior to 1.3 they were exempted from CSRF validations
3.2.1.1.1. because it wa assumed that browsers won't allow cross-site scripting
3.2.1.1.2. but a Flash vulnerabilyty does expose this risk
3.2.1.1.3. $.ajaxSetup({ beforeSend: function(xhr, settings) {
3.2.1.1.4. http://django.me/csrf-ajax
3.2.1.2. Placed restrictions on filters in the admin
3.2.1.3. Stopped rendering passwords in PasswordInput
3.2.1.4. Stopped allowing password resets for inactive users
3.3. Data-loss bug: FileField file deleteion
3.3.1. https://gist.github.com/889692
3.3.1.1. but be careful
3.3.1.1.1. when cleaning orphan files
3.4. Optimizations
3.4.1. Manually-managed transactions need to be expllicitly closed
3.4.1.1. @transaction.commit_manually
3.4.2. New index on session table
3.4.2.1. python manage.py sqlindexes sessions
3.4.2.1.1. will make it faster
3.4.2.2. Anyway recommends not using db sessions
3.4.2.2.1. either memcached, or redis
3.5. The rest
3.5.1. Clearable FileField widget is default
3.5.2. No more PROFANITIES_LIST
3.5.2.1. in comments
3.5.2.1.1. never really worked in the 1st place
3.5.3. Localflavor corrections for Canada, Indonesia & the USA
3.5.4. FormSets can no longer take empty data
3.5.5. Initial SQL files no longer work in tests
3.5.5.1. use fixtures instead
4. AMG POOP!
5. better tear-down
6. Better time-zone support
7. The new hotness
7.1. Views
7.1.1. Improved template tags
7.1.1.1. {% with total=managers.count name=... %}
7.1.1.2. {% include "template.html" with total=... %}
7.1.1.3. {% load my_tag from my_tag_lib %}
7.1.1.4. {% load url from future %}
7.1.1.4.1. {% url "path.to.view" %}
7.1.1.4.2. {% url my_var arg kw=arg2 %}
7.1.2. Class-based generic views
7.1.2.1. Template view
7.1.2.1.1. class HelpView(TemplateView): template_name = "..."
7.1.2.1.2. url('..', HelpView.as_view())
7.1.2.2. Model views
7.1.2.2.1. DetailView
7.1.2.3. Base View class
7.1.2.4. All generic views
7.1.2.4.1. You need to extend them
7.1.2.5. Implementation
7.1.2.5.1. Each comprised of mix-ins
7.1.2.6. You can construct your own mix-ins
7.1.2.6.1. Replacing some mix-ins with our own
7.1.2.6.2. See example in docs of JSONDetailView
7.1.2.6.3. Read about Python's MRO
7.1.2.7. Should you use CBV's?
7.1.2.7.1. Wait till there's more experience with it
7.2. Model "on delete" options
7.2.1. (Jacob's favorite new feature)
7.2.2. in 1.2 deletes cascade
7.2.2.1. delete author will delete its books
7.2.3. author = models.ForeignKey(Person, on_delete=models.PROTECT)
7.2.3.1. will throw error when deleting author with books
7.2.4. on_delete=models.DO_NOTHING
7.2.4.1. leave it to the DB handle it
7.2.4.1.1. E.g., MySQL will throw integrity error
7.2.5. on_delete=models.SET_NULL
7.2.5.1. books Author will be set to null
7.2.6. on_delete=models.SET(get_dummy_person)
7.2.6.1. callback that will be called to set the author field of books
7.2.6.1.1. e.g., creates a person called: DELETED
7.2.7. on_delete=<your own callback>
7.2.7.1. def CASCADE_AND_PRINT(collector, field, sub_objs, using):
7.2.7.1.1. print "Deleting", sub_objs
7.2.7.1.2. return models.CASCADE(collector, field, sub_objs, using)
7.3. Testing
7.3.1. unittest2
7.3.1.1. will be part of 2.7
7.3.1.1.1. bundled in 1.3
7.3.1.2. vastly improved failure messages
7.3.1.2.1. shows smart diff of
7.3.1.3. skipping tests
7.3.1.3.1. @unittest.skipIf(platform.system() != 'Linux', "only works on linux")
7.3.1.3.2. skip
7.3.1.3.3. skipIf
7.3.1.3.4. skipUnless(condition, 'skipped if not condition')
7.3.1.3.5. skipIfDBFeature('supports_transactions')
7.3.1.3.6. skipUnlessDBFeature
7.3.1.4. assertRaises context manager
7.3.1.5. class & module level setUp/tearDown
7.3.1.6. usage
7.3.1.6.1. from django.test import TestCase
7.3.1.6.2. class MyTest(TestCase):
7.3.1.7. http://django.me/testing
7.3.2. RequestFactory
7.3.2.1. in 1.2
7.3.2.1.1. r = self.client.get('/some/view')
7.3.2.1.2. self.assertEqual(r.status_code, 200)
7.3.2.2. in 1,3
7.3.2.2.1. rf = django.test.client.RequestFactory()
7.3.2.2.2. request = rf.get('/some/view')
7.3.2.2.3. response = some_view(request)
7.3.2.2.4. self.assertEqual(response.status_code, 200)
7.3.2.3. directly invokes view, without the full stack
7.3.2.3.1. middleware &c
7.3.2.4. Jacob says he'll now write view tests like this
7.3.3. assertNumQueries
7.3.3.1. with self.assertNumQueries(2):
7.3.3.1.1. self.client.get('/some/view/')
7.4. Caching
7.4.1. Multiple caches
7.4.1.1. settings.CACHES
7.4.1.1.1. like databases
7.4.1.1.2. old syntax still work, but at some point you'll need to upgrade
7.4.1.2. syntax
7.4.1.2.1. CACHES = {
7.4.1.2.2. c1 = cache.get_cache('default')
7.4.1.2.3. c1.set(...)
7.4.1.3. changing version will invalidate all previous cache
7.4.1.3.1. there's a python API to change the version
7.4.2. versioning
7.4.3. site-wide prefixing
7.4.4. transformation
7.4.5. pylibmc support
7.4.5.1. new & much faster memcached
7.4.6. Suggestions:
7.4.6.1. switch to pylibmc
7.4.6.2. enable versioning
7.5. Static files
7.5.1. clears confusion
7.5.2. Definitions
7.5.2.1. "media"
7.5.2.1.1. files uploaded by users
7.5.2.2. "static"
7.5.2.2.1. static assets that are part of your site
7.5.2.3. "files"
7.5.2.3.1. either of the above
7.5.3. pluggable apps have their own static files
7.5.4. new contrib app
7.5.4.1. django.contrib.staticfiles
7.5.4.2. collects static files from multiple apps into a central location
7.5.4.2.1. & just that
7.5.5. usage
7.5.5.1. in developement
7.5.5.1.1. add to INSTALLED_APPS
7.5.5.1.2. put static files in
7.5.5.1.3. set STATIC_URL to "/static/"
7.5.5.2. in production
7.5.5.2.1. use dedicated media server
7.5.5.2.2. STATIC_ROOT = '/var/www/static/'
7.5.5.2.3. STATIC_URL = 'http://media.example.com/'
7.5.5.2.4. ./manage.py collectstatic
7.5.6. in templates
7.5.6.1. {% load static %}
7.5.6.2. ...
7.5.6.2.1. see docs
7.5.7. Suggestion
7.5.7.1. Switch if your current scheme makes you unhappy
7.5.8. There are more 3rd party apps with more features
7.5.8.1. compression
7.5.8.2. sprites
7.5.8.3. caching
7.5.8.4. &c
7.5.8.5. see in djangopackages.com
7.5.8.5.1. djangopackages.com > Grids > G > Asset-managers
7.5.8.6. django-storages
7.5.8.6.1. use S3 &c
7.6. Everything else
7.6.1. Logging
7.6.1.1. built-in support for Python logging
7.6.1.2. http://django.me/logging
7.6.1.2.1. Read docs - really good intro
7.6.2. TemplateResponse
7.6.2.1. similar to HttpResponse, yet Lazy
7.6.2.1.1. easier to do manipulations before rendering
7.6.2.2. http://django.me/TemplateResponse
7.6.3. django.shortcuts.render()
7.6.3.1. can use the requst processor
7.6.3.1.1. use it
7.6.4. Transactions as context managers
7.6.5. "Pretty" error emails
7.6.5.1. like the debug pages
7.6.6. "Current site" helper
7.6.6.1. get_current_site
7.6.7. HTTPOnly cookies
7.6.7.1. http://django.me/set_cookie
7.6.8. Context-aware simple tags
8. What's coming next
8.1. Planning for deprecation
8.1.1. to be removed in 1.4
8.1.1.1. Python 2.4 support
8.1.1.2. single-db support
8.1.1.3. User-based messages
8.1.1.3.1. user.message_set.create()
8.1.1.4. Legacy auth backends
8.1.1.4.1. supports_anonymous_user &c must be true
8.1.1.5. & more
8.1.2. to be removed in 1.5
8.1.2.1. Python 2.5 support (?)
8.1.2.1.1. 2.6 much faster
8.1.2.2. mod_python support
8.1.2.2.1. you can't event download it anymore
8.1.2.2.2. use mod_wsgi
8.1.2.3. Function based generic views
8.1.2.4. Old style url & ssi template tags
8.2. New features (speculations)
8.2.1. Basic schema migration support
8.2.1.1. bringing basic low level south api's
8.2.2. Refactor & formalization of "apps"
8.2.3. Improved ideas of what a "user" is
8.2.4. Better hooks for monitoring, debugging, metrics
8.2.5. Template compilation
8.2.5.1. speed improvements
8.2.6. Python 3 support
8.2.6.1. experimental probably