You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
704 lines
23 KiB
704 lines
23 KiB
========================================= |
|
Porting your apps from Django 0.96 to 1.0 |
|
========================================= |
|
|
|
.. highlight:: python |
|
|
|
Django 1.0 breaks compatibility with 0.96 in some areas. |
|
|
|
This guide will help you port 0.96 projects and apps to 1.0. The first part of |
|
this document includes the common changes needed to run with 1.0. If after going |
|
through the first part your code still breaks, check the section `Less-common |
|
Changes`_ for a list of a bunch of less-common compatibility issues. |
|
|
|
.. seealso:: |
|
|
|
The :ref:`1.0 release notes <releases-1.0>`. That document explains the new |
|
features in 1.0 more deeply; the porting guide is more concerned with |
|
helping you quickly update your code. |
|
|
|
Common changes |
|
============== |
|
|
|
This section describes the changes between 0.96 and 1.0 that most users will |
|
need to make. |
|
|
|
Use Unicode |
|
----------- |
|
|
|
Change string literals (``'foo'``) into Unicode literals (``u'foo'``). Django |
|
now uses Unicode strings throughout. In most places, raw strings will continue |
|
to work, but updating to use Unicode literals will prevent some obscure |
|
problems. |
|
|
|
See :ref:`ref-unicode` for full details. |
|
|
|
Models |
|
------ |
|
|
|
Common changes to your models file: |
|
|
|
Rename ``maxlength`` to ``max_length`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Rename your ``maxlength`` argument to ``max_length`` (this was changed to be |
|
consistant with form fields): |
|
|
|
Replace ``__str__`` with ``__unicode__`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Replace your model's ``__str__`` function with a ``__unicode__`` method, and |
|
make sure you `use Unicode`_ (``u'foo'``) in that method. |
|
|
|
Remove ``prepopulated_from`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Remove the ``prepopulated_from`` argument on model fields. It's no longer valid |
|
and has been moved to the ``AdminModel`` class in ``admin.py``. See `the |
|
admin`_, below, for more details about changes to the admin. |
|
|
|
Replace ``class Admin:`` with ``admin.py`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Remove all your inner ``class Admin`` declarations from your models. They won't |
|
break anything if you leave them, but they also won't do anything. To register |
|
apps with the admin you'll move those declarations to an ``admin.py`` file; |
|
see `the admin`_ below for more details. |
|
|
|
Example |
|
~~~~~~~ |
|
|
|
Below is an example ``models.py`` file with all the changes you'll need to make: |
|
|
|
Old (0.96) ``models.py``:: |
|
|
|
class Author(models.Model): |
|
first_name = models.CharField(maxlength=30) |
|
last_name = models.CharField(maxlength=30) |
|
slug = models.CharField(maxlength=60, prepopulate_from=('first_name', 'last_name')) |
|
|
|
class Admin: |
|
list_display = ['first_name', 'last_name'] |
|
|
|
def __str__(self): |
|
return '%s %s' % (self.first_name, self.last_name) |
|
|
|
New (1.0) ``models.py``:: |
|
|
|
class Author(models.Model): |
|
first_name = models.CharField(max_length=30) |
|
last_name = models.CharField(max_length=30) |
|
slug = models.CharField(max_length=60) |
|
|
|
def __unicode__(self): |
|
return u'%s %s' % (self.first_name, self.last_name) |
|
|
|
New (1.0) ``admin.py``:: |
|
|
|
from django.contrib import admin |
|
from models import Author |
|
|
|
class AuthorAdmin(admin.ModelAdmin): |
|
list_display = ['first_name', 'last_name'] |
|
prepopulated_fields = { |
|
'slug': ('first_name', 'last_name') |
|
} |
|
|
|
admin.site.register(Author, AuthorAdmin) |
|
|
|
The Admin |
|
--------- |
|
|
|
One of the biggest changes in 1.0 is the new admin. The Django administrative |
|
interface (``django.contrib.admin``) has been completely refactored; admin |
|
definitions are now completely decoupled from model definitions, the framework |
|
as been rewritten to use Django's new form-handling library and redesigned with |
|
extensibility and customization in mind. |
|
|
|
Practically, this means you'll need to rewrite all of your ``class Admin`` |
|
declarations. You've already seen in `models`_ above how to replace your ``class |
|
Admin`` with a ``admin.site.register()`` call in an ``admin.py`` file. Below are |
|
some more details on how to rewrite that ``Admin`` declaration into the new |
|
syntax. |
|
|
|
.. seealso:: |
|
|
|
A contributor to djangosnippets__ has written a script that'll `scan your |
|
models.py and generate a corresponding admin.py`__. |
|
|
|
__ http://www.djangosnippets.org/ |
|
__ http://www.djangosnippets.org/snippets/603/ |
|
|
|
Use new inline syntax |
|
~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The new ``edit_inline`` options have all been moved to ``admin.py``. Here's an |
|
example: |
|
|
|
Old (0.96):: |
|
|
|
class Parent(models.Model): |
|
... |
|
|
|
class Child(models.Model): |
|
parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin=3) |
|
|
|
|
|
New (1.0):: |
|
|
|
class ChildInline(admin.StackedInline): |
|
model = Child |
|
extra = 3 |
|
|
|
class ParentAdmin(models.ModelAdmin): |
|
model = Parent |
|
inlines = [ChildInline] |
|
|
|
admin.site.register(Parent, ParentAdmin) |
|
|
|
See :ref:`admin-inlines` for more details. |
|
|
|
Simplify ``fields``, or use ``fieldsets`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The old ``fields`` syntax was quite confusing, and has been simplified. The old |
|
syntax still works, but you'll need to use ``fieldsets`` instead. |
|
|
|
Old (0.96):: |
|
|
|
class ModelOne(models.Model): |
|
... |
|
|
|
class Admin: |
|
fields = ( |
|
(None, {'fields': ('foo','bar')}), |
|
) |
|
|
|
class ModelTwo(models.Model): |
|
... |
|
|
|
class Admin: |
|
fields = ( |
|
('group1', {'fields': ('foo','bar'), 'classes': 'collapse'}), |
|
('group2', {'fields': ('spam','eggs'), 'classes': 'collapse wide'}), |
|
) |
|
|
|
|
|
New (1.0):: |
|
|
|
class ModelOneAdmin(admin.ModelAdmin): |
|
fields = ('foo', 'bar') |
|
|
|
class ModelTwoAdmin(admin.ModelAdmin): |
|
fieldsets = ( |
|
('group1', {'fields': ('foo','bar'), 'classes': 'collapse'}), |
|
('group2', {'fields': ('spam','eggs'), 'classes': 'collapse wide'}), |
|
) |
|
|
|
|
|
.. seealso:: |
|
|
|
* More detailed information about the changes and the reasons behind them |
|
can be found on the `NewformsAdminBranch wiki page`__ |
|
|
|
* The new admin comes with a ton of new features; you can read about them in |
|
the :ref:`admin documentation <ref-contrib-admin>`. |
|
|
|
__ http://code.djangoproject.com/wiki/NewformsAdminBranch |
|
|
|
URLs |
|
---- |
|
|
|
Update your root ``urls.py`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
If you are using the admin site you need to update your root ``urls.py``. |
|
|
|
Old (0.96) ``urls.py``:: |
|
|
|
from django.conf.urls.defaults import * |
|
|
|
urlpatterns = patterns('', |
|
(r'^admin/', include('django.contrib.admin.urls')), |
|
|
|
# ... the rest of your URLs here ... |
|
) |
|
|
|
New (1.0) ``urls.py``:: |
|
|
|
from django.conf.urls.defaults import * |
|
|
|
# The next two lines enable the admin and load each admin.py file: |
|
from django.contrib import admin |
|
admin.autodiscover() |
|
|
|
urlpatterns = patterns('', |
|
(r'^admin/(.*)', admin.site.root), |
|
|
|
# ... the rest of your URLs here ... |
|
) |
|
|
|
Views |
|
----- |
|
|
|
Use ``django.forms`` instead of ``newforms`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Replace ``django.newforms`` with ``django.forms`` -- Django 1.0 renamed the |
|
``newforms`` module (introduced in 0.96) to plain old ``forms``. The |
|
``oldforms`` module was also removed removed. |
|
|
|
If you are already using new forms all you have to do is change your import |
|
statement. Instead of ``from django import newforms as forms``, use ``from |
|
django import forms``. |
|
|
|
If you are using the old forms system, you will have to rewrite your forms. A |
|
good place to start is the :ref:`forms documentation <topics-forms-index>` |
|
|
|
Handle uploaded files using the new API |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Replace use of uploaded files -- that is, entries in ``request.FILES`` -- as |
|
simple dictionaries with the new :class:`~django.core.files.UploadedFile`. The |
|
old dictionary syntax no longer works. |
|
|
|
Thus, in a view like:: |
|
|
|
def my_view(request): |
|
f = request.FILES['file_field_name'] |
|
... |
|
|
|
You'd need to make the following changes: |
|
|
|
===================== ===================== |
|
Old (0.96) New (1.0) |
|
===================== ===================== |
|
``f['content']`` ``f.read()`` |
|
``f['filename']`` ``f.name`` |
|
``f['content-type']`` ``f.content_type`` |
|
===================== ===================== |
|
|
|
Templates |
|
--------- |
|
|
|
Learn to love autoescaping |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
By default, the templating system now automatically HTML-escapes the output of |
|
every variable. To learn more, see :ref:`automatic-html-escaping`. |
|
|
|
To disable auto-escaping for an individual variable, use the :tfilter:`safe` |
|
filter: |
|
|
|
.. code-block:: html+django |
|
|
|
This will be escaped: {{ data }} |
|
This will not be escaped: {{ data|safe }} |
|
|
|
To disable auto-escaping for an entire template, wrap the template (or just a |
|
particular section of the template) in the :ttag:`autoescape` tag: |
|
|
|
.. code-block:: html+django |
|
|
|
{% autoescape off %} |
|
... unescaped template content here ... |
|
{% endautoescape %} |
|
|
|
Less-common changes |
|
=================== |
|
|
|
The following changes are smaller, more localized changes. They should only |
|
affect more advanced users, but it's probably worth reading through the list and |
|
checking your code for these things. |
|
|
|
Signals |
|
------- |
|
|
|
* Add ``**kwargs`` to any registered signal handlers. |
|
|
|
* Connect, disconnect, and send signals via methods on the |
|
:class:`~django.dispatch.Signal` object instead of through module methods in |
|
``django.dispatch.dispatcher``. |
|
|
|
* Remove any use of the ``Anonymous`` and ``Any`` sender options; they no longer |
|
exist. You can still receive signals sent by any sender by using |
|
``sender=None`` |
|
|
|
* Make any custom signals you've declared into instances of |
|
:class:`django.dispatch.Signal`` instead of anonymous objects. |
|
|
|
Here's quick summary of the code changes you'll need to make: |
|
|
|
================================================= ====================================== |
|
Old (0.96) New (1.0) |
|
================================================= ====================================== |
|
``def callback(sender)`` ``def callback(sender, **kwargs)`` |
|
``sig = object()`` ``sig = django.dispatch.Signal()`` |
|
``dispatcher.connect(callback, sig)`` ``sig.connect(callback)`` |
|
``dispatcher.send(sig, sender)`` ``sig.send(sender)`` |
|
``dispatcher.connect(callback, sig, sender=Any)`` ``sig.connect(callback, sender=None)`` |
|
================================================= ====================================== |
|
|
|
Comments |
|
-------- |
|
|
|
If you were using Django 0.96's ``django.contrib.comments`` app, you'll need to |
|
upgrade to the new comments app introduced in 1.0. See |
|
:ref:`ref-contrib-comments-upgrade` for details. |
|
|
|
Template tags |
|
------------- |
|
|
|
:ttag:`spaceless` tag |
|
~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The spaceless template tag removes *all* spaces between HTML tags instead of |
|
preserving a single space. |
|
|
|
Localflavor |
|
----------- |
|
|
|
US localflavor |
|
~~~~~~~~~~~~~~ |
|
|
|
``django.contrib.localflavor.usa`` has been renamed |
|
:mod:`django.contribg.localflavor.us`. This change was made to match the naming |
|
scheme of other local flavors. |
|
|
|
Sessions |
|
-------- |
|
|
|
Getting a new session key |
|
~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
``SeesionBase.get_new_session_key()`` has been renamed to |
|
``_get_new_session_key()``; ``get_new_session_object()`` no longer exists. |
|
|
|
Fixtures |
|
-------- |
|
|
|
Loading a row no longer calls ``save()`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Previously, loading a row automatically ran the model's ``save()`` method. This |
|
is no longer the case, so any fields (for example: timestamps) that were |
|
auto-populated by a ``save()`` now need explicit values in any fixture. |
|
|
|
Settings |
|
-------- |
|
|
|
Better exceptions |
|
~~~~~~~~~~~~~~~~~ |
|
|
|
The old :exc:`EnvironmentError` was split into an :exc:`ImportError` raised when |
|
Django fails to find the settings module and a :exc:`RuntimeError` when you try |
|
to reconfigure settings after having already used them |
|
|
|
``LOGIN_URL`` has moved |
|
~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The ``LOGIN_URL`` constant moved from ``django.contrib.auth`` into the |
|
``settings`` module. Instead of using ``from django.contrib.auth import |
|
LOGIN_URL`` refer to :setting:`settings.LOGIN_URL <LOGIN_URL>`. |
|
|
|
:setting:`APPEND_SLASH` behaviour has been updated |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
In 0.96, if a URL didn't end in a slash or have a period in the final |
|
component of it's path, and ``APPEND_SLASH`` was True, Django would redirect |
|
to the same URL, but with a slash appended to the end. Now, Django checks to |
|
see if the pattern without the trailing slash would be matched by something in |
|
your URL patterns. If so, no redirection takes place, because it is assumed |
|
you deliberately wanted to catch that pattern. |
|
|
|
For most people, this won't require any changes. Some people, though, have URL |
|
patterns that look like this:: |
|
|
|
r'/some_prefix/(.*)$' |
|
|
|
Previously, those patterns would have been redirected to have a trailing |
|
slash. If you always want a slash on such URLs, rewrite the pattern as:: |
|
|
|
r'/some_prefix/(.*/)$' |
|
|
|
Samller model changes |
|
--------------------- |
|
|
|
Different exception from ``get()`` |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The models manager now returns a :exc:`MultipleObjectsReturned` exception |
|
instead of :exc:`AssertionError`: |
|
|
|
Old (0.96):: |
|
|
|
try: |
|
Model.objects.get(...) |
|
except AssertionError: |
|
handle_the_error() |
|
|
|
New (1.0):: |
|
|
|
try: |
|
Model.objects.get(...) |
|
except Model.MultipleObjectsReturned: |
|
handle_the_error() |
|
|
|
``LazyDate`` has been fired |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The ``LazyDate`` helper class no longer exists. |
|
|
|
Default field values and query arguments can both be callable objects, so |
|
instances of ``LazyDate`` can be replaced with a reference to ``datetime.datetime.now``: |
|
|
|
Old (0.96):: |
|
|
|
class Article(models.Model): |
|
title = models.CharField(maxlength=100) |
|
published = models.DateField(default=LazyDate()) |
|
|
|
New (1.0):: |
|
|
|
import datetime |
|
|
|
class Article(models.Model): |
|
title = models.CharField(maxlength=100) |
|
published = models.DateField(default=datetime.datetime.now) |
|
|
|
``DecimalField`` is new, and ``FloatField`` is now a proper float |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Old (0.96):: |
|
|
|
class MyModel(models.Model): |
|
field_name = models.FloatField(max_digits=10, decimal_places=3) |
|
... |
|
|
|
New (1.0):: |
|
|
|
class MyModel(models.Model): |
|
field_name = models.DecimalField(max_digits=10, decimal_places=3) |
|
... |
|
|
|
If you forget to make this change, you will see errors about ``FloatField`` |
|
not taking a ``max_digits`` attribute in ``__init__``, since the new |
|
``FloatField`` takes no precision-related arguments. |
|
|
|
If you are using MySQL or PostgreSQL, there are no further changes needed. The |
|
database column types for ``DecimalField`` are the same as for the old |
|
``FloatField``. |
|
|
|
If you are using SQLite, you need to force the database to view the |
|
appropriate columns as decimal types, rather than floats. To do this, you'll |
|
need to reload your data. Do this after you have made the change to using |
|
``DecimalField`` in your code and updated the Django code. |
|
|
|
.. warning:: |
|
|
|
**Back up your database first!** |
|
|
|
For SQLite, this means making a copy of the single file that stores the |
|
database (the name of that file is the ``DATABASE_NAME`` in your settings.py |
|
file). |
|
|
|
To upgrade each application to use a ``DecimalField``, do the following, |
|
replacing ``<app>`` in the code below with each app's name: |
|
|
|
.. code-block:: bash |
|
|
|
$ ./manage.py dumpdata --format=xml <app> > data-dump.xml |
|
$ ./manage.py reset <app> |
|
$ ./manage.py loaddata data-dump.xml |
|
|
|
Notes: |
|
|
|
1. It is important that you remember to use XML format in the first step of |
|
this process. We are exploiting a feature of the XML data dumps that makes |
|
porting floats to decimals with SQLite possible. |
|
|
|
2. In the second step you will be asked to confirm that you are prepared to |
|
lose the data for the application(s) in question. Say yes; we'll restore |
|
this data in the third step, of course. |
|
|
|
3. ``DecimalField`` is not used in any of the apps shipped with Django prior |
|
to this change being made, so you do not need to worry about performing |
|
this procedure for any of the standard Django models. |
|
|
|
If something goes wrong in the above process, just copy your backed up |
|
database file over the top of the original file and start again. |
|
|
|
Internationalization |
|
-------------------- |
|
|
|
:func:`django.views.i18n.set_language` now requires a POST request |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Previously, a GET request was used. The old behavior meant that state (the |
|
locale used to display the site) could be changed by a GET request, which is |
|
against the HTTP specification's recommendations. Code calling this view must |
|
ensure that a POST request is now made, instead of a GET. This means you can |
|
no longer use a link to access the view, but must use a form submission of |
|
some kind (e.g. a button). |
|
|
|
``_()`` is no longer in builtins |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
``_()`` is no longer monkeypatched into builtins. If you were previously |
|
relying on ``_()`` always being present, you should now explicitly import |
|
``ugettext`` or ``ugettext_lazy``, if appropriate, and alias it to ``_`` |
|
yourself:: |
|
|
|
from django.utils.translation import ugettext as _ |
|
|
|
HTTP request/response objects |
|
----------------------------- |
|
|
|
Accessing ``HTTPResponse`` headers |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
``django.http.HttpResponse.headers`` has been renamed to ``_headers`` and |
|
:class:`HttpResponse`` now supports containment checking directly. So use |
|
``if header in response:`` instead of ``if header in response.headers:``. |
|
|
|
Generic relations |
|
----------------- |
|
|
|
Generic relations have been moved out of core |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The generic relation classes -- ``GenericForeignKey`` and ``GenericRelation`` |
|
-- have moved into the :mod:`django.contrib.contenttypes` module. |
|
|
|
Testing |
|
------- |
|
|
|
:meth:`django.test.Client.login` has changed |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Old (0.96):: |
|
|
|
from django.test import Client |
|
c = Client() |
|
c.login('/path/to/login','myuser','mypassword') |
|
|
|
New (1.0):: |
|
|
|
# ... same as above, but then: |
|
c.login(username='myuser', password='mypassword') |
|
|
|
Management commands |
|
------------------- |
|
|
|
Running management commands from your code |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
:mod:`django.core.management`` has been greately refactored. |
|
|
|
Calls to management services in your code will now need to use |
|
``call_command``. For example, if you have some test code that calls flush and |
|
load_data:: |
|
|
|
from django.core import management |
|
management.flush(verbosity=0, interactive=False) |
|
management.load_data(['test_data'], verbosity=0) |
|
|
|
You will need to change this code to read:: |
|
|
|
from django.core import management |
|
management.call_command('flush', verbosity=0, interactive=False) |
|
management.call_command('loaddata', 'test_data', verbosity=0) |
|
|
|
Subcommands must now preceed options |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
``django-admin.py`` and ``manage.py`` now require subcommands to precede |
|
options. So: |
|
|
|
.. code-block:: bash |
|
|
|
$ django-admin.py --settings=foo.bar runserver |
|
|
|
no longer works, and must be changed to: |
|
|
|
.. code-block:: bash |
|
|
|
$ django-admin.py runserver --settings=foo.bar |
|
|
|
Syndication |
|
----------- |
|
|
|
``Feed.__init__`` has changed |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
The ``__init__()`` parameters in in syndication framework's ``Feed`` class now |
|
take an ``HttpRequest`` object as its second parameter, instead of the feed's |
|
URL. This allows the syndication framework to work without requiring the sites |
|
framework. This only affects code that subclass ``Feed`` and overrides the |
|
``__init__()`` method, and code that calls ``Feed.__init__()`` directly. |
|
|
|
Data structures |
|
--------------- |
|
|
|
``SortedDictFromList`` is gone |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
`django.newforms.forms.SortedDictFromList`` was removed. |
|
:class:`django.utils.datastructures.SortedDict`` can now be instantiated with |
|
a sequence of tuples. |
|
|
|
To update your code: |
|
|
|
1. Use :class:`django.utils.datastructures.SortedDict` wherever you were |
|
using ``django.newforms.forms.SortedDictFromList``. |
|
|
|
2. Since :meth:`django.utils.datastructures.SortedDict.copy` return a |
|
deepcopy as ``SortedDictFromList`` method did, you will need to update |
|
your code if you were relying on a deepcopy. Do this by using |
|
``copy.deepcopy`` directly. |
|
|
|
Database backend functions |
|
-------------------------- |
|
|
|
Database backend functions have been renamed |
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Almost *all* of the database backend-level functions have been renamed and/or |
|
relocated. None of these were documented, but you'll need to change your code |
|
if you're using any of these functions, all of which are in :mod:`django.db`: |
|
|
|
======================================= =================================================== |
|
Old (0.96) New (1.0) |
|
======================================= =================================================== |
|
``backend.get_autoinc_sql`` ``connection.ops.autoinc_sql`` |
|
``backend.get_date_extract_sql`` ``connection.ops.date_extract_sql`` |
|
``backend.get_date_trunc_sql`` ``connection.ops.date_trunc_sql`` |
|
``backend.get_datetime_cast_sql`` ``connection.ops.datetime_cast_sql`` |
|
``backend.get_deferrable_sql`` ``connection.ops.deferrable_sql`` |
|
``backend.get_drop_foreignkey_sql`` ``connection.ops.drop_foreignkey_sql`` |
|
``backend.get_fulltext_search_sql`` ``connection.ops.fulltext_search_sql`` |
|
``backend.get_last_insert_id`` ``connection.ops.last_insert_id`` |
|
``backend.get_limit_offset_sql`` ``connection.ops.limit_offset_sql`` |
|
``backend.get_max_name_length`` ``connection.ops.max_name_length`` |
|
``backend.get_pk_default_value`` ``connection.ops.pk_default_value`` |
|
``backend.get_random_function_sql`` ``connection.ops.random_function_sql`` |
|
``backend.get_sql_flush`` ``connection.ops.sql_flush`` |
|
``backend.get_sql_sequence_reset`` ``connection.ops.sequence_reset_sql`` |
|
``backend.get_start_transaction_sql`` ``connection.ops.start_transaction_sql`` |
|
``backend.get_tablespace_sql`` ``connection.ops.tablespace_sql`` |
|
``backend.quote_name`` ``connection.ops.quote_name`` |
|
``backend.get_query_set_class`` ``connection.ops.query_set_class`` |
|
``backend.get_field_cast_sql`` ``connection.ops.field_cast_sql`` |
|
``backend.get_drop_sequence`` ``connection.ops.drop_sequence_sql`` |
|
``backend.OPERATOR_MAPPING`` ``connection.operators`` |
|
``backend.allows_group_by_ordinal`` ``connection.features.allows_group_by_ordinal`` |
|
``backend.allows_unique_and_pk`` ``connection.features.allows_unique_and_pk`` |
|
``backend.autoindexes_primary_keys`` ``connection.features.autoindexes_primary_keys`` |
|
``backend.needs_datetime_string_cast`` ``connection.features.needs_datetime_string_cast`` |
|
``backend.needs_upper_for_iops`` ``connection.features.needs_upper_for_iops`` |
|
``backend.supports_constraints`` ``connection.features.supports_constraints`` |
|
``backend.supports_tablespaces`` ``connection.features.supports_tablespaces`` |
|
``backend.uses_case_insensitive_names`` ``connection.features.uses_case_insensitive_names`` |
|
``backend.uses_custom_queryset`` ``connection.features.uses_custom_queryset`` |
|
======================================= =================================================== |
|
|
|
|