この記事は Django Advent Calendar 2017 2日目の記事です。

9年ぶりとなるメジャーバージョンアップとなるDjango 2.0について紹介していきます。

Django 2.0では、Python2系のサポートは打ち切られて、Python3.4/3.5/3.6のみをサポートすることとなります。

Django 2.0 Roadmap

https://code.djangoproject.com/wiki/Version2.0Roadmap

Date Process
2017/09/18 Django 2.0 alpha; feature freeze.
2017/10/16 Django 2.0 beta; non-release blocking bug fix freeze.
2017/11/15 Django 2.0 RC 1; translation string freeze.
2+ weeks after RC1 Django 2.0 final (or RC 2, if needed).

現時点ではRC 1がリリースされています。
https://pypi.python.org/pypi/Django/2.0rc1

順調にいけば、12月中にはDjango2.0の正式リリースが発表されるでしょう。

追記

この記事を書いた数時間後の12/2に無事リリースされました! :tada:
Django 2.0 released | Weblog | Django

新機能

シンプルなURLルーティング構文

従来の正規表現を用いた書き方(django.conf.urls.url())に加えて、新たにシンプルな書き方(django.urls.path())ができるようになりました。

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
path('articles/<int:year>/', views.year_archive),

モバイルフレンドリーなcontrib.admin

admin画面がレスポンシブ対応になりました。

Django 1.1

スクリーンショット 2017-12-02 09.22.16.png

Django 2.0

スクリーンショット 2017-12-02 09.16.24.png

Window式

  • 新しいWindow式として、OVER句を足せるようになりました。

細かい機能群

runserverで立ち上がるサーバーがHTTP 1.1に対応するなど、他にも細かい新機能があります。ドキュメントをざっと眺めておくとよいでしょう。

https://docs.djangoproject.com/en/2.0/releases/2.0/#minor-features

後方互換性がない変更

  • I/Oまわりを除いて、bytestringsは使用不可
    • Python2系のサポート切るため
  • DBバックエンドAPIの変更
  • Oracle 11.2をサポート外
    • Django1.11でサポートしていく
  • MySQLの分離レベルのデフォルト設定をrepeatable readからread committedに変更
  • AbstractUser.last_nameのmax_lengthが150文字までに増加
    • AbstractUserを使っている場合は、新たにmigrationを適用する必要あり
  • スライス後の、QuerySet.reverse()QuerySet.last()は使用禁止
>>> Model.objects.all()[:2].reverse()
Traceback (most recent call last):
...
TypeError: Cannot reverse a query once a slice has been taken.
  • Form fieldsへの位置引数を禁止
    • :no_good: forms.IntegerField(25, 10)
    • :ok_woman: forms.IntegerField(max_value=25, min_value=10)
  • call_commandのオプション指定方法に、parser.add_argument 加えて stealth_options という簡単な設定が可能に
    • 以下はflushcommandの実装を一部抜粋したもの
class Command(BaseCommand):
    help = (
        'Removes ALL DATA from the database, including data added during '
        'migrations. Does not achieve a "fresh install" state.'
    )
    stealth_options = ('reset_sequences', 'allow_cascade', 'inhibit_post_migrate')

    def add_arguments(self, parser):
        parser.add_argument(
            '--noinput', '--no-input', action='store_false', dest='interactive',
            help='Tells Django to NOT prompt the user for input of any kind.',
        )
        parser.add_argument(
            '--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
            help='Nominates a database to flush. Defaults to the "default" database.',
        )

    def handle(self, **options):
        database = options['database']
        connection = connections[database]
        verbosity = options['verbosity']
        interactive = options['interactive']
        # The following are stealth options used by Django's internals.
        reset_sequences = options.get('reset_sequences', True)
        allow_cascade = options.get('allow_cascade', False)
        inhibit_post_migrate = options.get('inhibit_post_migrate', False)

非推奨になった機能

まとめ

Djnago2.0の変更点について見てきましたが、移行準備として1.11の環境のうちからRemovedInDjango20Warningを解消しておきましょう。(RemovedInDjango20Warning$ python -Wd manage.pyで検出できます。)