Context Navigation

Backwards-incompatible changes

As Django is still in pre-1.0 mode, we haven't yet committed to maintaining backwards compatibility in any APIs. Although we're keeping such changes to a minimum, Django developers should be acutely aware of these changes.

Of course, once we reach 1.0, we'll be strongly committed to backward compatibility.

Refactored meta.py

As of [378], django/core/meta.py has been converted to a package, django/core/meta/. If you're using a version of Django from before [378], make sure to delete django/core/meta.pyc and django/core/meta.pyo, if they exist. The existence of those files doesn't pose any known problems, but it's best to clean things up.

Changed edit_inline and edit_inline_type behavior

As of [440], using edit_inline_type in your models is deprecated, in favor of a less-redundant approach that uses edit_inline itself.

Example of old syntax:
edit_inline=True, edit_inline_type=meta.TABULAR

As of [469], the object_id field in django.models.auth.LogEntry is a TextField instead of an IntegerField. We made this change to accomodate non-integer primary keys.

If you're using a Django database installation from before [469] and you want to use non-integer primary keys on an object you edit in the admin site, you'll need to do an ALTER TABLE in your database.

Added support for anonymous sessions

As of [518], Django has support for anonymous sessions. If you're using a Django database installation from before [518] and you want to use the Django admin, anonymous sessions or auth-based sessions, you'll need to make a few updates to your database and settings files.

Change your settings files

Add "django.middleware.sessions.SessionMiddleware" to the MIDDLEWARE_CLASSES tuple in your admin settings file. Make sure it appears before "django.middleware.admin.AdminUserRequired". (The middleware classes are applied in order, and the admin middleware requires that the session middleware come first.)

If you want session support any other (i.e., non-admin) Django installation, change the MIDDLEWARE_CLASSES setting accordingly. The order (i.e., whether it comes before or after the other installed middleware classes) doesn't matter.

Edit your Django settings file (probably called settings/main.py) to make the following changes:

Add "django.contrib.admin" to INSTALLED_APPS. Order doesn't matter; it can be the first, last, whatever.

Remove "django.middleware.admin.AdminUserRequired" from MIDDLEWARE_CLASSES, if it's in there.

Add "django.middleware.sessions.SessionMiddleware" to MIDDLEWARE_CLASSES, if it's not already in there.

If you've created any custom admin templates, add the appropriate line from the admin TEMPLATE_DIRS setting to your "main" TEMPLATE_DIRS.

(Note that Django looks for "404.html" and "500.html" templates in your TEMPLATE_DIRS. Make sure you have these templates available.)

If you've created any custom admin templates, note that the template inheritance structure has changed. All admin templates are now within an admin subdirectory of the template directory. The following admin templates are directly affected by this change:

404 --> admin/404

500 --> admin/500

base --> admin/base

base_site --> admin/base_site

admin_object_history --> admin/object_history

delete_confirmation_generic --> admin/delete_confirmation

index --> admin/index

login --> admin/login

template_validator --> admin/template_validator

Add "django.core.template.loaders.app_directories.load_template_source" to TEMPLATE_LOADERS, after "django.core.template.loaders.filesystem.load_template_source". If you don't have the TEMPLATE_LOADERS setting, set it to this:

Refactored RSS framework

As of [1194], Django's RSS framework was refactored. This change should not affect most Django users, because the RSS framework was completely undocumented. The only users affected are people who reverse-engineered the framework, and WorldOnline.

Removed django/conf/urls/rss.py. The syndication system doesn't require its own URLconf anymore.

Moved django/views/rss/rss.py to django/contrib/syndication/views.py and refactored it so that feed() takes url and feed_dict instead of slug and param.

Renamed DefaultRssFeed to DefaultFeed in django/utils/feedgenerator.py.

RSS feeds are now specified as subclasses of django.contrib.syndication.feeds.Feed instead of django.core.rss.FeedConfiguration. Syntax is completely different.

RSS feeds are now registered in URLconfs rather than in "magic" settings modules whose names end with "_rss".

Templates for RSS titles and descriptions now live in a feeds directory, not an rss directory.

Changed field name and length for auth.User password_md5 field

As of [1327], the password_md5 field in the auth.User model, which is used for authentication in the Django admin, was renamed to password, and its length was changed from 32 to 128 to accomodate longer hashes and password metadata, such as which hash algorithm to use. This affects everybody who uses the Django authentication system -- including users of the Django admin.

Templates

Templates that are included in another template using {% include %} or {% ssi %}, or extend a template using {% extends %}, must explicitly {% load %} all libraries they need for their tags and filters. Some templates may have worked in the past due to previous requests registering tags : this will no longer work.

Added support for non-named groups in URLconf regular expressions

As of [1470], Django URLconfs support non-named groups in URLconf regular expressions. This means you no longer have to specify the name of each group.

For example, this old syntax:

(r'^(?P<item_id>\d{1,3})/$', 'foo.item_detail'),

Can be shortened to this syntax:

(r'^(\d{1,3})/$', 'foo.item_detail'),

The algorithm it follows is: If there are any named groups, it will use those, ignoring all non-named groups. Otherwise, it will pass all non-named groups as positional arguments. In both cases, it will pass any extra_kwargs as keyword arguments.

The old syntax (named groups) still works. Use that in cases where you can't (or don't want to) couple the order of URL parameters with the order of your view function arguments.

There are two small backwards-incompatibilities about this change:

If you've written custom middleware that implements process_view(), you'll need to change it so it takes view_args and view_kwargs arguments instead of param_dict:

def process_view(self, request, view_func, view_args, view_kwargs)

On the off chance you have legacy URLconfs that have NO captured items but DO use capturing parenthesis (which until now would have had no effect), you'll need to either change your view code to accept the captured values, or uncapture them.

Changed behavior of MultiValueDict.items()

In [1504], the MultiValueDict (and QueryDict) items() method was changed to return the *last* member of each list rather than the full list.

Removed undocumented '_or' database API parameter

As of [1508], the _or parameter no longer works. Use the new complex parameter. This likely doesn't affect anybody except World Online, because _or has been undocumented and vehemently discouraged on the mailing list.

Removed the magic

Database constraint names changed

As of [3512], the format of the constraint names Django generates for foreign key references changed slightly. These names are only used sometimes, when it is not possible to put the reference directly on the affected column, so this is not always visible.

The effect of this change is that manage.py reset app_name and similar commands may generate SQL with invalid constraint names and thus generate an error when run against the database (the database server will complain about the constraint not existing). To fix this, you will need to tweak the output of manage.py sqlreset app_name to match the correct constraint names and pass the results to the database server manually.

Backslash escaping changed

As of [3552], the Django database API now escapes backslashes given as query parameters. If you have any database API code that match backslashes, and it was working before (despite the broken escaping), you'll have to change your code to "unescape" the slashes one level.

For example, this used to work:

# Code that matches a single backslash
MyModel.objects.filter(text__contains='\\\\')

But it should be rewritten as this:

# Code that matches a single backslash
MyModel.objects.filter(text__contains='\\')

Removed ENABLE_PSYCO setting

As of [3877], the ENABLE_PSYCO setting no longer exists. If your settings file includes ENABLE_PSYCO, nothing will break per se, but it just won't do anything. If you want to use ​Psyco with Django, write some custom middleware that activates Psyco.

Changed Admin.manager option to more flexible hook

As of [4342], the manager option to class Admin no longer exists. This option was undocumented, but we're mentioning the change here in case you used it. In favor of this option, class Admin may now define one of these methods:

queryset()

queryset_add()

queryset_change()

These give you much more flexibility.

Note that this change was made to the NewformsAdminBranch. (We initially called the new method change_list_queryset, but this was changed in [4584] to be more flexible.) The change will not be made to trunk until that branch is merged to trunk.

Changed prepopulate_from to be defined in the Admin class, not database field classes

As of [4446], the prepopulate_from option to database fields no longer exists. It's been discontinued in favor of the new prepopulated_fields option on class Admin. The new prepopulated_fields option, if given, should be a dictionary mapping field names to lists/tuples of field names. Here's an example comparing old syntax and new syntax:

Note that this change was made to the NewformsAdminBranch. The change will not be made to trunk until that branch is merged to trunk.

Moved admin doc views into django.contrib.admindocs

As of [4585], the documentation views for the Django admin site were moved into a new package, django.contrib.admindocs.

The admin docs, which aren't documented very well, were located at docs/ in the admin site. They're also linked-to by the "Documentation" link in the upper right of default admin templates.

Because we've moved the doc views, you now have to activate admin docs explicitly. Do this by adding the following line to your URLconf:

(r'^admin/doc/', include('django.contrib.admindocs.urls')),

Note that this change was made to the NewformsAdminBranch. The change will not be made to trunk until that branch is merged to trunk.

Enforcing MySQLdb version

As of [4724], Django will raise an error if you try to use the MySQL backend with a MySQLdb ( MySQL python module) version earlier than 1.2.1p2. There were significant, production-related bugs in earlier versions, so we have upgraded the minimum requirement.

In [4767], a mysql_old backend was added, that is identical to the original mysql backend prior to the change in [4724]. This backend can be used if upgrading the MySQLdb module is not immediately possible, however, it is deprecated and no further development will be done on it.