狠狠撸

狠狠撸Share a Scribd company logo
Djangoでさくっと
Webアプリケーション
開発をする話
みんなのPython勉強会 in 長野
Yuichi Nakazawa
@y_nakazawa1220
(株)日本システム技研 所属
Python/Django案件 ディレクター兼エンジニア
GEEKLAB.NAGANO エバンジェリスト
自己紹介
元ネタ
スライドシェア:https://goo.gl/Hx9zEp
Youtube:https://goo.gl/c8y6xy
元ネタ2
https://goo.gl/3FlpjP
顿箩补苍驳辞入门の参考书
https://goo.gl/bMHGyi
サンプルコード:github
https://goo.gl/9LumRd
デモURL
? PythonでWebアプリケーション開発
したい人
? これからDjangoで開発したい人、興味
がある人
? Djangoの初級者向け
このセッションの対象
? ベストプラクティス的なこと
? Tips的なこと
? その他、細かいDjangoの機能
(テストとか、多言語対応とか??)
話さないこと
#stapy
お願い
? こんな書き方あるよ
? こうした方が分かりやすいよ
? こんなこと知りたいよ
Django
? フルスタックなWebアプリケーション
フレームワーク
? MVCでなく、MVT
? 学習コストが低い
? 补诲尘颈苍サイトが秀逸
? migrationが便利
Django特徴
チュートリアルが良い
https://docs.djangoproject.com/ja/1.10/intro/
? Djangoアプリ作成
? 惭辞诲别濒作成と尘颈驳谤补迟颈辞苍
? 补诲尘颈苍サイト
? 簡単なCRUD
? Herokuへのデプロイ
レジュメ
(書籍管理アプリの作り方)
顿箩补苍辞驳辞アプリ作成
Djangoインストール
$ pip install django
現状だと1.10.6あたりが入るはず
$ pip freeze django
Django==1.10.6
Djangoプロジェクト&アプリの生成
$ django-admin.py startproject [myproject]
プロジェクトを作る
$ python manage.py startapp [myapp]
アプリ作る
settings.pyにアプリ追加
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
]
ディレクトリ構成
.
├── cms
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ ├── forms.py
│ └── views.py
│ └── templates
├── db.sqlite3
├── manage.py
└── stapydemo
├── __init__.py
├── __pycache__
├── settings.py
├── urls.py
└── wsgi.py
?色付きファイルを中心に作業します
。
?青字は自動生成されます。
?赤字は自分で適宜作成します。
開発用サーバー起動
$ cd myproject
$ python manage.py runserver
System check identified no issues (0 silenced).
March 03, 2017 - 15:23:22
Django version 1.10.6, using settings 'stapydemo.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
開発用サーバーのTips
$ python manage.py runserver IP:ポート番号
$ python manage.py rumserver --settings= myapp.settings
IPとポート指定したい場合
settings.py(環境設定ファイル)を切り替えたい場合
Webアプリケーション開発フロー
1. Model(データ構造)を考える
? Models.pyの実装(ビジネスロジックの実装)
2. Views.py ? templateへ渡すためのデータ加工
3. templateを作る(HTML/CSS/Javascript)
4. URL設計 ? Urls.pyの実装
惭辞诲别濒作成と尘颈驳谤补迟颈辞苍
Webアプリケーション開発フロー
1. Model(データ構造)を考える
? Models.pyの実装(ビジネスロジックの実装)
2. Views.py ? templateへ渡すためのデータ加工
3. templateを作る(HTML/CSS/Javascript)
4. URL設計 ? Urls.pyの実装
Modelとは?
そのアプリケーションが扱う領域のデータと手続き
(ビジネスロジック - ショッピングの合計額や送料を計算するなど)
を表現する要素である - wikipediaより
DBに定義したいデータ構造を定義する
? 基本的にDjangoに用意されているORMのみで
DBにアクセスできる。
? SQLは書かなくて済む(個人的に経験なし??)
def book_list(request):
'''書籍の一覧'''
books = Book.objects.all().order_by('id') # 親の書籍を全件読む
return render_to_response('cms/book_list.html', # 使用するテンプレート
{'books': books}, # テンプレートに渡すデータ
context_instance=RequestContext(request))
def impression_list(request, book_id):
'''感想の一覧'''
book = get_object_or_404(Book, pk=book_id) # 親の書籍を1件読む
impressions = book.impressions.all().order_by('id') # 書籍の子供の、感想を読む
:
:
親の読み方、子の読み方
ORM (Object Relation Mapping)
モデルの追加や項目の更新?削除を
手軽にDBと同期が取れる仕組み
migrationとは
? model.py の定義変更をDBに反映させることができ
る
? modelを直した場合に、所定のコマンドを叩くと
migrateファイルを作ってくれる
? Django 1.6まではSouth
- http://south.aeracode.org
? Django 1.7からは標準として取り込まれた
migration
認証とセッション関連の
テーブルを作成
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying sessions.0001_initial... OK
まずmigrateして、認証とセッション関連をDB上にテーブルを作成する
管理者ユーザ作成
$ python manage.py createsuperuser
Username (leave blank to use 'nakazawa'): admin
Email address: admin@any.com
Password:
Password (again):
Superuser created successfully.
createsuperuser で管理者ユーザを作成する
テーブルの中身をのぞいてみる
$ python manage.py dbshell
SQLite version 3.8.10.2 2015-05-20 18:17:19
Enter ".help" for usage hints.
sqlite>
settings.pyに設定してあるDBエンジンに接続(デフォは、sqlite)
sqlite> .tables
auth_group auth_user_user_permissions
auth_group_permissions django_admin_log
auth_permission django_content_type
auth_user django_migrations
auth_user_groups django_session
SQLを叩いてみる
sqlite> .header on
sqlite> .mode column
sqlite> select id, username, email from auth_user;
id username email
---------- ---------- -------------
1 admin admin@any.com
from django.db import models
class Book(models.Model):
"""書籍"""
name = models.CharField('書籍名', max_length=255)
publisher = models.CharField('出版社', max_length=255, blank=True)
page = models.IntegerField('ページ数', blank=True, default=0)
def __str__(self):
return self.name
class Impression(models.Model):
"""感想"""
book = models.ForeignKey(Book, verbose_name='書籍', related_name='impressions')
comment = models.TextField('コメント', blank=True)
def __str__(self):
return self.comment
Modelの実装
「書籍」と各書籍の「感想」をモデル化(関連が1:nのモデル)
modelを更新した場合
(migrationsディレクトリ配下に000x_xxxx.pyが作成される)
$ python manage.py makemigrations
Migrations for 'cms':
cms/migrations/0001_initial.py:
- Create model Book
- Create model Impression
DB migration(変更の抽出)
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='書籍名')),
('publisher', models.CharField(blank=True, max_length=255, verbose_name='出版社')),
('page', models.IntegerField(blank=True, default=0, verbose_name='ページ数')),
],
),
migrations.CreateModel(
name='Impression',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('comment', models.TextField(blank=True, verbose_name='コメント')),
('book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='impressions', to='cms.Book',
verbose_name='書籍')),
],
),
]
000x_xxxx.pyのサンプル
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, cms, contenttypes, sessions
Running migrations:
Applying cms.0001_initial... OK
DB migration(DBへ反映)
sqlite> .tables
auth_group cms_book
auth_group_permissions cms_impression
auth_permission django_admin_log
auth_user django_content_type
auth_user_groups django_migrations
auth_user_user_permissions django_session
DB migration(カラム追加)
models.py に isbn という項目を追加します。
class Book(models.Model):
:
page = models.IntegerField(u'ページ数', blank=True, default=0)
isbn = models.CharField(u'ISBN', max_length=255, blank=True, null=True) # 追加
DB migration
$ python manage.py makemigrations myapp
makemigrationsコマンド(models.pyの変更を拾う)
makemigrationsが作成したマイグレーション ファイルを確認
myproj/myapp/migrations/0002_book_isbn.py
migrateコマンドで、変更をDBに反映する
$ python manage.py migrate myapp
などといったファイルができているので、エディタで確認する
モデルの項目追加/変更がDBのテーブルに反映される
补诲尘颈苍サイト
补诲尘颈苍サイトに
ログインしてみる
http://127.0.0.1:8000/admin
※补诲尘颈苍サイト:
DBのメンテナンスに使用するサイト
补诲尘颈苍サイト ログイン画面
补诲尘颈苍サイト
补诲尘颈苍サイトへ追加する
admin.site.register(Book)
admin.site.register(Impression)
Listにカラム表示するのであれば、こんな感じ
カスタマイズするとこんな感じ
class BookAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'publisher', 'page',) # 一覧に出したい項目
list_display_links = ('id', 'name',) # 修正リンクでクリックできる項目
search_fields = ['name'] # 検索ボックス を出す
admin.site.register(Book, BookAdmin)
class ImpressionAdmin(admin.ModelAdmin):
list_display = ('id', 'comment',)
list_display_links = ('id', 'comment',)
admin.site.register(Impression, ImpressionAdmin)
补诲尘颈苍サイトへ追加する
CRUD
CRUD(クラッド)とは、ほとんど全てのコンピュータソフ
トウェアが持つ永続性[1]の4つの基本機能のイニシャルを並
べた用語。その4つとは、Create(生成)、Read(読み取り
)、Update(更新)、Delete(削除)である。ユーザイン
タフェースが備えるべき機能(情報の参照/検索/更新)を指
す用語としても使われる。
- wikipediaより
CRUDとは
Webアプリケーション開発フロー
1. Model(データ構造)を考える
? Models.pyの実装(ビジネスロジックの実装)
2. Views.py ? templateへ渡すためのデータ加工
3. URL設計 ? Urls.pyの実装
4. templateを作る(HTML/CSS/Javascript)
CRUDの書き方
書籍の一覧を表示したい場合は、以下のような感じ
def book_list(request):
'''書籍の一覧'''
books = Book.objects.all().order_by('id')
return render_to_response('cms/book_list.html', # 使用するテンプレート
dict(books=books), # テンプレートに渡すデータ
context_instance=RequestContext(request))
? django.views.generic.list.ListView
を使っておくと、ページネートが簡単
Listページの書き方
class BookList(ListView):
"""書籍の一覧"""
context_object_name = 'books'
template_name = 'cms/book_list.html'
paginate_by = 2 # 1ページは最大2件ずつでページングする
def get(self, request, *args, **kw):
self.object_list = Book.objects.all().order_by('id') #書籍を全件取得
context = self.get_context_data(object_list=self.object_list)
return self.render_to_response(context)
views.py 一覧
Listページの書き方
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}">&laquo;</a></li>
{% else %}
<li class="disabled"><a href="#">&laquo;</a></li>
{% endif %}
{% for linkpage in page_obj.paginator.page_range %}
{% ifequal linkpage page_obj.number %}
<li class="active"><a href="#">{{ linkpage }}</a></li>
{% else %}
<li><a href="?page={{ linkpage }}">{{ linkpage }}</a></li>
{% endifequal %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}">&raquo;</a></li>
{% else %}
<li class="disabled"><a href="#">&raquo;</a></li>
{% endif %}
</ul>
{% endif %}
book_list.html のページング部分
Listページの書き方
ページングの表示例
この部分
CRUDの書き方
def book_edit(request, book_id=None):
"""書籍の編集"""
if book_id: # book_id が指定されている (修正時)
book = get_object_or_404(Book, pk=book_id)
else: # book_id が指定されていない (追加時)
book = Book()
if request.method == ‘POST':
# POST された request データからフォームを作成
form = BookForm(request.POST, instance=book)
if form.is_valid(): # フォームのバリデーション
form.save()
return redirect('cms:book_list')
else: # GET の時
# book インスタンスからフォームを作成
form = BookForm(instance=book)
return render(request, 'cms/book_edit.html', dict(form=form, book_id=book_id))
views.py 登録/修正
CRUDの書き方
forms.py
class BookForm(ModelForm):
'''書籍のフォーム'''
class Meta:
model = Book
fields = ('name', 'publisher', 'page', )
CRUDの書き方
def book_del(request, book_id):
'''書籍の削除'''
book = get_object_or_404(Book, pk=book_id)
book.delete()
return redirect('cms:book_list')
views.py 削除
urls.py
urlpatterns = patterns('',
# 書籍
url(r'^book/$', views.book_list, name='book_list'), # 一覧
url(r'^book/add/$', views.book_edit, name='book_add'), # 登録
url(r'^book/mod/(?P<book_id>d+)/$', views.book_edit, name='book_mod'), # 修正
url(r'^book/del/(?P<book_id>d+)/$', views.book_del, name='book_del'), # 削除
)
Webアプリケーション開発フロー
1. Model(データ構造)を考える
? Models.pyの実装(ビジネスロジックの実装)
2. Views.py ? templateへ渡すためのデータ加工
3. URL設計 ? Urls.pyの実装
4. templateを作る(HTML/CSS/Javascript)
? CSSフレームワーク http://getbootstrap.com/
? とりあえずお手軽に見栄えするサイトを作りたい場合に便
利
Bootstrapを使う
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
静的ファイルの配置場所を設定
myproject ディレクトリの下に static ディレクトリを作って
配置する場合は、settings.pyに以下のように定義します
? Bootstrap - http://getbootstrap.com/
? jQuery - http://jquery.com/
今回は、以下のサイトからベタにDLして配置します
myproject/
static/
css/
bootstrap-theme.css
bootstrap-theme.css.map
bootstrap-theme.min.css
bootstrap-theme.min.css.map
bootstrap.css
bootstrap.css.map
bootstrap.min.css
bootstrap.min.css.map
fonts/
glyphicons-halflings-regular.eot
glyphicons-halflings-regular.svg
glyphicons-halflings-regular.ttf
glyphicons-halflings-regular.woff
glyphicons-halflings-regular.woff2
js/
bootstrap.js
bootstrap.min.js
npm.js
jquery-3.1.1.min.js
静的ファイルの配置イメージ
? 一覧系のページは、Bootstrap提供のclassを使って書きます
? Form系のページは、django-bootstrap-form
https://github.com/tzangms/django-bootstrap-form
を使うと便利です。
Bootstrap
$ pip install django-bootstrap-form
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrapform', # django-bootstrap-form
'cms',
)
? Djangoのテンプレートは継承できるので、以下のような構造に
すると流用性が高いです。
Bootstrap
BootstrapのJS、CSS
を定義したベース
CMSの各種ページ
base.html
index.html など
叠辞辞迟蝉迟谤补辫の例(一覧)
{% load staticfiles %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
<meta charset="UTF-8">
<title>{% block title %}My books{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href=/nakazawayuichi/djangoweb-73272659/"{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<link href=/nakazawayuichi/djangoweb-73272659/"{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet">
<script src=/nakazawayuichi/djangoweb-73272659/"{% static 'js/jquery-3.1.1.min.js' %}"></script>
<script src=/nakazawayuichi/djangoweb-73272659/"{% static 'js/bootstrap.min.js' %}"></script>
{% block extrahead %}{% endblock %}
</head>
<body>
<div class="container">
{% block content %}
{{ content }}
{% endblock %}
</div>
</body>
</html>
base.html
叠辞辞迟蝉迟谤补辫の例(一覧)
Bootstrap の JS、CSSを記述する
ベースとなるテンプレート
{% extends "base.html" %}
{% block title %}書籍の一覧{% endblock title %}
{% block extrahead %}
<style>
table {
margin-top: 8px;
}
</style>
{% endblock %}
{% block content %}
<h3 class="page-header">書籍の一覧</h3>
<a href=/nakazawayuichi/djangoweb-73272659/"{% url 'cms:book_add' %}" class="btn btn-default btn-sm">追加</a>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>書籍名</th>
<th>出版社</th>
<th>ページ数</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book in books %}
<tr>
<td>{{ book.id }}</td>
<td>{{ book.name }}</td>
<td>{{ book.publisher }}</td>
<td>{{ book.page }}</td>
<td>
<a href=/nakazawayuichi/djangoweb-73272659/"{% url 'cms:book_mod' book_id=book.id %}" class="btn btn-default btn-sm">修正</a>
<a href=/nakazawayuichi/djangoweb-73272659/"{% url 'cms:book_del' book_id=book.id %}" class="btn btn-default btn-sm">削除</a>
</td>
</tr>
book_list.html
Bootstrapの例
↑ 一覧系は Bootstrap の class を使って普通に書く
← base.html を継承
← base.html の title ブロックを置き換え
← base.html の content ブロックを置き換え
HTML出力例
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>書籍の一覧</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src=/nakazawayuichi/djangoweb-73272659/"/static/js/jquery-3.1.1.min.js"></script>
</head>
<body>
<div class="container">
<h3 class="page-header">書籍の一覧</h3>
<a href="" class="btn btn-default btn-sm">追加</a>
<table class="table table-striped table-bordered">
<thead>
</thead>
<tbody>
</tbody>
</table>
<ul class="pagination">
<li class="disabled"><a href="#">&laquo;</a></li>
<li class="active"><a href="#">1</a></li>
<li><a href="?page=2">2</a></li>
<li><a href="?page=2">&raquo;</a></li>
</ul>
</div>
</body>
</html>
青字:base.html
赤字:book_list.html
叠辞辞迟蝉迟谤补辫の例(贵辞谤尘)
{% extends “base_navi.html" %}
{% load bootstrap %}
{% block title %}書籍の編集{% endblock title %}
{% block content %}
<h3 class="page-header">書籍の編集</h3>
{% if book_id %}
<form action=/nakazawayuichi/djangoweb-73272659/"{% url 'cms:book_mod' book_id=book_id %}" method="post" class="form-horizontal" role="form">
{% else %}
<form action=/nakazawayuichi/djangoweb-73272659/"{% url 'cms:book_add' %}" method="post" class="form-horizontal" role="form">
{% endif %}
{% csrf_token %}
{{ form|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">送信</button>
</div>
</div>
</form>
<a href=/nakazawayuichi/djangoweb-73272659/"{% url 'cms:book_list' %}" class="btn btn-default btn-sm">戻る</a>
{% endblock content %}
book_edit.html
Bootstrapの例(Form系)
← django-bootstrap-form を使っているので
Form の項目を Bootstrap 形式で展開してくれる
{{ form|bootstrap_horizontal }}
form を丸ごと出す
django-bootstrap-formのTips
form を項目単位にバラす(項目を出す/出さない の制御をしたい時)
{{ form.id|bootstrap_horizontal }}
{{ form.name|bootstrap_horizontal }}
HTMLレベルにバラす(checkbox、radioは微妙に異なるので注意)
<div class="form-group{% if form.name.errors %} has-error{% endif %}">
<label class="control-label" for="{{ form.name.auto_id }}">{{ form.name.label }}</label>
<input type="text" class=“form-control" name="{{ form.name.html_name }}" value="{{ form.name.value }}" id="{{ form.name.auto_id }}">
{% for error in form.name.errors %}
<span class=“help-block {{ form.error_css_class }}">{{ error }}</span>
{% endfor %}
{% if form.name.help_text %}
<p class="help-block">
{{ form.name.help_text|safe }}
</p>
{% endif %}
</div>
checkbox、radioはsite-
packages/bootstrapform/templates/bootstrapfrom/field.html
を参考にしてみると良いです。
アプリケーションを公开する
Herokuを使う
? Paas https://www.heroku.com
? フリープランもあるので、今回はそちらを利用します
runtimeとgunicornの設定
$ pip install gunicorn
アプリケーション?サーバーとして「gunicorn」を入れる
python-3.4.1
PROJECR_ROOT/runtime.txt に使用するPythonバージョン
を書く
web: gunicorn --env DJANGO_SETTINGS_MODULE=stapydemo.settings
stapydemo.wsgi --log-file -
PROJECR_ROOT/Procfileに設定を書く
DBの切り替え
$ pip install dj_database_url
DBをPostgreSQLに切り替える。sqliteが使用できないのと、MySQLは
クレカ登録が必要なため
HerokuのDB設定を使用するため
$ pip install psycopg2
PostgreSQLのアダプタ
Settings.pyを両対応させる
from socket import gethostname
if ‘my_hostname' in gethostname():
DEBUG = True
TEMPLATE_DEBUG = True
else:
DEBUG = False
TEMPLATE_DEBUG = False
ALLOWED_HOSTS = ['*']
開発環境とHerokuの環境で設定を切り替える。
if 'my_hostname' in gethostname():
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
else:
import dj_database_url
DATABASES = {
'default': dj_database_url.config()
}
静的ファイルの扱い
静的ファイルをHerokuで扱うため、whitenoise を入れる。
http://whitenoise.evans.io/en/stable/django.html
$ pip install whitenoise
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
settings.pyにパスを追加する
環境をまとめる
$ pip freeze > requirements.txt
デプロイ
まとめ
? Djangoは、チュートリアルが充実しているので
学習コストが比較的低いです。
? フルスタックなので、色々やりたいことがあるので
あればDjangoを選ぶと良いと思います。
? Herokuは、お手軽にデプロイ経験できるので是非
使ってみてください。
Pythonエンジニア募集中!
https://jsl.co.jp
? 長野でPython/Djangoをやりたい方
? MBP支給します
? リモートワーク有り/Slack有り
? 勉強会/セミナー参加支援有り
Q&A

More Related Content

DjangoでさくっとWeb アプリケーション開発をする話

Editor's Notes

  • #2: 先程、辻さんが笔测迟丑辞苍の初心者向けの话しをして顶いたのと、前回の厂迟补辫测で阿久津さんが产辞迟辞濒别の话しをしてくれたので、私は顿箩补苍驳辞の话しをさせて顶こうと思います。
  • #5: 一緒にPyconで話しをした弊社のエンジニア垣田が書きました Quitaの記事です。いいね数がハンパないすね。 今回、お話しするに当たって何を話そうかなと思った。 最初は、Djangoのアップデートで泣いた話しとかしようと思ったのですが、まずが広めることを考えようと思いました。
  • #6: 顿箩补苍驳辞入门と合わせて、顿箩补苍驳辞で开発する勘所が分かってもらえればと思います。
  • #8: Djangoって初めて聞いた人 Django使ったことない人、これからやってみようって人
  • #9: ユニットテストの话しとか、多言语対応とか
  • #10: 初心者向けにあれば、お愿いします。
  • #11: D/Jango じゃなくてDjanhoです。