Django

Code

Ticket #8438: t8438-r8767.diff

File t8438-r8767.diff, 20.5 kB (added by ramiro, 4 months ago)

Please disregard previous bogus patch, use this instead. Aplly with patch -p1

  • a/docs/releases/index.txt

    old new  
    99 
    1010.. toctree:: 
    1111   :maxdepth: 1 
    12     
     12 
    1313   0.95 
    1414   0.96 
    1515   1.0-alpha-1 
    1616   1.0-alpha-2 
    1717   1.0-beta 
    1818   1.0-beta-2 
     19   porting-guide 
    1920 
    2021.. seealso:: 
    2122 
     
    2324    development "trunk". If you're running versions of Django newer than an 
    2425    official release, you should keep track of new pieces pointed there. It's 
    2526    also fun reading if you're looking forward to new versions of Django. 
    26      
     27 
    2728.. _backwards-incompatible changes: http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges 
  • /dev/null

    old new  
     1======================== 
     2Porting 0.96 apps to 1.0 
     3======================== 
     4 
     5Version 1.0 breaks compatibility with 0.96. 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 `Other Changes`_ for a list of all compatibility issues. 
     6 
     7Common Changes 
     8============== 
     9 
     10models 
     11------ 
     12    * The ``maxlength`` argument for model fields was replaced with ``max_length``. 
     13    * Rename your model's ``__str__`` function to ``__unicode__`` and use unicode strings: ``u'foo'`` instead of ``'foo'``. 
     14    * The ``prepopulated_from`` argument for model fields has been moved to the ``AdminModel`` class in ``admin.py`` (see below). 
     15    * All of the Admin definitions moved from the ``Model`` definition to the new ``AdminModel`` class stored in an ``admin.py`` file. You can read about the new class in `The Django admin site`_. Here is an example with some of the most common changes:: 
     16 
     17        # 0.96: 
     18        class Author(models.Model): 
     19            first_name = models.CharField(maxlength=30) 
     20            last_name = models.CharField(maxlength=30) 
     21            slug = models.CharField(max_length=60, prepopulate_from=('first_name', 'last_name')) 
     22 
     23            class Admin: 
     24                 fields = ( 
     25                     ('full name', {'fields': ('first_name','last_name'), 'classes': 'collapse wide'}), 
     26                 ) 
     27                 js = ( 
     28                     "/static/my_code.js", 
     29                 ) 
     30 
     31         class Book(models.Model): 
     32             author = models.ForeignKey(Author, edit_inline=models.TABULAR) 
     33             title = models.CharField(maxlength=100) 
     34 
     35        # 1.0: 
     36        class Author(models.Model): 
     37            first_name = models.CharField(max_length=30) 
     38            last_name = models.CharField(max_length=30) 
     39 
     40        class Book(models.Model): 
     41            author = models.ForeignKey(Author) 
     42            title = models.CharField(max_length=100) 
     43 
     44        # admin.py 
     45        from django.contrib import admin 
     46        from models import Book, Author 
     47 
     48        class BookInline(admin.TabularInline): 
     49            model = Book 
     50            extra = 3 
     51 
     52        class AuthorAdmin(admin.ModelAdmin): 
     53            inlines = [BookInline] 
     54            fieldsets = ( 
     55                ('full name', {'fields': ('first_name','last_name'), 'classes': ('collapse', 'wide')}), 
     56            ) 
     57            prepopulated_fields = {'slug': ('first_name', 'last_name')} 
     58 
     59            class Media: 
     60                js = ( 
     61                    "/static/my_code.js", 
     62                ) 
     63        admin.site.register(Author, AuthorAdmin) 
     64 
     65      NOTE: There is a script_ that scans your models.py and automatically outputs the corresponding source code for ``admin.py``. 
     66 
     67.. _The Django admin site: http://docs.djangoproject.com/en/dev/ref/contrib/admin/ 
     68.. _script: http://www.djangosnippets.org/snippets/603/ 
     69 
     70 
     71Templates 
     72--------- 
     73    * By default the templating system automatically escapes the output of every variable tag.  To learn more take a look at `automatic html escaping`_. To disable auto-escaping for an individual variable, use the safe filter:: 
     74 
     75        This will be escaped: {{ data }} 
     76        This will not be escaped: {{ data|safe }} 
     77 
     78      To disable auto-escaping for an entire template, wrap the template (or just a particular section of the template) in the autoescape tag, like so:: 
     79 
     80        {% autoescape off %} 
     81           ... normal template content here ... 
     82        {% endautoescape %} 
     83 
     84.. _automatic html escaping: http://docs.djangoproject.com/en/dev/topics/templates/#automatic-html-escaping 
     85 
     86urls 
     87---- 
     88    * If you are using the Admin you need to update your root ``urls.py``:: 
     89 
     90        # 0.96: 
     91        from django.conf.urls.defaults import * 
     92 
     93        urlpatterns = patterns('', 
     94            (r'^admin/', include('django.contrib.admin.urls')), 
     95        ) 
     96 
     97        # 1.0: 
     98        from django.conf.urls.defaults import * 
     99        from django.contrib import admin 
     100 
     101        # automatically load the INSTALLED_APPS admin.py modules 
     102        admin.autodiscover() 
     103 
     104        urlpatterns = patterns('', 
     105            (r'^admin/doc/', include('django.contrib.admindocs.urls')), 
     106            (r'^admin/(.*)', admin.site.root), 
     107        ) 
     108 
     109views 
     110----- 
     111    * With 1.0 ``newforms`` were renamed ``forms`` and ``oldforms`` were removed. If you are already using new forms all you have to do is change your import statement:: 
     112 
     113        # 0.96 
     114        from django import newforms as forms 
     115 
     116        # 1.0 
     117        from django import forms 
     118 
     119       If you are using the old forms, you will have to rewrite your forms - a good place to start is the `forms documentation`_. 
     120 
     121.. _forms documentation: http://docs.djangoproject.com/en/dev/topics/forms/ 
     122 
     123    * In 0.96 uploaded files -- that is, entries in ``request.FILES`` -- were represented by simple dictionaries with a few well-known keys. Uploaded files are now represented by an `UploadedFile object`_, and thus the file's information is accessible through object attributes. Thus, given ``f = request.FILES['file_field_name']``: 
     124 
     125        ===================== ===================== 
     126        0.96                  1.0 
     127        ===================== ===================== 
     128        ``f['content']``      ``f.read()`` 
     129        ``f['filename']``     ``f.name`` 
     130        ``f['content-type']`` ``f.content_type`` 
     131        ===================== ===================== 
     132 
     133.. _UploadedFile object: http://docs.djangoproject.com/en/dev/topics/http/file-uploads/#uploadedfile-objects 
     134 
     135Signals 
     136------- 
     137    * All handlers now must be declared as accepting ``**kwargs``. 
     138    * Signals are now instances of ``django.dispatch.Signal`` instead of anonymous objects. 
     139    * Connecting, disconnecting, and sending signals are done via methods on the ``Signal`` object instead of through module methods in ``django.dispatch.dispatcher``. The module-level methods are deprecated. 
     140    * The ``Anonymous`` and ``Any`` sender options no longer exist. You can still receive signals sent by any sender by using ``sender=None`` 
     141    * So, a quick summary of the code changes you'd need to make: 
     142 
     143        ========================================================= ================================================ 
     144        0.96                                                      1.0 
     145        ========================================================= ================================================ 
     146        ``def my_handler(sender)``                                ``def my_handler(sender, **kwargs)`` 
     147        ``my_signal = object()``                                  ``my_signal = django.dispatch.Signal()`` 
     148        ``dispatcher.connect(my_handler, my_signal)``             ``my_signal.connect(my_handler)`` 
     149        ``dispatcher.send(my_signal, sender)``                    ``my_signal.send(sender)`` 
     150        ``dispatcher.connect(my_handler, my_signal, sender=Any)`` ``my_signal.connect(my_handler, sender=None)`` 
     151        ========================================================= ================================================ 
     152 
     153.. Other Changes_: 
     154 
     155Other Changes 
     156============= 
     157    * The spaceless template tag removes *all* spaces between HTML tags instead of preserving a single space 
     158    * ``localflavor.usa`` has been renamed ``localflavor.us``. This change was made to match the naming scheme of other local flavors. 
     159    * Renamed ``SeesionBase.get_new_session_key()`` to ``_get_new_session_key()`` and removed ``get_new_session_object()``. 
     160    * Fixture behaviour has changed slightly: 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. 
     161    * Settings exception changed. ``EnvironmentError`` was split into an ``ImportError`` raised when Django fails to find the settings module and ``RuntimeError`` when you try to reconfigure settings after having already used them 
     162    * The models manager now returns a ``MultipleObjectsReturned`` exception instead of ``AssertionError``:: 
     163 
     164        #0.96 
     165        try: 
     166            Model.objects.get(...) 
     167        except AssertionError: 
     168            ... 
     169 
     170        #1.0 
     171        try: 
     172            Model.objects.get(...) 
     173        except Model.MultipleObjectsReturned: 
     174            ... 
     175 
     176    * The manager option to class ``Admin`` no longer exists. In favor of this option, a ``ModelAdmin`` class may now define a queryset method:: 
     177 
     178        class BookAdmin(admin.ModelAdmin): 
     179            def queryset(self, request): 
     180                """ 
     181                Filter based on the current user. 
     182                """ 
     183                return self.model._default_manager.filter(user=request.user) 
     184 
     185    * ``django.views.i18n.set_language`` 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. 
     186      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). 
     187    * ``django.http.HttpResponse.headers`` has been renamed to ``_headers`` and ``HttpResponse`` now supports containment checking directly:: 
     188 
     189        # 0.96 
     190        if header in response.headers: 
     191 
     192        # 1.0 
     193        if header in response: 
     194 
     195    * The generic relation classes - ``GenericForeignKey`` and ``GenericRelation`` - have moved into the ``django.contrib.contenttypes module``:: 
     196 
     197        #0.96 
     198        generic_field = models.GenericRelation(SomeOtherModel) 
     199 
     200        #1.0 
     201        from django.contrib.contenttypes import generic 
     202        ... 
     203        generic_field = generic.GenericRelation(SomeOtherModel) 
     204 
     205    * ``_()`` is no longer in builtins so 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:: 
     206 
     207        from django.utils.translation import ugettext as _ 
     208 
     209    * The ``LazyDate`` helper class was removed. Default field values and query arguments can both be callable objects, so instances of ``LazyDate`` can be replaced with a reference to datetime.now:: 
     210 
     211        # 0.96 
     212        class Article(models.Model): 
     213            title = models.CharField(maxlength=100) 
     214            published = models.DateField(default=LazyDate()) 
     215 
     216        # 1.0 
     217        from datetime import datetime 
     218        class Article(models.Model): 
     219            title = models.CharField(maxlength=100) 
     220            published = models.DateField(default=datetime.now) 
     221 
     222    * 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 ``settings.LOGIN_URL``. 
     223 
     224    * Test client login method changed:: 
     225 
     226        # 0.96 
     227        from django.test import Client 
     228        c = Client() 
     229        c.login('/path/to/login','myuser','mypassword') 
     230 
     231        # 1.0 
     232        ... 
     233        c.login(username='myuser', password='mypassword') 
     234 
     235 
     236    * Changes to ``django.core.management`` - calls to management services in your code will need to use the ``call_command``. For example, if you have some test code that calls flush and load_data:: 
     237 
     238        from django.core import management 
     239        management.flush(verbosity=0, interactive=False) 
     240        management.load_data(['test_data'], verbosity=0) 
     241 
     242      You will need to change this code to read:: 
     243 
     244        from django.core import management 
     245        management.call_command('flush', verbosity=0, interactive=False) 
     246        management.call_command('loaddata', 'test_data', verbosity=0) 
     247 
     248    * ``django-admin.py`` and ``manage.py`` now require subcommands to precede options:: 
     249 
     250        django-admin.py --settings=foo.bar runserver 
     251 
     252      changed to:: 
     253 
     254        django-admin.py runserver --settings=foo.bar 
     255 
     256    * Changed ``__init__()`` parameters in syndication framework's Feed class to 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. 
     257      This only affects code that subclass Feed and overrides the ``__init__()`` method, and code that calls ``Feed.__init__()`` directly. 
     258    * ``django.newforms.forms.SortedDictFromList`` class removed, due to ``django.utils.datastructures.SortedDict`` gaining the ability to be instantiated with a sequence of tuples. Two things need to be done to fix your code: 
     259 
     260       1. Use ``django.utils.datastructures.SortedDict`` wherever you were using ``django.newforms.forms.SortedDictFromList``. 
     261       2. Since ``SortedDict``'s copy method doesn't return a deepcopy as ``SortedDictFromList'``s copy method did, you will need to update your code if you were relying on ``SortedDictFromList.copy`` to return a deepcopy. Do this by using ``copy.deepcopy`` instead of ``SortedDict``'s copy method. 
     262 
     263    * Change to ``APPEND_SLASH`` behaviour. 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. 
     264      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. 
     265      For most people, this won't require any changes. Some people, though, have URL patterns that look like this:: 
     266 
     267        r'/some_prefix/(.*)$' 
     268 
     269      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:: 
     270 
     271        r'/some_prefix/(.*/)$' 
     272 
     273    * Introduced ``DecimalField`` and changed ``FloatField`` to proper float - one that takes no ``max_digits``:: 
     274 
     275        # 0.96 
     276        class MyModel(models.Model): 
     277            ... 
     278            field_name = models.FloatField(max_digits=10, decimal_places=3) 
     279 
     280        #1.0 
     281        class MyModel(models.Model): 
     282            ... 
     283            field_name = models.DecimalField(max_digits=10, decimal_places=3) 
     284 
     285      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. 
     286      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``. 
     287      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, follow this procedure for every application you have that contains a ``DecimalField``. Do this after you have made the change to using ``DecimalField`` in your code and updated the Django code. 
     288      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). 
     289 
     290      For every application using a ``DecimalField``, do the following. We will use applications called some_app and another_app in this example:: 
     291 
     292        ./manage.py dumpdata --format=xml some_app another_app > data-dump.xml 
     293        ./manage.py reset some_app another_app 
     294        ./manage.py loaddata data-dump.xml 
     295 
     296      Notes: 
     297 
     298       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. 
     299       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. We restore this data in the third step, of course. 
     300       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 applications. 
     301 
     302      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. 
     303    * 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: 
     304 
     305        ============================================= ========================================================= 
     306        0.96 name/location                            1.0 name/location 
     307        ============================================= ========================================================= 
     308        django.db.backend.get_autoinc_sql             django.db.connection.ops.autoinc_sql 
     309        django.db.backend.get_date_extract_sql        django.db.connection.ops.date_extract_sql 
     310        django.db.backend.get_date_trunc_sql          django.db.connection.ops.date_trunc_sql 
     311        django.db.backend.get_datetime_cast_sql       django.db.connection.ops.datetime_cast_sql 
     312        django.db.backend.get_deferrable_sql          django.db.connection.ops.deferrable_sql 
     313        django.db.backend.get_drop_foreignkey_sql     django.db.connection.ops.drop_foreignkey_sql 
     314        django.db.backend.get_fulltext_search_sql     django.db.connection.ops.fulltext_search_sql 
     315        django.db.backend.get_last_insert_id          django.db.connection.ops.last_insert_id 
     316        django.db.backend.get_limit_offset_sql        django.db.connection.ops.limit_offset_sql 
     317        django.db.backend.get_max_name_length         django.db.connection.ops.max_name_length 
     318        django.db.backend.get_pk_default_value        django.db.connection.ops.pk_default_value 
     319        django.db.backend.get_random_function_sql     django.db.connection.ops.random_function_sql 
     320        django.db.backend.get_sql_flush               django.db.connection.ops.sql_flush 
     321        django.db.backend.get_sql_sequence_reset      django.db.connection.ops.sequence_reset_sql 
     322        django.db.backend.get_start_transaction_sql   django.db.connection.ops.start_transaction_sql 
     323        django.db.backend.get_tablespace_sql          django.db.connection.ops.tablespace_sql 
     324        django.db.backend.quote_name                  django.db.connection.ops.quote_name 
     325        django.db.backend.get_query_set_class         django.db.connection.ops.query_set_class 
     326        django.db.backend.get_field_cast_sql          django.db.connection.ops.field_cast_sql 
     327        django.db.backend.get_drop_sequence           django.db.connection.ops.drop_sequence_sql 
     328        django.db.backend.OPERATOR_MAPPING            django.db.connection.operators 
     329        django.db.backend.allows_group_by_ordinal     django.db.connection.features.allows_group_by_ordinal 
     330        django.db.backend.allows_unique_and_pk        django.db.connection.features.allows_unique_and_pk 
     331        django.db.backend.autoindexes_primary_keys    django.db.connection.features.autoindexes_primary_keys 
     332        django.db.backend.needs_datetime_string_cast  django.db.connection.features.needs_datetime_string_cast 
     333        django.db.backend.needs_upper_for_iops        django.db.connection.features.needs_upper_for_iops 
     334        django.db.backend.supports_constraints        django.db.connection.features.supports_constraints 
     335        django.db.backend.supports_tablespaces        django.db.connection.features.supports_tablespaces 
     336        django.db.backend.uses_case_insensitive_names django.db.connection.features.uses_case_insensitive_names 
     337        django.db.backend.uses_custom_queryset        django.db.connection.features.uses_custom_queryset 
     338        ============================================= ========================================================= 
     339