Django3.0の気になった新機能まとめ

Django 3.0 alphaがリリースされました。
まだ開発段階ではありますが、一部いくつか気になる新機能/機能削除があったので忘備録代わりに書いておきます。

(元ソース) https://docs.djangoproject.com/en/dev/releases/3.0/

## MariaDBのサポート
MySQLよりMariaDB派であったので、正直にうれしい。
一方でドキュメントにはこんな言葉が……

> To use MariaDB, use the MySQL backend, which is shared between the two. See the MySQL notes for more details.

つまり今まではMariaDBを使う時にMySQLの設定を流用してなんとかしてきたが、アップデートに伴って設定を書き換える必要がないということかな。いずれにせよありがたい……！

## ASGIのサポート
今まではWSGIでの同期サーバーとして処理ができたが、ASGIのサポートとともに非同期処理ができるようになりました。
……ASGIを触ったことがないからよくわからん……startprojectするとasgi.pyなるファイルも生成されるけど……うぅむ……今後確認してみようかな

```python:asgi.py

"""
ASGI config for sample_project project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/dev/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sample_project.settings')

application = get_asgi_application()

```

## ModelのEnumClass
Modelの選択肢がもっと書きやすくなりました。

過去は

```python:django_less_then_3
from django.db import models

class Student(models.Model):
    FRESHMAN = 'FR'
    SOPHOMORE = 'SO'
    JUNIOR = 'JR'
    SENIOR = 'SR'
    GRADUATE = 'GR'
    YEAR_IN_SCHOOL_CHOICES = [
        (FRESHMAN, 'Freshman'),
        (SOPHOMORE, 'Sophomore'),
        (JUNIOR, 'Junior'),
        (SENIOR, 'Senior'),
        (GRADUATE, 'Graduate'),
    ]
    
    year_in_school = models.CharField(
        max_length=2,
        choices=YEAR_IN_SCHOOL_CHOICES,
        default=FRESHMAN,
    )
```

と書いていたものが、下記のようにイケてる書き方ができるようになりました。いいじゃん！

```python:django_more_than_3
from django.utils.translation import gettext_lazy as _

class Student(models.Model):

    class YearInSchool(models.TextChoices):
        FRESHMAN = 'FR', _('Freshman')
        SOPHOMORE = 'SO', _('Sophomore')
        JUNIOR = 'JR', _('Junior')
        SENIOR = 'SR', _('Senior')
        GRADUATE = 'GR', _('Graduate')

    year_in_school = models.CharField(
        max_length=2,
        choices=YearInSchool.choices,
        default=YearInSchool.FRESHMAN,
    )
```

## Modelsにハッシュ関数が追加

Modelsに各種ハッシュ関数が追加されたらしいです。
使い方は下記の通り。

```python:hash_shell
>>> from django.db.models.functions import SHA1
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_sha1=SHA1('name')).get()
>>> print(author.name_sha1)
b87efd8a6c991c390be5a68e8a7945a7851c7e5c
```

……使い道がパッと出てきませんが、ハッシュ値を計算して参照するだけのロジックがあれば役に立ちそう。

## セキュリティ周り
ざっと見ると、マイナーのはずが結構強い変更に見える……気のせいでしょうか？
APIなどでお行儀が悪いことしているとアップデート共に使えなくなりそうなので要注意ですね。

### X_FRAME_OPTIONS="DENY"(デフォルト値変更)
X_FRAME_OPTIONSのデフォルト値がSAMEORIGINからDENYになりました。~~ClickJackingは死すべし~~
これによりsetting.pyのmiddlewaredjango.middleware.clickjacking.XFrameOptionsMiddlewareの挙動が変わるので、iflame埋め込んだりしているアプリは要注意ですね……



### SECURE_CONTENT_TYPE_NOSNIFF=True(デフォルト値変更)

「X-Content-Type-Options: nosniff」がすべてのレスポンスヘッダーに付与されるそうです。まぁtext/plainのjsonでやりとりしたりしていなければ、恩恵しかないはず……


## Python2対応していたprivate APIのサポート除去
ま　だ　あ　っ　た　の　か
Djangoのソースコードあんまり読んでいないから知らなかったけど、下記の関数からpython2サポートが消えたそうです。

- django.test.utils.str_prefix()
- django.test.utils.patch_logger() 
- django.utils.lru_cache.lru_cache()
- django.utils.decorators.available_attrs()
- django.utils.decorators.ContextDecorator
- django.utils._os.abspathu()
- django.utils._os.upath() and npath()
- django.utils.six 
- django.utils.encoding.python_2_unicode_compatible()
- django.utils.functional.curry()
- django.utils.safestring.SafeBytes

## django.utils.html.escape()の挙動変更
'(シングルクォート)のパース文字が変更になったとのこと

    &#39; → &#x27;

レアケースかもしれないけれども、templateのsnapshot testを利用されているアプリケーションのテストに影響が出るかも……？



## さよなら、django.shortcuts.render_to_response
render_to_responseが削除されます。今後はrenderメソッドで代用しましょう。