DjangoCongress JP 2018 Django利用状況アンケート 途中結果

DjangoCongress JP 2018の企画としてDjangoの利用状況のアンケートを実施しています。( https://goo.gl/forms/BVVgBGtebHNW8aGu1 )

アンケートの3/18時点での途中結果としてレポートとして公開します。 イベント当日までまだまだアンケートは実施していますので、まだ回答していない方いらっしゃればぜひお願いいたします!

In [1]:
import re
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['font.family'] = 'IPAPGothic'
In [2]:
def flatmap_series(series, func):
    values = []
    for value in series:
        new_values = func(value)
        for v in new_values:
            values.append(v)
    return pd.Series(values)


def multiple_choices(series):
    return flatmap_series(series.dropna(), lambda s: [v.strip() for v in re.split(',', s)])
In [3]:
df = pd.read_csv("DjangoCongress JP 2018 事前アンケート(回答) - フォームの回答 1.csv",
                 header=0,
                 names=['company_name', 'product_kind', 'why_django', 'experience', 'django_version', 'python_version', 'os', 'db_backend', 'problem', 'recommend_library'])
# df

Djangoを使っている企業

In [4]:
for company_name in df['company_name'].replace('Castalia', 'キャスタリア株式会社').dropna().sort_values().unique():
    print(company_name)
AWAKENS, Inc.
BeProud
UNCOVER TRUTH Inc.
キャスタリア株式会社
日本営農システムズ株式会社
株式会社SQUEEZE
株式会社オープンコレクター
株式会社クレジットエンジン
株式会社ハートビーツ
株式会社ワングリット
株式会社日本システム技研
株式会社雛屋建設社

Djangoでどのようなアプリケーションを開発しているか

In [5]:
default_kind = 'WEBアプリケーション'
kinds = dict((re.compile(k), v) for k, v in ({
    '.*(教育|MOOC|学習|勉強).*': '教育',
    '.*社内.*': '社内システム',
    '.*受託.*': '受託',
    '.*(ウェブサイト|ブログ).*': 'ウェブサイト',
    '.*個人.*': '個人',
    '.*API.*': 'APIサービス',
    '.*メディア.*': 'ウェブメディア',
    '.*(分析|集計).*': '分析',
    '.*業務.*': '業務',
}).items())

def product_kind(value):
    for pattern, label in kinds.items():
        if pattern.match(value):
            return label
    else:
        return default_kind
    
product_kinds = flatmap_series(df['product_kind'].dropna(),
               lambda s: [label.replace('* ', '') for label in re.split('[\n,、,・]', s) if label != '']).map(product_kind)
product_kinds.groupby(product_kinds).count().plot('pie', label='').axis('equal')
Out[5]:
(-1.1000000116550814,
 1.1000000288594245,
 -1.1159208826239502,
 1.1122365077186602)

他のフレームワークではなくDjangoを選んだ理由

In [6]:
for why in df['why_django'].dropna():
    print(why)
入社当時からあったので詳しく聞いていない
MOOCプラットフォームのedx(エデックス)のWeb Application Frameworkに採用されているため
利用している MOOC のプラットフォームで利用しているため
* 色々なコンポーネントがすぐに使えて便利
* Django製ライブラリーが豊富
* 社内の利用者が多いのでノウハウを共有できる
* 国内の利用者が多い

初めからたくさんの機能があり、歯車の開発がほぼないから
Pythonが使える、安定感のあるフレームワークがDjangoだったから
社内で使用実績があったから.
Djangoフレームワークの指定がある場合には使用。
ビルトインの管理画面が使えるので登録・編集・削除の画面開発が不要
オールインワンな感じがするから
仕事でPythonを使っているから
・開発効率・保守性の良さ
・DB関連の機能の良さ(マイグレーション、adminサイト)
・Webアプリを開発するのに必要な機能や外部モジュールが豊富
・フルスタックで揃っているため大きなプロジェクトで運用しやすい
Pythonが使えて最初から色々揃ってるから
Pythonでwebサービスを作るためのフルスタックなフレームワークを探していたので
ドキュメントが多い
コミュニティが活発
Web上に情報がある
豊富な事例がある
サードパーティのライブラリが多い
Pythonのフルスタックwebアプリケーションフレームワークの定番だと思われたので
今まではWebサービスの本体と社内向け管理サイト(django)とで別けていたが、二つ保守するのが大変になり、新しく作る際は統一することになってdjangoが最適だった。
最初から管理画面とUserモデルも付いている。
会社の人にpythonを勧められて使うことになり、python製のフルスタックwebフレームワークがdjangoのため選んだ。
簡単なアプリケーションであればDjangoの標準機能とアドオンで短期間で開発できるため
機能のサイズがちょうど良い。
社内でPythonを使用しているスタッフが多かったため
* 2011年ごろ、GAEを使うためDjango likeなkayFrameworkを使ったから
* frameworkの中のコードが読みやすく、呼び出し順序などが把握しやすいため
* 多言語に比べてPythonは複数人で作るときに記法が統一しやすい
* hirokikyのサポートがあった
チームメンバーにPython使いが多く、DjangoはPythonのWebアプリケーションフレームワークで実質デファクトなので。継続してメンテナンスが必要な組織のWebサイトに利用されており、積極的に脆弱性情報が集まるため。ユーザーコミュニティが大きく、関連する情報や便利なライブラリー等がたくさんあるため。
python用のWEBフレームワークとして一番目にしたことと、DB実装部分が半自動化していて扱い安いと感じたから。

どれくらいの期間Djangoを使って開発をしているか

In [7]:
df['experience'].groupby(df.experience).count().plot('pie', label='').axis('equal')
Out[7]:
(-1.1000000086007158,
 1.1000000004095578,
 -1.1278402520635842,
 1.1209352413267513)

使っているDjangoのバージョン

In [8]:
django_versions = multiple_choices(df['django_version'])
django_versions.groupby(django_versions).count().plot('pie', label='').axis('equal')
Out[8]:
(-1.121645056753839,
 1.101030716988278,
 -1.1018030110953134,
 1.1324818852974243)

使っているPython

In [9]:
python_versions = multiple_choices(df['python_version'])
python_versions.groupby(python_versions).count().plot('pie', label='').axis('equal')
Out[9]:
(-1.1070918944572163,
 1.1003377453160312,
 -1.1043512658959478,
 1.111521273896213)

Djangoを動かしているOS

In [10]:
oses = multiple_choices(df['os'])
oses.groupby(oses).count().plot('pie', label='').axis('equal')
Out[10]:
(-1.1061316418676779,
 1.100291985514528,
 -1.1051246233198042,
 1.1068316984528277)

Djangoバックエンドのデータベース

二大OSSデータベースであるMySQLとPostgreSQLの利用が大半を占めていますね。 珍しいところでMongoDBを使われているところもあるようですが、これはdjango-mongodb-engine( https://django-mongodb-engine.readthedocs.io/en/latest/ )のようなカスタムのバックエンドを使っているのでしょうか。

In [11]:
db_backends = multiple_choices(df['db_backend'].replace("Aurora, Amazon Redshift", "Aurora、Amazon Redshift", regex=True)) # 選択肢の設定上で","が含まれてた
db_backends.groupby(db_backends).count().plot('pie', label='').axis('equal')
Out[11]:
(-1.1099684054560452,
 1.1004746859740975,
 -1.1117990392175334,
 1.1038178813796027)

Djangoを使っていて困っていること

最新の情報が日本語で少ないというのが目立ちますね。 個人的には性能について困っている人がいることが気になりました。 Djangoに限らず大きなフレームワークはどうしてもオーバーヘッドがかかってしまうので金の弾丸含めて包括的に検討されることをおすすめします。

In [12]:
for problem in df['problem'].dropna():
    print(problem)
特にない
本家以外のドキュメントが少なく、私のような初心者には敷居が高いイメージがある
ORMを複雑な要件に使うと、発行されるクエリーが予想しにくいことです。
日本語の情報が少なくて辛いと言う人がいる
使い方が悪いのかもしれませんが.
Hamっていうモデルがあったとして,
Ham.objects.get(id=2)
のように,存在しないデータ(id:2は無い)を指定したとき,NoneではなくDoesNotExistの例外が発生するのは面倒だなとおもいます.
ORMで複雑な問い合わせをしづらい。
日本語書籍が少ない
pdf化が上手くできない
日本語の書籍が少ない。
日本語のトラブルシュート記事が少ない。
・SNSログイン関連のライブラリに何を使ってよいか分からない
・gunicornのチューニング方法が分からない。あまり情報がない
・mysqlドライバーに何を使ってよいか分からない
・debug toolbarとのバージョン不整合問題
・class-based-viewとfunction-based-viewのどちらを使えばよいか(おそらく、class-based-viewだと思いますが...)
日本語の情報が少ない
最新情報寄りの日本語情報が少ない、定番・鉄板ライブラリが探しづらい
qiitaなどを見ていると記述方法にいろいろあり、どれが定式的にいいのかわからなくなる。
標準のテンプレートエンジンの性能が若干低くhtml出力でボトルネックになることがある
管理者と一般ユーザー用にDBを分けたいたい時にやり方がわかりませんでした。今はわかりませんがMongoDBを上手く使えない時期がありました。標準機能やアドオン以外の拡張をしようとした時にいきなり学習コストが高くなるように感じました。
現場に即した形の日本語チュートリアルが少ない印象です
ノンブロッキング処理が難しい
ちょっと遅い
日本語の情報が少ないこと。

おすすめライブラリ

やはりDjango REST Frameworkが人気のようです。

In [13]:
for recommend_library in df['recommend_library'].dropna():
    print(recommend_library)
使い始めて日が浅いため、特になし
django-rest-framework
python-social-auth
django-sekizai
django-cors-headers
django-debug-toolbar
django-meta
django-basicauth
django-hijack
django-keeper

django rest frameworkとfactoryboyはよくつかいます.
Django REST framework, WhiteNoise
import-export
django-settings-export(最近使い始めた)
・Background Tasks
・Django Rest Framework
・DjangoREST Swagger
・awesome-django
・django-environ
・django-debug-toolbar
・django-storages
・django-widget-tweaks
django-debug-toolbar
django-environ
django-extensions
django-hijack
django-silk
django-storages
Django REST framework
Django import/export(http://django-import-export.readthedocs.io/en/latest/)が、拡張しやすくexcel, csv, jsonと様々な形式でインポート、エクスポートできて良かったです。
social-auth-app-django
Django Horizon :-) / Django REST framework