|
1 ======================== |
|
2 Django 1.2 release notes |
|
3 ======================== |
|
4 |
|
5 *May 17, 2010.* |
|
6 |
|
7 Welcome to Django 1.2! |
|
8 |
|
9 Nearly a year in the making, Django 1.2 packs an impressive list of `new |
|
10 features`_ and lots of bug fixes. These release notes cover the new features, |
|
11 as well as important changes you'll want to be aware of when upgrading from |
|
12 Django 1.1 or older versions. |
|
13 |
|
14 .. _new features: `What's new in Django 1.2`_ |
|
15 |
|
16 Overview |
|
17 ======== |
|
18 |
|
19 Django 1.2 introduces several large, important new features, including: |
|
20 |
|
21 * Support for `multiple database connections`_ in a single Django instance. |
|
22 |
|
23 * `Model validation`_ inspired by Django's form validation. |
|
24 |
|
25 * Vastly `improved protection against Cross-Site Request Forgery`_ (CSRF). |
|
26 |
|
27 * A new `user "messages" framework`_ with support for cookie- and session-based |
|
28 message for both anonymous and authenticated users. |
|
29 |
|
30 * Hooks for `object-level permissions`_, `permissions for anonymous users`_, |
|
31 and `more flexible username requirements`_. |
|
32 |
|
33 * Customization of e-mail sending via `e-mail backends`_. |
|
34 |
|
35 * New :ref:`"smart" if template tag <new-in-1.2-smart-if>` which supports |
|
36 comparison operators. |
|
37 |
|
38 .. _multiple database connections: `support for multiple databases`_ |
|
39 .. _improved protection against Cross-Site Request Forgery: `improved CSRF protection`_ |
|
40 .. _user "messages" framework: `messages framework`_ |
|
41 .. _more flexible username requirements: `relaxed requirements for usernames`_ |
|
42 |
|
43 These are just the highlights; full details and a complete list of features `may |
|
44 be found below`_. |
|
45 |
|
46 .. _may be found below: `what's new in django 1.2`_ |
|
47 |
|
48 .. seealso:: |
|
49 |
|
50 `Django Advent`_ covered the release of Django 1.2 with a series of |
|
51 articles and tutorials that cover some of the new features in depth. |
|
52 |
|
53 .. _django advent: http://djangoadvent.com/ |
|
54 |
|
55 Wherever possible these features have been introduced in a backwards-compatible |
|
56 manner per :doc:`our API stability policy </misc/api-stability>` policy. |
|
57 |
|
58 However, a handful of features *have* changed in ways that, for some users, will be |
|
59 backwards-incompatible. The big changes are: |
|
60 |
|
61 * Support for Python 2.3 has been dropped. See the full notes |
|
62 below. |
|
63 |
|
64 * The new CSRF protection framework is not backwards-compatible with |
|
65 the old system. Users of the old system will not be affected until |
|
66 the old system is removed in Django 1.4. |
|
67 |
|
68 However, upgrading to the new CSRF protection framework requires a few |
|
69 important backwards-incompatible changes, detailed in `CSRF Protection`_, |
|
70 below. |
|
71 |
|
72 * Authors of custom :class:`~django.db.models.Field` subclasses should be |
|
73 aware that a number of methods have had a change in prototype, detailed |
|
74 under `get_db_prep_*() methods on Field`_, below. |
|
75 |
|
76 * The internals of template tags have changed somewhat; authors of custom |
|
77 template tags that need to store state (e.g. custom control flow tags) |
|
78 should ensure that their code follows the new rules for `stateful template |
|
79 tags`_ |
|
80 |
|
81 * The :func:`~django.contrib.auth.decorators.user_passes_test`, |
|
82 :func:`~django.contrib.auth.decorators.login_required`, and |
|
83 :func:`~django.contrib.auth.decorators.permission_required`, decorators |
|
84 from :mod:`django.contrib.auth` only apply to functions and no longer |
|
85 work on methods. There's a simple one-line fix `detailed below`_. |
|
86 |
|
87 .. _detailed below: `user_passes_test, login_required and permission_required`_ |
|
88 |
|
89 Again, these are just the big features that will affect the most users. Users |
|
90 upgrading from previous versions of Django are heavily encouraged to consult |
|
91 the complete list of :ref:`backwards-incompatible changes |
|
92 <backwards-incompatible-changes-1.2>` and the list of :ref:`deprecated |
|
93 features <deprecated-features-1.2>`. |
|
94 |
|
95 Python compatibility |
|
96 ==================== |
|
97 |
|
98 While not a new feature, it's important to note that Django 1.2 |
|
99 introduces the first shift in our Python compatibility policy since |
|
100 Django's initial public debut. Previous Django releases were tested |
|
101 and supported on 2.x Python versions from 2.3 up; Django 1.2, however, |
|
102 drops official support for Python 2.3. As such, the minimum Python |
|
103 version required for Django is now 2.4, and Django is tested and |
|
104 supported on Python 2.4, 2.5 and 2.6, and will be supported on the |
|
105 as-yet-unreleased Python 2.7. |
|
106 |
|
107 This change should affect only a small number of Django users, as most |
|
108 operating-system vendors today are shipping Python 2.4 or newer as |
|
109 their default version. If you're still using Python 2.3, however, |
|
110 you'll need to stick to Django 1.1 until you can upgrade; per |
|
111 :doc:`our support policy </internals/release-process>`, Django 1.1 will |
|
112 continue to receive security support until the release of Django 1.3. |
|
113 |
|
114 A roadmap for Django's overall 2.x Python support, and eventual |
|
115 transition to Python 3.x, is currently being developed, and will be |
|
116 announced prior to the release of Django 1.3. |
|
117 |
|
118 What's new in Django 1.2 |
|
119 ======================== |
|
120 |
|
121 Support for multiple databases |
|
122 ------------------------------ |
|
123 |
|
124 Django 1.2 adds the ability to use :doc:`more than one database |
|
125 </topics/db/multi-db>` in your Django project. Queries can be issued at a |
|
126 specific database with the `using()` method on ``QuerySet`` objects. Individual |
|
127 objects can be saved to a specific database by providing a ``using`` argument |
|
128 when you call ``save()``. |
|
129 |
|
130 Model validation |
|
131 ---------------- |
|
132 |
|
133 Model instances now have support for :ref:`validating their own data |
|
134 <validating-objects>`, and both model and form fields now accept configurable |
|
135 lists of :doc:`validators </ref/validators>` specifying reusable, encapsulated |
|
136 validation behavior. Note, however, that validation must still be performed |
|
137 explicitly. Simply invoking a model instance's ``save()`` method will not |
|
138 perform any validation of the instance's data. |
|
139 |
|
140 Improved CSRF protection |
|
141 ------------------------ |
|
142 |
|
143 Django now has much improved protection against :doc:`Cross-Site Request Forgery |
|
144 (CSRF) attacks</ref/contrib/csrf>`. This type of attack occurs when a malicious |
|
145 Web site contains a link, a form button or some JavaScript that is intended to |
|
146 perform some action on your Web site, using the credentials of a logged-in user |
|
147 who visits the malicious site in their browser. A related type of attack, "login |
|
148 CSRF," where an attacking site tricks a user's browser into logging into a site |
|
149 with someone else's credentials, is also covered. |
|
150 |
|
151 Messages framework |
|
152 ------------------ |
|
153 |
|
154 Django now includes a robust and configurable :doc:`messages framework |
|
155 </ref/contrib/messages>` with built-in support for cookie- and session-based |
|
156 messaging, for both anonymous and authenticated clients. The messages framework |
|
157 replaces the deprecated user message API and allows you to temporarily store |
|
158 messages in one request and retrieve them for display in a subsequent request |
|
159 (usually the next one). |
|
160 |
|
161 Object-level permissions |
|
162 ------------------------ |
|
163 |
|
164 A foundation for specifying permissions at the per-object level has been added. |
|
165 Although there is no implementation of this in core, a custom authentication |
|
166 backend can provide this implementation and it will be used by |
|
167 :class:`django.contrib.auth.models.User`. See the :doc:`authentication docs |
|
168 </topics/auth>` for more information. |
|
169 |
|
170 Permissions for anonymous users |
|
171 ------------------------------- |
|
172 |
|
173 If you provide a custom auth backend with ``supports_anonymous_user`` set to |
|
174 ``True``, AnonymousUser will check the backend for permissions, just like |
|
175 User already did. This is useful for centralizing permission handling - apps |
|
176 can always delegate the question of whether something is allowed or not to |
|
177 the authorization/authentication backend. See the :doc:`authentication |
|
178 docs </topics/auth>` for more details. |
|
179 |
|
180 Relaxed requirements for usernames |
|
181 ---------------------------------- |
|
182 |
|
183 The built-in :class:`~django.contrib.auth.models.User` model's |
|
184 :attr:`~django.contrib.auth.models.User.username` field now allows a wider range |
|
185 of characters, including ``@``, ``+``, ``.`` and ``-`` characters. |
|
186 |
|
187 E-mail backends |
|
188 --------------- |
|
189 |
|
190 You can now :ref:`configure the way that Django sends e-mail |
|
191 <topic-email-backends>`. Instead of using SMTP to send all e-mail, you |
|
192 can now choose a configurable e-mail backend to send messages. If your |
|
193 hosting provider uses a sandbox or some other non-SMTP technique for |
|
194 sending mail, you can now construct an e-mail backend that will allow |
|
195 Django's standard :doc:`mail sending methods</topics/email>` to use |
|
196 those facilities. |
|
197 |
|
198 This also makes it easier to debug mail sending. Django ships with |
|
199 backend implementations that allow you to send e-mail to a |
|
200 :ref:`file<topic-email-file-backend>`, to the |
|
201 :ref:`console<topic-email-console-backend>`, or to |
|
202 :ref:`memory<topic-email-memory-backend>`. You can even configure all |
|
203 e-mail to be :ref:`thrown away<topic-email-dummy-backend>`. |
|
204 |
|
205 .. _new-in-1.2-smart-if: |
|
206 |
|
207 "Smart" :ttag:`if` tag |
|
208 ---------------------- |
|
209 |
|
210 The :ttag:`if` tag has been upgraded to be much more powerful. First, we've |
|
211 added support for comparison operators. No longer will you have to type: |
|
212 |
|
213 .. code-block:: html+django |
|
214 |
|
215 {% ifnotequal a b %} |
|
216 ... |
|
217 {% endifnotequal %} |
|
218 |
|
219 You can now do this: |
|
220 |
|
221 .. code-block:: html+django |
|
222 |
|
223 {% if a != b %} |
|
224 ... |
|
225 {% endif %} |
|
226 |
|
227 There's really no reason to use ``{% ifequal %}`` or ``{% ifnotequal %}`` |
|
228 anymore, unless you're the nostalgic type. |
|
229 |
|
230 The operators supported are ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=``, |
|
231 ``in`` and ``not in``, all of which work like the Python operators, in addition |
|
232 to ``and``, ``or`` and ``not``, which were already supported. |
|
233 |
|
234 Also, filters may now be used in the ``if`` expression. For example: |
|
235 |
|
236 .. code-block:: html+django |
|
237 |
|
238 <div |
|
239 {% if user.email|lower == message.recipient|lower %} |
|
240 class="highlight" |
|
241 {% endif %} |
|
242 >{{ message }}</div> |
|
243 |
|
244 Template caching |
|
245 ---------------- |
|
246 |
|
247 In previous versions of Django, every time you rendered a template, it |
|
248 would be reloaded from disk. In Django 1.2, you can use a :ref:`cached |
|
249 template loader <template-loaders>` to load templates once, then |
|
250 cache the result for every subsequent render. This can lead to a |
|
251 significant performance improvement if your templates are broken into |
|
252 lots of smaller subtemplates (using the ``{% extends %}`` or ``{% |
|
253 include %}`` tags). |
|
254 |
|
255 As a side effect, it is now much easier to support non-Django template |
|
256 languages. For more details, see the :ref:`notes on supporting |
|
257 non-Django template languages<topic-template-alternate-language>`. |
|
258 |
|
259 Natural keys in fixtures |
|
260 ------------------------ |
|
261 |
|
262 Fixtures can now refer to remote objects using |
|
263 :ref:`topics-serialization-natural-keys`. This lookup scheme is an |
|
264 alternative to the normal primary-key based object references in a |
|
265 fixture, improving readability and resolving problems referring to |
|
266 objects whose primary key value may not be predictable or known. |
|
267 |
|
268 Fast failure for tests |
|
269 ---------------------- |
|
270 |
|
271 Both the :djadmin:`test` subcommand of ``django-admin.py`` and the |
|
272 ``runtests.py`` script used to run Django's own test suite now support a |
|
273 ``--failfast`` option. When specified, this option causes the test runner to |
|
274 exit after encountering a failure instead of continuing with the test run. In |
|
275 addition, the handling of ``Ctrl-C`` during a test run has been improved to |
|
276 trigger a graceful exit from the test run that reports details of the tests that |
|
277 were run before the interruption. |
|
278 |
|
279 ``BigIntegerField`` |
|
280 ------------------- |
|
281 |
|
282 Models can now use a 64-bit :class:`~django.db.models.BigIntegerField` type. |
|
283 |
|
284 Improved localization |
|
285 --------------------- |
|
286 |
|
287 Django's :doc:`internationalization framework </topics/i18n/index>` has been expanded |
|
288 with locale-aware formatting and form processing. That means, if enabled, dates |
|
289 and numbers on templates will be displayed using the format specified for the |
|
290 current locale. Django will also use localized formats when parsing data in |
|
291 forms. See :ref:`Format localization <format-localization>` for more details. |
|
292 |
|
293 ``readonly_fields`` in ``ModelAdmin`` |
|
294 ------------------------------------- |
|
295 |
|
296 :attr:`django.contrib.admin.ModelAdmin.readonly_fields` has been added to |
|
297 enable non-editable fields in add/change pages for models and inlines. Field |
|
298 and calculated values can be displayed alongside editable fields. |
|
299 |
|
300 Customizable syntax highlighting |
|
301 -------------------------------- |
|
302 |
|
303 You can now use a ``DJANGO_COLORS`` environment variable to modify or disable |
|
304 the colors used by ``django-admin.py`` to provide :ref:`syntax highlighting |
|
305 <syntax-coloring>`. |
|
306 |
|
307 Syndication feeds as views |
|
308 -------------------------- |
|
309 |
|
310 :doc:`Syndication feeds </ref/contrib/syndication>` can now be used directly as |
|
311 views in your :doc:`URLconf </topics/http/urls>`. This means that you can |
|
312 maintain complete control over the URL structure of your feeds. Like any other |
|
313 view, feeds views are passed a ``request`` object, so you can do anything you |
|
314 would normally do with a view, like user based access control, or making a feed |
|
315 a named URL. |
|
316 |
|
317 GeoDjango |
|
318 --------- |
|
319 |
|
320 The most significant new feature for :doc:`GeoDjango </ref/contrib/gis/index>` |
|
321 in 1.2 is support for multiple spatial databases. As a result, |
|
322 the following :ref:`spatial database backends <spatial-backends>` |
|
323 are now included: |
|
324 |
|
325 * :mod:`django.contrib.gis.db.backends.postgis` |
|
326 * :mod:`django.contrib.gis.db.backends.mysql` |
|
327 * :mod:`django.contrib.gis.db.backends.oracle` |
|
328 * :mod:`django.contrib.gis.db.backends.spatialite` |
|
329 |
|
330 GeoDjango now supports the rich capabilities added |
|
331 in the `PostGIS 1.5 release <http://postgis.refractions.net/documentation/manual-1.5/>`_. |
|
332 New features include suppport for the the :ref:`geography type <geography-type>` |
|
333 and enabling of :ref:`distance queries <distance-queries>` |
|
334 with non-point geometries on geographic coordinate systems. |
|
335 |
|
336 Support for 3D geometry fields was added, and may be enabled |
|
337 by setting the :attr:`~django.contrib.gis.db.models.GeometryField.dim` |
|
338 keyword to 3 in your :class:`~django.contrib.gis.db.models.GeometryField`. |
|
339 The :class:`~django.contrib.gis.db.models.Extent3D` aggregate |
|
340 and :meth:`~django.contrib.gis.db.models.GeoQuerySet.extent3d` ``GeoQuerySet`` |
|
341 method were added as a part of this feature. |
|
342 |
|
343 The following :class:`~django.contrib.gis.db.models.GeoQuerySet` |
|
344 methods are new in 1.2: |
|
345 |
|
346 * :meth:`~django.contrib.gis.db.models.GeoQuerySet.force_rhr` |
|
347 * :meth:`~django.contrib.gis.db.models.GeoQuerySet.reverse_geom` |
|
348 * :meth:`~django.contrib.gis.db.models.GeoQuerySet.geohash` |
|
349 |
|
350 The :ref:`GEOS interface <ref-geos>` was updated to use |
|
351 thread-safe C library functions when available on the platform. |
|
352 |
|
353 The :ref:`GDAL interface <ref-gdal>` now allows the user to |
|
354 set a :attr:`~django.contrib.gis.gdal.Layer.spatial_filter` on |
|
355 the features returned when iterating over a |
|
356 :class:`~django.contrib.gis.gdal.Layer`. |
|
357 |
|
358 Finally, :doc:`GeoDjango's documentation </ref/contrib/gis/index>` is now |
|
359 included with Django's and is no longer |
|
360 hosted separately at `geodjango.org <http://geodjango.org/>`_. |
|
361 |
|
362 .. _1.2-js-assisted-inlines: |
|
363 |
|
364 JavaScript-assisted handling of inline related objects in the admin |
|
365 ------------------------------------------------------------------- |
|
366 |
|
367 If a user has JavaScript enabled in their browser, the interface for |
|
368 inline objects in the admin now allows inline objects to be |
|
369 dynamically added and removed. Users without JavaScript-enabled |
|
370 browsers will see no change in the behavior of inline objects. |
|
371 |
|
372 New ``now`` template tag format specifier characters: ``c`` and ``u`` |
|
373 --------------------------------------------------------------------- |
|
374 |
|
375 The argument to the :ttag:`now` has gained two new format characters: |
|
376 ``c`` to specify that a datetime value should be formatted in ISO 8601 |
|
377 format, and ``u`` that allows output of the microseconds part of a |
|
378 datetime or time value. |
|
379 |
|
380 These are also available in others parts like the :tfilter:`date` and |
|
381 :tfilter:`time` template filters, the ``humanize`` template tag library |
|
382 and the new `format localization`_ framework. |
|
383 |
|
384 .. _format localization: `Improved localization`_ |
|
385 |
|
386 .. _backwards-incompatible-changes-1.2: |
|
387 |
|
388 Backwards-incompatible changes in 1.2 |
|
389 ===================================== |
|
390 |
|
391 Wherever possible the new features above have been introduced in a |
|
392 backwards-compatible manner per :doc:`our API stability policy |
|
393 </misc/api-stability>` policy. This means that practically all existing |
|
394 code which worked with Django 1.1 will continue to work with Django |
|
395 1.2; such code will, however, begin issuing warnings (see below for |
|
396 details). |
|
397 |
|
398 However, a handful of features *have* changed in ways that, for some |
|
399 users, will be immediately backwards-incompatible. Those changes are |
|
400 detailed below. |
|
401 |
|
402 CSRF Protection |
|
403 --------------- |
|
404 |
|
405 We've made large changes to the way CSRF protection works, detailed in |
|
406 :doc:`the CSRF documentaton </ref/contrib/csrf>`. Here are the major changes you |
|
407 should be aware of: |
|
408 |
|
409 * ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated and |
|
410 will be removed completely in Django 1.4, in favor of a template tag that |
|
411 should be inserted into forms. |
|
412 |
|
413 * All contrib apps use a ``csrf_protect`` decorator to protect the view. This |
|
414 requires the use of the ``csrf_token`` template tag in the template. If you |
|
415 have used custom templates for contrib views, you MUST READ THE :ref:`UPGRADE |
|
416 INSTRUCTIONS <ref-csrf-upgrading-notes>` to fix those templates. |
|
417 |
|
418 * ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by |
|
419 default. This turns on CSRF protection by default, so views that accept |
|
420 POST requests need to be written to work with the middleware. Instructions |
|
421 on how to do this are found in the CSRF docs. |
|
422 |
|
423 * All of the CSRF has moved from contrib to core (with backwards |
|
424 compatible imports in the old locations, which are deprecated and |
|
425 will cease to be supported in Django 1.4). |
|
426 |
|
427 ``get_db_prep_*()`` methods on ``Field`` |
|
428 ---------------------------------------- |
|
429 |
|
430 Prior to Django 1.2, a custom ``Field`` had the option of defining |
|
431 several functions to support conversion of Python values into |
|
432 database-compatible values. A custom field might look something like:: |
|
433 |
|
434 class CustomModelField(models.Field): |
|
435 # ... |
|
436 def db_type(self): |
|
437 # ... |
|
438 |
|
439 def get_db_prep_save(self, value): |
|
440 # ... |
|
441 |
|
442 def get_db_prep_value(self, value): |
|
443 # ... |
|
444 |
|
445 def get_db_prep_lookup(self, lookup_type, value): |
|
446 # ... |
|
447 |
|
448 In 1.2, these three methods have undergone a change in prototype, and |
|
449 two extra methods have been introduced:: |
|
450 |
|
451 class CustomModelField(models.Field): |
|
452 # ... |
|
453 |
|
454 def db_type(self, connection): |
|
455 # ... |
|
456 |
|
457 def get_prep_value(self, value): |
|
458 # ... |
|
459 |
|
460 def get_prep_lookup(self, lookup_type, value): |
|
461 # ... |
|
462 |
|
463 def get_db_prep_save(self, value, connection): |
|
464 # ... |
|
465 |
|
466 def get_db_prep_value(self, value, connection, prepared=False): |
|
467 # ... |
|
468 |
|
469 def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False): |
|
470 # ... |
|
471 |
|
472 These changes are required to support multiple databases -- |
|
473 ``db_type`` and ``get_db_prep_*`` can no longer make any assumptions |
|
474 regarding the database for which it is preparing. The ``connection`` |
|
475 argument now provides the preparation methods with the specific |
|
476 connection for which the value is being prepared. |
|
477 |
|
478 The two new methods exist to differentiate general data-preparation |
|
479 requirements from requirements that are database-specific. The |
|
480 ``prepared`` argument is used to indicate to the database-preparation |
|
481 methods whether generic value preparation has been performed. If |
|
482 an unprepared (i.e., ``prepared=False``) value is provided to the |
|
483 ``get_db_prep_*()`` calls, they should invoke the corresponding |
|
484 ``get_prep_*()`` calls to perform generic data preparation. |
|
485 |
|
486 We've provided conversion functions that will transparently |
|
487 convert functions adhering to the old prototype into functions |
|
488 compatible with the new prototype. However, these conversion functions |
|
489 will be removed in Django 1.4, so you should upgrade your ``Field`` |
|
490 definitions to use the new prototype as soon as possible. |
|
491 |
|
492 If your ``get_db_prep_*()`` methods made no use of the database |
|
493 connection, you should be able to upgrade by renaming |
|
494 ``get_db_prep_value()`` to ``get_prep_value()`` and |
|
495 ``get_db_prep_lookup()`` to ``get_prep_lookup()``. If you require |
|
496 database specific conversions, then you will need to provide an |
|
497 implementation ``get_db_prep_*`` that uses the ``connection`` |
|
498 argument to resolve database-specific values. |
|
499 |
|
500 Stateful template tags |
|
501 ---------------------- |
|
502 |
|
503 Template tags that store rendering state on their ``Node`` subclass |
|
504 have always been vulnerable to thread-safety and other issues; as of |
|
505 Django 1.2, however, they may also cause problems when used with the |
|
506 new :ref:`cached template loader<template-loaders>`. |
|
507 |
|
508 All of the built-in Django template tags are safe to use with the cached |
|
509 loader, but if you're using custom template tags that come from third |
|
510 party packages, or from your own code, you should ensure that the |
|
511 ``Node`` implementation for each tag is thread-safe. For more |
|
512 information, see |
|
513 :ref:`template tag thread safety considerations<template_tag_thread_safety>`. |
|
514 |
|
515 You may also need to update your templates if you were relying on the |
|
516 implementation of Django's template tags *not* being thread safe. The |
|
517 :ttag:`cycle` tag is the most likely to be affected in this way, |
|
518 especially when used in conjunction with the :ttag:`include` tag. |
|
519 Consider the following template fragment:: |
|
520 |
|
521 {% for object in object_list %} |
|
522 {% include "subtemplate.html" %} |
|
523 {% endfor %} |
|
524 |
|
525 with a ``subtemplate.html`` that reads:: |
|
526 |
|
527 {% cycle 'even' 'odd' %} |
|
528 |
|
529 Using the non-thread-safe, pre-Django 1.2 renderer, this would output:: |
|
530 |
|
531 even odd even odd ... |
|
532 |
|
533 Using the thread-safe Django 1.2 renderer, you will instead get:: |
|
534 |
|
535 even even even even ... |
|
536 |
|
537 This is because each rendering of the :ttag:`include` tag is an |
|
538 independent rendering. When the :ttag:`cycle` tag was not thread safe, |
|
539 the state of the :ttag:`cycle` tag would leak between multiple |
|
540 renderings of the same :ttag:`include`. Now that the :ttag:`cycle` tag |
|
541 is thread safe, this leakage no longer occurs. |
|
542 |
|
543 ``user_passes_test``, ``login_required`` and ``permission_required`` |
|
544 -------------------------------------------------------------------- |
|
545 |
|
546 ``django.contrib.auth.decorators`` provides the decorators |
|
547 ``login_required``, ``permission_required`` and |
|
548 ``user_passes_test``. Previously it was possible to use these |
|
549 decorators both on functions (where the first argument is 'request') |
|
550 and on methods (where the first argument is 'self', and the second |
|
551 argument is 'request'). Unfortunately, flaws were discovered in the |
|
552 code supporting this: it only works in limited circumstances, and |
|
553 produces errors that are very difficult to debug when it does not |
|
554 work. |
|
555 |
|
556 For this reason, the 'auto adapt' behavior has been removed, and if |
|
557 you are using these decorators on methods, you will need to manually |
|
558 apply :func:`django.utils.decorators.method_decorator` to convert the |
|
559 decorator to one that works with methods. For example, you would |
|
560 change code from this:: |
|
561 |
|
562 class MyClass(object): |
|
563 |
|
564 @login_required |
|
565 def my_view(self, request): |
|
566 pass |
|
567 |
|
568 to this:: |
|
569 |
|
570 from django.utils.decorators import method_decorator |
|
571 |
|
572 class MyClass(object): |
|
573 |
|
574 @method_decorator(login_required) |
|
575 def my_view(self, request): |
|
576 pass |
|
577 |
|
578 or:: |
|
579 |
|
580 from django.utils.decorators import method_decorator |
|
581 |
|
582 login_required_m = method_decorator(login_required) |
|
583 |
|
584 class MyClass(object): |
|
585 |
|
586 @login_required_m |
|
587 def my_view(self, request): |
|
588 pass |
|
589 |
|
590 For those of you who've been following the development trunk, this |
|
591 change also applies to other decorators introduced since 1.1, |
|
592 including ``csrf_protect``, ``cache_control`` and anything created |
|
593 using ``decorator_from_middleware``. |
|
594 |
|
595 :ttag:`if` tag changes |
|
596 ---------------------- |
|
597 |
|
598 Due to new features in the :ttag:`if` template tag, it no longer |
|
599 accepts 'and', 'or' and 'not' as valid **variable** names. Previously, |
|
600 these strings could be used as variable names. Now, the keyword status |
|
601 is always enforced, and template code such as ``{% if not %}`` or ``{% |
|
602 if and %}`` will throw a ``TemplateSyntaxError``. Also, ``in`` is a |
|
603 new keyword and so is not a valid variable name in this tag. |
|
604 |
|
605 ``LazyObject`` |
|
606 -------------- |
|
607 |
|
608 ``LazyObject`` is an undocumented-but-often-used utility class used for lazily |
|
609 wrapping other objects of unknown type. |
|
610 |
|
611 In Django 1.1 and earlier, it handled introspection in a non-standard way, |
|
612 depending on wrapped objects implementing a public method named |
|
613 ``get_all_members()``. Since this could easily lead to name clashes, it has been |
|
614 changed to use the standard Python introspection method, involving |
|
615 ``__members__`` and ``__dir__()``. |
|
616 |
|
617 If you used ``LazyObject`` in your own code |
|
618 and implemented the ``get_all_members()`` method for wrapped objects, you'll need |
|
619 to make a couple of changes: |
|
620 |
|
621 First, if your class does not have special requirements for introspection (i.e., |
|
622 you have not implemented ``__getattr__()`` or other methods that allow for |
|
623 attributes not discoverable by normal mechanisms), you can simply remove the |
|
624 ``get_all_members()`` method. The default implementation on ``LazyObject`` will |
|
625 do the right thing. |
|
626 |
|
627 If you have more complex requirements for introspection, first rename the |
|
628 ``get_all_members()`` method to ``__dir__()``. This is the standard |
|
629 introspection method for Python 2.6 and above. If you require support for Python |
|
630 versions earlier than 2.6, add the following code to the class:: |
|
631 |
|
632 __members__ = property(lambda self: self.__dir__()) |
|
633 |
|
634 ``__dict__`` on model instances |
|
635 ------------------------------- |
|
636 |
|
637 Historically, the ``__dict__`` attribute of a model instance has only contained |
|
638 attributes corresponding to the fields on a model. |
|
639 |
|
640 In order to support multiple database configurations, Django 1.2 has |
|
641 added a ``_state`` attribute to object instances. This attribute will |
|
642 appear in ``__dict__`` for a model instance. If your code relies on |
|
643 iterating over ``__dict__`` to obtain a list of fields, you must now |
|
644 be prepared to handle or filter out the ``_state`` attribute. |
|
645 |
|
646 Test runner exit status code |
|
647 ---------------------------- |
|
648 |
|
649 The exit status code of the test runners (``tests/runtests.py`` and ``python |
|
650 manage.py test``) no longer represents the number of failed tests, because a |
|
651 failure of 256 or more tests resulted in a wrong exit status code. The exit |
|
652 status code for the test runner is now 0 for success (no failing tests) and 1 |
|
653 for any number of test failures. If needed, the number of test failures can be |
|
654 found at the end of the test runner's output. |
|
655 |
|
656 Cookie encoding |
|
657 --------------- |
|
658 |
|
659 To fix bugs with cookies in Internet Explorer, Safari, and possibly |
|
660 other browsers, our encoding of cookie values was changed so that the |
|
661 comma and semicolon are treated as non-safe characters, and are |
|
662 therefore encoded as ``\054`` and ``\073`` respectively. This could |
|
663 produce backwards incompatibilities, especially if you are storing |
|
664 comma or semi-colon in cookies and have javascript code that parses |
|
665 and manipulates cookie values client-side. |
|
666 |
|
667 ``ModelForm.is_valid()`` and ``ModelForm.errors`` |
|
668 ------------------------------------------------- |
|
669 |
|
670 Much of the validation work for ModelForms has been moved down to the model |
|
671 level. As a result, the first time you call ``ModelForm.is_valid()``, access |
|
672 ``ModelForm.errors`` or otherwise trigger form validation, your model will be |
|
673 cleaned in-place. This conversion used to happen when the model was saved. If |
|
674 you need an unmodified instance of your model, you should pass a copy to the |
|
675 ``ModelForm`` constructor. |
|
676 |
|
677 ``BooleanField`` on MySQL |
|
678 -------------------------- |
|
679 |
|
680 In previous versions of Django, a model's ``BooleanField`` under MySQL |
|
681 would return its value as either ``1`` or ``0``, instead of ``True`` |
|
682 or ``False``; for most people this wasn't a problem because ``bool`` |
|
683 is a subclass of ``int`` in Python. In Django 1.2, however, |
|
684 ``BooleanField`` on MySQL correctly returns a real ``bool``. The only |
|
685 time this should ever be an issue is if you were expecting the |
|
686 ``repr`` of a ``BooleanField`` to print ``1`` or ``0``. |
|
687 |
|
688 Changes to the interpretation of ``max_num`` in FormSets |
|
689 -------------------------------------------------------- |
|
690 |
|
691 As part of enhancements made to the handling of FormSets, the default |
|
692 value and interpretation of the ``max_num`` parameter to the |
|
693 :ref:`django.forms.formsets.formset_factory() <formsets-max-num>` and |
|
694 :ref:`django.forms.models.modelformset_factory() |
|
695 <model-formsets-max-num>` functions has changed slightly. This |
|
696 change also affects the way the ``max_num`` argument is :ref:`used for |
|
697 inline admin objects <ref-contrib-admin-inline-max-num>` |
|
698 |
|
699 Previously, the default value for ``max_num`` was ``0`` (zero). |
|
700 FormSets then used the boolean value of ``max_num`` to determine if a |
|
701 limit was to be imposed on the number of generated forms. The default |
|
702 value of ``0`` meant that there was no default limit on the number of |
|
703 forms in a FormSet. |
|
704 |
|
705 Starting with 1.2, the default value for ``max_num`` has been changed |
|
706 to ``None``, and FormSets will differentiate between a value of |
|
707 ``None`` and a value of ``0``. A value of ``None`` indicates that no |
|
708 limit on the number of forms is to be imposed; a value of ``0`` |
|
709 indicates that a maximum of 0 forms should be imposed. This doesn't |
|
710 necessarily mean that no forms will be displayed -- see the |
|
711 :ref:`ModelFormSet documentation <model-formsets-max-num>` for more |
|
712 details. |
|
713 |
|
714 If you were manually specifying a value of ``0`` for ``max_num``, you |
|
715 will need to update your FormSet and/or admin definitions. |
|
716 |
|
717 .. seealso:: |
|
718 |
|
719 :ref:`1.2-js-assisted-inlines` |
|
720 |
|
721 ``email_re`` |
|
722 ------------ |
|
723 |
|
724 An undocumented regular expression for validating email addresses has been moved |
|
725 from ``django.form.fields`` to ``django.core.validators``. You will need to |
|
726 update your imports if you are using it. |
|
727 |
|
728 .. _deprecated-features-1.2: |
|
729 |
|
730 Features deprecated in 1.2 |
|
731 ========================== |
|
732 |
|
733 Finally, Django 1.2 deprecates some features from earlier releases. |
|
734 These features are still supported, but will be gradually phased out |
|
735 over the next few release cycles. |
|
736 |
|
737 Code taking advantage of any of the features below will raise a |
|
738 ``PendingDeprecationWarning`` in Django 1.2. This warning will be |
|
739 silent by default, but may be turned on using Python's `warnings |
|
740 module`_, or by running Python with a ``-Wd`` or `-Wall` flag. |
|
741 |
|
742 .. _warnings module: http://docs.python.org/library/warnings.html |
|
743 |
|
744 In Django 1.3, these warnings will become a ``DeprecationWarning``, |
|
745 which is *not* silent. In Django 1.4 support for these features will |
|
746 be removed entirely. |
|
747 |
|
748 .. seealso:: |
|
749 |
|
750 For more details, see the documentation :doc:`Django's release process |
|
751 </internals/release-process>` and our :doc:`deprecation timeline |
|
752 </internals/deprecation>`.` |
|
753 |
|
754 .. _specifying-databases: |
|
755 |
|
756 Specifying databases |
|
757 -------------------- |
|
758 |
|
759 Prior to Django 1.2, Django used a number of settings to control |
|
760 access to a single database. Django 1.2 introduces support for |
|
761 multiple databases, and as a result the way you define database |
|
762 settings has changed. |
|
763 |
|
764 Any existing Django settings file will continue to work as expected |
|
765 until Django 1.4. Until then, old-style database settings will be |
|
766 automatically translated to the new-style format. |
|
767 |
|
768 In the old-style (pre 1.2) format, you had a number of ``DATABASE_`` |
|
769 settings in your settings file. For example:: |
|
770 |
|
771 DATABASE_NAME = 'test_db' |
|
772 DATABASE_ENGINE = 'postgresql_psycopg2' |
|
773 DATABASE_USER = 'myusername' |
|
774 DATABASE_PASSWORD = 's3krit' |
|
775 |
|
776 These settings are now in a dictionary named |
|
777 :setting:`DATABASES`. Each item in the dictionary corresponds to a |
|
778 single database connection, with the name ``'default'`` describing the |
|
779 default database connection. The setting names have also been |
|
780 shortened. The previous sample settings would now look like this:: |
|
781 |
|
782 DATABASES = { |
|
783 'default': { |
|
784 'NAME': 'test_db', |
|
785 'ENGINE': 'django.db.backends.postgresql_psycopg2', |
|
786 'USER': 'myusername', |
|
787 'PASSWORD': 's3krit', |
|
788 } |
|
789 } |
|
790 |
|
791 This affects the following settings: |
|
792 |
|
793 ========================================= ========================== |
|
794 Old setting New Setting |
|
795 ========================================= ========================== |
|
796 :setting:`DATABASE_ENGINE` :setting:`ENGINE` |
|
797 :setting:`DATABASE_HOST` :setting:`HOST` |
|
798 :setting:`DATABASE_NAME` :setting:`NAME` |
|
799 :setting:`DATABASE_OPTIONS` :setting:`OPTIONS` |
|
800 :setting:`DATABASE_PASSWORD` :setting:`PASSWORD` |
|
801 :setting:`DATABASE_PORT` :setting:`PORT` |
|
802 :setting:`DATABASE_USER` :setting:`USER` |
|
803 :setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET` |
|
804 :setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION` |
|
805 :setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME` |
|
806 ========================================= ========================== |
|
807 |
|
808 These changes are also required if you have manually created a database |
|
809 connection using ``DatabaseWrapper()`` from your database backend of choice. |
|
810 |
|
811 In addition to the change in structure, Django 1.2 removes the special |
|
812 handling for the built-in database backends. All database backends |
|
813 must now be specified by a fully qualified module name (i.e., |
|
814 ``django.db.backends.postgresql_psycopg2``, rather than just |
|
815 ``postgresql_psycopg2``). |
|
816 |
|
817 ``postgresql`` database backend |
|
818 ------------------------------- |
|
819 |
|
820 The ``psycopg1`` library has not been updated since October 2005. As a |
|
821 result, the ``postgresql`` database backend, which uses this library, |
|
822 has been deprecated. |
|
823 |
|
824 If you are currently using the ``postgresql`` backend, you should |
|
825 migrate to using the ``postgresql_psycopg2`` backend. To update your |
|
826 code, install the ``psycopg2`` library and change the |
|
827 :setting:`DATABASE_ENGINE` setting to use |
|
828 ``django.db.backends.postgresql_psycopg2``. |
|
829 |
|
830 CSRF response-rewriting middleware |
|
831 ---------------------------------- |
|
832 |
|
833 ``CsrfResponseMiddleware``, the middleware that automatically inserted |
|
834 CSRF tokens into ``POST`` forms in outgoing pages, has been deprecated |
|
835 in favor of a template tag method (see above), and will be removed |
|
836 completely in Django 1.4. ``CsrfMiddleware``, which includes the |
|
837 functionality of ``CsrfResponseMiddleware`` and |
|
838 ``CsrfViewMiddleware``, has likewise been deprecated. |
|
839 |
|
840 Also, the CSRF module has moved from contrib to core, and the old |
|
841 imports are deprecated, as described in the :ref:`upgrading notes |
|
842 <ref-csrf-upgrading-notes>`. |
|
843 |
|
844 ``SMTPConnection`` |
|
845 ------------------ |
|
846 |
|
847 The ``SMTPConnection`` class has been deprecated in favor of a generic |
|
848 e-mail backend API. Old code that explicitly instantiated an instance |
|
849 of an SMTPConnection:: |
|
850 |
|
851 from django.core.mail import SMTPConnection |
|
852 connection = SMTPConnection() |
|
853 messages = get_notification_email() |
|
854 connection.send_messages(messages) |
|
855 |
|
856 ...should now call :meth:`~django.core.mail.get_connection()` to |
|
857 instantiate a generic e-mail connection:: |
|
858 |
|
859 from django.core.mail import get_connection |
|
860 connection = get_connection() |
|
861 messages = get_notification_email() |
|
862 connection.send_messages(messages) |
|
863 |
|
864 Depending on the value of the :setting:`EMAIL_BACKEND` setting, this |
|
865 may not return an SMTP connection. If you explicitly require an SMTP |
|
866 connection with which to send e-mail, you can explicitly request an |
|
867 SMTP connection:: |
|
868 |
|
869 from django.core.mail import get_connection |
|
870 connection = get_connection('django.core.mail.backends.smtp.EmailBackend') |
|
871 messages = get_notification_email() |
|
872 connection.send_messages(messages) |
|
873 |
|
874 If your call to construct an instance of ``SMTPConnection`` required |
|
875 additional arguments, those arguments can be passed to the |
|
876 :meth:`~django.core.mail.get_connection()` call:: |
|
877 |
|
878 connection = get_connection('django.core.mail.backends.smtp.EmailBackend', hostname='localhost', port=1234) |
|
879 |
|
880 User Messages API |
|
881 ----------------- |
|
882 |
|
883 The API for storing messages in the user ``Message`` model (via |
|
884 ``user.message_set.create``) is now deprecated and will be removed in Django |
|
885 1.4 according to the standard :doc:`release process </internals/release-process>`. |
|
886 |
|
887 To upgrade your code, you need to replace any instances of this:: |
|
888 |
|
889 user.message_set.create('a message') |
|
890 |
|
891 ...with the following:: |
|
892 |
|
893 from django.contrib import messages |
|
894 messages.add_message(request, messages.INFO, 'a message') |
|
895 |
|
896 Additionally, if you make use of the method, you need to replace the |
|
897 following:: |
|
898 |
|
899 for message in user.get_and_delete_messages(): |
|
900 ... |
|
901 |
|
902 ...with:: |
|
903 |
|
904 from django.contrib import messages |
|
905 for message in messages.get_messages(request): |
|
906 ... |
|
907 |
|
908 For more information, see the full |
|
909 :doc:`messages documentation </ref/contrib/messages>`. You should begin to |
|
910 update your code to use the new API immediately. |
|
911 |
|
912 Date format helper functions |
|
913 ---------------------------- |
|
914 |
|
915 ``django.utils.translation.get_date_formats()`` and |
|
916 ``django.utils.translation.get_partial_date_formats()`` have been deprecated |
|
917 in favor of the appropriate calls to ``django.utils.formats.get_format()``, |
|
918 which is locale-aware when :setting:`USE_L10N` is set to ``True``, and falls |
|
919 back to default settings if set to ``False``. |
|
920 |
|
921 To get the different date formats, instead of writing this:: |
|
922 |
|
923 from django.utils.translation import get_date_formats |
|
924 date_format, datetime_format, time_format = get_date_formats() |
|
925 |
|
926 ...use:: |
|
927 |
|
928 from django.utils import formats |
|
929 date_format = formats.get_format('DATE_FORMAT') |
|
930 datetime_format = formats.get_format('DATETIME_FORMAT') |
|
931 time_format = formats.get_format('TIME_FORMAT') |
|
932 |
|
933 Or, when directly formatting a date value:: |
|
934 |
|
935 from django.utils import formats |
|
936 value_formatted = formats.date_format(value, 'DATETIME_FORMAT') |
|
937 |
|
938 The same applies to the globals found in ``django.forms.fields``: |
|
939 |
|
940 * ``DEFAULT_DATE_INPUT_FORMATS`` |
|
941 * ``DEFAULT_TIME_INPUT_FORMATS`` |
|
942 * ``DEFAULT_DATETIME_INPUT_FORMATS`` |
|
943 |
|
944 Use ``django.utils.formats.get_format()`` to get the appropriate formats. |
|
945 |
|
946 Function-based test runners |
|
947 --------------------------- |
|
948 |
|
949 Django 1.2 changes the test runner tools to use a class-based |
|
950 approach. Old style function-based test runners will still work, but |
|
951 should be updated to use the new :ref:`class-based runners |
|
952 <topics-testing-test_runner>`. |
|
953 |
|
954 .. _1.2-updating-feeds: |
|
955 |
|
956 ``Feed`` in ``django.contrib.syndication.feeds`` |
|
957 ------------------------------------------------ |
|
958 |
|
959 The :class:`django.contrib.syndication.feeds.Feed` class has been |
|
960 replaced by the :class:`django.contrib.syndication.views.Feed` class. |
|
961 The old ``feeds.Feed`` class is deprecated, and will be removed in |
|
962 Django 1.4. |
|
963 |
|
964 The new class has an almost identical API, but allows instances to be |
|
965 used as views. For example, consider the use of the old framework in |
|
966 the following :doc:`URLconf </topics/http/urls>`:: |
|
967 |
|
968 from django.conf.urls.defaults import * |
|
969 from myproject.feeds import LatestEntries, LatestEntriesByCategory |
|
970 |
|
971 feeds = { |
|
972 'latest': LatestEntries, |
|
973 'categories': LatestEntriesByCategory, |
|
974 } |
|
975 |
|
976 urlpatterns = patterns('', |
|
977 # ... |
|
978 (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', |
|
979 {'feed_dict': feeds}), |
|
980 # ... |
|
981 ) |
|
982 |
|
983 Using the new Feed class, these feeds can be deployed directly as views:: |
|
984 |
|
985 from django.conf.urls.defaults import * |
|
986 from myproject.feeds import LatestEntries, LatestEntriesByCategory |
|
987 |
|
988 urlpatterns = patterns('', |
|
989 # ... |
|
990 (r'^feeds/latest/$', LatestEntries()), |
|
991 (r'^feeds/categories/(?P<category_id>\d+)/$', LatestEntriesByCategory()), |
|
992 # ... |
|
993 ) |
|
994 |
|
995 If you currently use the ``feed()`` view, the ``LatestEntries`` class would |
|
996 often not need to be modified apart from subclassing the new |
|
997 :class:`~django.contrib.syndication.views.Feed` class. The exception is if |
|
998 Django was automatically working out the name of the template to use to render |
|
999 the feed's description and title elements (if you were not specifying the |
|
1000 ``title_template`` and ``description_template`` attributes). You should ensure |
|
1001 that you always specify ``title_template`` and ``description_template`` |
|
1002 attributes, or provide ``item_title()`` and ``item_description()`` methods. |
|
1003 |
|
1004 However, ``LatestEntriesByCategory`` uses the ``get_object()`` method |
|
1005 with the ``bits`` argument to specify a specific category to show. In |
|
1006 the new :class:`~django.contrib.syndication.views.Feed` class, |
|
1007 ``get_object()`` method takes a ``request`` and arguments from the |
|
1008 URL, so it would look like this:: |
|
1009 |
|
1010 from django.contrib.syndication.views import Feed |
|
1011 from django.shortcuts import get_object_or_404 |
|
1012 from myproject.models import Category |
|
1013 |
|
1014 class LatestEntriesByCategory(Feed): |
|
1015 def get_object(self, request, category_id): |
|
1016 return get_object_or_404(Category, id=category_id) |
|
1017 |
|
1018 # ... |
|
1019 |
|
1020 Additionally, the ``get_feed()`` method on ``Feed`` classes now take |
|
1021 different arguments, which may impact you if you use the ``Feed`` |
|
1022 classes directly. Instead of just taking an optional ``url`` argument, |
|
1023 it now takes two arguments: the object returned by its own |
|
1024 ``get_object()`` method, and the current ``request`` object. |
|
1025 |
|
1026 To take into account ``Feed`` classes not being initialized for each |
|
1027 request, the ``__init__()`` method now takes no arguments by default. |
|
1028 Previously it would have taken the ``slug`` from the URL and the |
|
1029 ``request`` object. |
|
1030 |
|
1031 In accordance with `RSS best practices`_, RSS feeds will now include |
|
1032 an ``atom:link`` element. You may need to update your tests to take |
|
1033 this into account. |
|
1034 |
|
1035 For more information, see the full :doc:`syndication framework |
|
1036 documentation </ref/contrib/syndication>`. |
|
1037 |
|
1038 .. _RSS best practices: http://www.rssboard.org/rss-profile |
|
1039 |
|
1040 Technical message IDs |
|
1041 --------------------- |
|
1042 |
|
1043 Up to version 1.1 Django used :ref:`technical message IDs<technical-messages>` |
|
1044 to provide localizers the possibility to translate date and time formats. They |
|
1045 were translatable :term:`translation strings <translation string>` that could |
|
1046 be recognized because they were all upper case (for example |
|
1047 ``DATETIME_FORMAT``, ``DATE_FORMAT``, ``TIME_FORMAT``). They have been |
|
1048 deprecated in favor of the new :ref:`Format localization |
|
1049 <format-localization>` infrastructure that allows localizers to specify that |
|
1050 information in a ``formats.py`` file in the corresponding |
|
1051 ``django/conf/locale/<locale name>/`` directory. |
|
1052 |
|
1053 GeoDjango |
|
1054 --------- |
|
1055 |
|
1056 To allow support for multiple databases, the GeoDjango database internals were |
|
1057 changed substantially. The largest backwards-incompatible change is that |
|
1058 the module ``django.contrib.gis.db.backend`` was renamed to |
|
1059 :mod:`django.contrib.gis.db.backends`, where the full-fledged |
|
1060 :ref:`spatial database backends <spatial-backends>` now exist. The |
|
1061 following sections provide information on the most-popular APIs that |
|
1062 were affected by these changes. |
|
1063 |
|
1064 ``SpatialBackend`` |
|
1065 ^^^^^^^^^^^^^^^^^^ |
|
1066 |
|
1067 Prior to the creation of the separate spatial backends, the |
|
1068 ``django.contrib.gis.db.backend.SpatialBackend`` object was |
|
1069 provided as an abstraction to introspect on the capabilities of |
|
1070 the spatial database. All of the attributes and routines provided by |
|
1071 ``SpatialBackend`` are now a part of the ``ops`` attribute of the |
|
1072 database backend. |
|
1073 |
|
1074 The old module ``django.contrib.gis.db.backend`` is still provided |
|
1075 for backwards-compatibility access to a ``SpatialBackend`` object, |
|
1076 which is just an alias to the ``ops`` module of the |
|
1077 *default* spatial database connection. |
|
1078 |
|
1079 Users that were relying on undocumented modules and objects |
|
1080 within ``django.contrib.gis.db.backend``, rather the abstractions |
|
1081 provided by ``SpatialBackend``, are required to modify their code. |
|
1082 For example, the following import which would work in 1.1 and |
|
1083 below:: |
|
1084 |
|
1085 from django.contrib.gis.db.backend.postgis import PostGISAdaptor |
|
1086 |
|
1087 Would need to be changed:: |
|
1088 |
|
1089 from django.db import connection |
|
1090 PostGISAdaptor = connection.ops.Adapter |
|
1091 |
|
1092 ``SpatialRefSys`` and ``GeometryColumns`` models |
|
1093 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
1094 |
|
1095 In previous versions of GeoDjango, :mod:`django.contrib.gis.db.models` |
|
1096 had ``SpatialRefSys`` and ``GeometryColumns`` models for querying |
|
1097 the OGC spatial metadata tables ``spatial_ref_sys`` and ``geometry_columns``, |
|
1098 respectively. |
|
1099 |
|
1100 While these aliases are still provided, they are only for the |
|
1101 *default* database connection and exist only if the default connection |
|
1102 is using a supported spatial database backend. |
|
1103 |
|
1104 .. note:: |
|
1105 |
|
1106 Because the table structure of the OGC spatial metadata tables |
|
1107 differs across spatial databases, the ``SpatialRefSys`` and |
|
1108 ``GeometryColumns`` models can no longer be associated with |
|
1109 the ``gis`` application name. Thus, no models will be returned |
|
1110 when using the ``get_models`` method in the following example:: |
|
1111 |
|
1112 >>> from django.db.models import get_app, get_models |
|
1113 >>> get_models(get_app('gis')) |
|
1114 [] |
|
1115 |
|
1116 To get the correct ``SpatialRefSys`` and ``GeometryColumns`` |
|
1117 for your spatial database use the methods provided by the spatial backend:: |
|
1118 |
|
1119 >>> from django.db import connections |
|
1120 >>> SpatialRefSys = connections['my_spatialite'].ops.spatial_ref_sys() |
|
1121 >>> GeometryColumns = connections['my_postgis'].ops.geometry_columns() |
|
1122 |
|
1123 .. note:: |
|
1124 |
|
1125 When using the models returned from the ``spatial_ref_sys()`` and |
|
1126 ``geometry_columns()`` method, you'll still need to use the |
|
1127 correct database alias when querying on the non-default connection. |
|
1128 In other words, to ensure that the models in the example above |
|
1129 use the correct database:: |
|
1130 |
|
1131 sr_qs = SpatialRefSys.objects.using('my_spatialite').filter(...) |
|
1132 gc_qs = GeometryColumns.objects.using('my_postgis').filter(...) |
|
1133 |
|
1134 Language code ``no`` |
|
1135 -------------------- |
|
1136 |
|
1137 The currently used language code for Norwegian Bokmål ``no`` is being |
|
1138 replaced by the more common language code ``nb``. |
|
1139 |