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

76
Django ででででで Web でででででででででででででで でででで Python ででで in でで

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

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

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

みんなの Python 勉強会 in 長野

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

Yuichi Nakazawa @y_nakazawa1220

( 株 ) 日本システム技研 所属   Python/Django 案件 ディレクター兼エンジニア

  GEEKLAB.NAGANO エバンジェリスト

自己紹介

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

元ネタ

スライドシェア: https://goo.gl/Hx9zEp Youtube : https://goo.gl/c8y6xy

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

元ネタ2

https://goo.gl/3FlpjP

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

Django 入門の参考書

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

https://goo.gl/bMHGyiサンプルコード :github

https://goo.gl/9LumRdデモ URL

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

• Python で Web アプリケーション開発したい人• これから Django で開発したい人、興味がある人• Django の初級者向け

このセッションの対象

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

• ベストプラクティス的なこと• Tips 的なこと• その他、細かい Django の機能(テストとか、多言語対応とか・・)

話さないこと

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

#stapy

お願い• こんな書き方あるよ• こうした方が分かりやすいよ• こんなこと知りたいよ

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

Django

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

• フルスタックな Web アプリケーションフレームワーク• MVC でなく、 MVT• 学習コストが低い• admin サイトが秀逸• migration が便利

Django 特徴

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

チュートリアルが良い

https://docs.djangoproject.com/ja/1.10/intro/

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

• Django アプリ作成• Model 作成と migration• admin サイト• 簡単な CRUD• Heroku へのデプロイ

レジュメ( 書籍管理アプリの作り方 )

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

Djanogo アプリ作成

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

Django インストール

$ pip install django

現状だと 1.10.6 あたりが入るはず$ pip freeze djangoDjango==1.10.6

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

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',]

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

ディレクトリ構成.├── 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

・色付きファイルを中心に作業します。・青字は自動生成されます。・赤字は自分で適宜作成します。

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

開発用サーバー起動$ cd myproject$ python manage.py runserverSystem check identified no issues (0 silenced).

March 03, 2017 - 15:23:22Django version 1.10.6, using settings 'stapydemo.settings'Starting development server at http://127.0.0.1:8000/Quit the server with CONTROL-C.

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

開発用サーバーの Tips

$ python manage.py runserver IP: ポート番号

$ python manage.py rumserver --settings= myapp.settings

IP とポート指定したい場合

settings.py (環境設定ファイル)を切り替えたい場合

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

Web アプリケーション開発フロー

1. Model (データ構造)を考える ⇒ Models.py の実装(ビジネスロジックの実装)2. Views.py ⇒ template へ渡すためのデータ加工3. template を作る( HTML/CSS/Javascript )4. URL 設計 ⇒ Urls.py の実装

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

Model 作成とmigration

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

Web アプリケーション開発フロー

1. Model (データ構造)を考える ⇒ Models.py の実装(ビジネスロジックの実装)2. Views.py ⇒ template へ渡すためのデータ加工3. template を作る( HTML/CSS/Javascript )4. URL 設計 ⇒ Urls.py の実装

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

Model とは?

そのアプリケーションが扱う領域のデータと手続き(ビジネスロジック - ショッピングの合計額や送料を計算するなど)を表現する要素である - wikipedia より

DB に定義したいデータ構造を定義する

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

• 基本的に 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)

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

モデルの追加や項目の更新・削除を手軽に DB と同期が取れる仕組み

migration とは

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

• model.py の定義変更を DB に反映させることができる• model を直した場合に、所定のコマンドを叩くと

migrate ファイルを作ってくれる• Django 1.6 までは South

- http://south.aeracode.org

• Django 1.7 からは標準として取り込まれた

migration

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

認証とセッション関連のテーブルを作成$ python manage.py migrateOperations to perform: Apply all migrations: admin, auth, contenttypes, sessionsRunning 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 上にテーブルを作成する

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

管理者ユーザ作成

$ python manage.py createsuperuserUsername (leave blank to use 'nakazawa'): adminEmail address: [email protected]: Password (again): Superuser created successfully.

createsuperuser で管理者ユーザを作成する

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

テーブルの中身をのぞいてみる

$ python manage.py dbshellSQLite version 3.8.10.2 2015-05-20 18:17:19Enter ".help" for usage hints.sqlite>

settings.py に設定してある DBエンジンに接続(デフォは、 sqlite )

sqlite> .tablesauth_group auth_user_user_permissionsauth_group_permissions django_admin_log auth_permission django_content_type auth_user django_migrations auth_user_groups django_session

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

SQL を叩いてみる

sqlite> .header onsqlite> .mode columnsqlite> select id, username, email from auth_user;id username email ---------- ---------- -------------1 admin [email protected]

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

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 のモデル)

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

model を更新した場合( migrations ディレクトリ配下に 000x_xxxx.py が作成される)$ python manage.py makemigrationsMigrations for 'cms': cms/migrations/0001_initial.py: - Create model Book - Create model Impression

DB migration( 変更の抽出 )

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

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 のサンプル

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

$ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, cms, contenttypes, sessionsRunning migrations: Applying cms.0001_initial... OK

DB migration(DB へ反映 )

sqlite> .tablesauth_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

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

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) # 追加

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

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 のテーブルに反映される

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

admin サイト

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

admin サイトにログインしてみる

http://127.0.0.1:8000/admin

※admin サイト :DB のメンテナンスに使用するサイト

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

admin サイト ログイン画面

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

admin サイト

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

admin サイトへ追加する

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)

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

admin サイトへ追加する

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

CRUD

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

CRUD (クラッド)とは、ほとんど全てのコンピュータソフトウェアが持つ永続性[1] の 4つの基本機能のイニシャルを並べた用語。その 4つとは、 Create (生成)、 Read (読み取り)、 Update (更新)、 Delete(削除)である。ユーザインタフェースが備えるべき機能(情報の参照 /検索 / 更新)を指す用語としても使われる。 - wikipedia より

CRUD とは

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

Web アプリケーション開発フロー

1. Model (データ構造)を考える ⇒ Models.py の実装(ビジネスロジックの実装)2. Views.py ⇒ template へ渡すためのデータ加工3. URL 設計 ⇒ Urls.py の実装4. template を作る( HTML/CSS/Javascript )

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

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))

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

• 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 一覧

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

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 のページング部分

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

Listページの書き方ページングの表示例

この部分

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

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 登録/修正

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

CRUD の書き方forms.py

class BookForm(ModelForm): ''' 書籍のフォーム ''' class Meta: model = Book fields = ('name', 'publisher', 'page', )

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

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'), # 削除)

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

Web アプリケーション開発フロー

1. Model (データ構造)を考える ⇒ Models.py の実装(ビジネスロジックの実装)2. Views.py ⇒ template へ渡すためのデータ加工3. URL 設計 ⇒ Urls.py の実装4. template を作る( HTML/CSS/Javascript )

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

• CSS フレームワーク http://getbootstrap.com/• とりあえずお手軽に見栄えするサイトを作りたい場合に便利

Bootstrap を使う

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

STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"),)

静的ファイルの配置場所を設定myproject ディレクトリの下に static ディレクトリを作って配置する場合は、 settings.py に以下のように定義します

• Bootstrap - http://getbootstrap.com/ • jQuery - http://jquery.com/

今回は、以下のサイトからベタに DL して配置します

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

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

静的ファイルの配置イメージ

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

• 一覧系のページは、 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',)

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

• Django のテンプレートは継承できるので、以下のような構造にすると流用性が高いです。

Bootstrap

Bootstrap の JS 、 CSSを定義したベース

CMS の各種ページ

base.html

index.html など

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

Bootstrap の例(一覧)

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

{% 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="{% static 'css/bootstrap.min.css' %}" rel="stylesheet"><link href="{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet"><script src="{% static 'js/jquery-3.1.1.min.js' %}"></script><script src="{% static 'js/bootstrap.min.js' %}"></script>{% block extrahead %}{% endblock %}</head><body> <div class="container"> {% block content %} {{ content }} {% endblock %} </div></body></html>

base.html

Bootstrap の例(一覧)

Bootstrap の JS 、 CSS を記述するベースとなるテンプレート

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

{% 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="{% 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="{% url 'cms:book_mod' book_id=book.id %}" class="btn btn-default btn-sm">修正</a> <a href="{% url 'cms:book_del' book_id=book.id %}" class="btn btn-default btn-sm"> 削除 </a> </td> </tr> {% endfor %} </tbody> </table>{% endblock content %}

book_list.html

Bootstrap の例

↑ 一覧系は Bootstrap の class を使って普通に書く

← base.html を継承← base.html の title ブロックを置き換え← base.html の content ブロックを置き換え

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

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="/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

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

Bootstrap の例( Form )

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

{% extends “base_navi.html" %}{% load bootstrap %}

{% block title %} 書籍の編集 {% endblock title %}

{% block content %} <h3 class="page-header"> 書籍の編集</h3> {% if book_id %} <form action="{% url 'cms:book_mod' book_id=book_id %}" method="post" class="form-horizontal" role="form"> {% else %} <form action="{% 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="{% url 'cms:book_list' %}" class="btn btn-default btn-sm">戻る </a>{% endblock content %}

book_edit.html

Bootstrap の例( Form系)

← django-bootstrap-form を使っているので  Form の項目を Bootstrap 形式で展開してくれる

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

{{ 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を参考にしてみると良いです。

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

アプリケーションを公開する

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

Heroku を使う• Paas https://www.heroku.com• フリープランもあるので、今回はそちらを利用します

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

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 に設定を書く

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

DB の切り替え

$ pip install dj_database_url

DB を PostgreSQL に切り替える。 sqlite が使用できないのと、 MySQL はクレカ登録が必要なため

Heroku の DB 設定を使用するため$ pip install psycopg2PostgreSQL のアダプタ

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

Settings.py を両対応させるfrom socket import gethostnameif ‘my_hostname' in gethostname(): DEBUG = True TEMPLATE_DEBUG = Trueelse: 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() }

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

静的ファイルの扱い静的ファイルを 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 にパスを追加する

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

環境をまとめる

$ pip freeze > requirements.txt

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

デプロイ

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

まとめ• Django は、チュートリアルが充実しているので学習コストが比較的低いです。• フルスタックなので、色々やりたいことがあるのであれば Django を選ぶと良いと思います。• Heroku は、お手軽にデプロイ経験できるので是非使ってみてください。

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

Pythonエンジニア募集中!

https://jsl.co.jp

• 長野で Python/Django をやりたい方• MBP支給します• リモートワーク有り /Slack有り• 勉強会 / セミナー参加支援有り

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

Q&A