DjangoとMySQLと

Django使ってMySQLのDBに接続してデータを記入したり、出力したり、してみたいと思います。
MySQLの設定とかは他のところを参考にしてほしいです。
注意：この記事ではMySQLを標準のDBとしては扱わず、外部のDBを操作するようにしています。
　　：初心者なので間違いなどがあるので信じ込みすぎないでください。
ここではそれぞれ個別では使える状態を前提にやってきます。

# 使ってる環境
とりあえず使っている環境は
vagrant　2.0.2
Host:win10
guest:ubuntu　14.04.6
MySQL　0.0.2

# 準備
pipで入れていきましょう。
一応`freeze`で確認しましたが、抜けだったりいらないのがあるかも。

```ruby:Terminal
pip install mysql
pip install mysql-connector-python-rf
pip install mysqlclient
pip install PyMySQL
```
これでいいはず。

# MySQLの操作
テスト用にDB作って、テーブル作りましょう。
MySQLへの接続は以下のようにします。

```ruby:Terminal
 mysql -u ユーザー名
```
既存のDBにアクセスする場合、

```ruby:Terminal
mysql -h ホスト名 -u ユーザー名 -p
```
そしてこの後パスワード入力で起動します。
でわでわ、まずDBを作りましょう。

```ruby:Terminal
create database DB名;
```
DB名は`test_DB`としておきましょう。
作れたかどうかは下記のコマンドを実行すると見れますよ。

```ruby:Terminal
show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test_DB            |
+--------------------+
```
DBの一覧の中に`test_BD`が入っていますね。作成できたようです。
このDBを使うので

```ruby:Terminal
use DB名
```
のように実行して`test_BD`を使うように設定しておきましょう。
では、テーブルを作ってみましょう。今回作るテーブルは`test_Table`という名前で、

|    user_name     |         age       |        height      |        weight      |        song        |    add_day        |
|:----------------:|:-----------------:|:------------------:|:------------------:|:------------------:|:------------------:|

こんなでいいでしょうか。
`age`は整数値、`height`,`weight`は浮動小数、`User_Name`,`song`は文字列データ、`add_day`は日付データとしましょう。
それでは作りましょう。

```ruby:Terminal
CREATE TABLE テーブル名( 
フィールド名 型 オプション, 
フィールド名 型 オプション,
...
フィールド名 型 オプション
);
```
こんな感じで追加できます。
今回の例でいくと、

```ruby:Terminal
CREATE TABLE test_Table( 
user_name varchar(15), 
age int,
height float,
weight float,
song varchar(30), 
add_day  datetime
) DEFAULT CHARSET=utf8;
```
これで作成できます。最後にちょっと付け加わっているのは、
このテーブルを使うときは基本UTF8を使いますよーって明示的に指定しています。こうしないと日本語を入力したとき`???`と文字化けしてしまい、困ります。
データの入れ込みとかはDjangoで行うのでMySQLはここまで。
MySQLからはCtrl+Cで抜け出せます。

# Djangoの準備をする
それではまずはプロジェクト作ってアプリを作りましょう。
これは前の記事で書いているので大体流します。

```ruby:Terminal
django-admin startproject mysite
python manage.py startapp testapp
```
アプリのを追加して、

```ruby:mysite/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'testapp', # 追加
]
```
アプリのURLを読むようにして、

```ruby:mysite/urls.py
from django.conf.urls import include #追加

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('testapp.urls')), # 追加
]
```
`testapp`に`urls.py`を作成して、Viewを表示するようにして、

```ruby:testapp/urls.py
from django.urls import path
from testapp import views

app_name = 'testapp'

urlpatterns = [
    path('', views.list_view, name='list_view'),
]
```
そして表示するためのviewを適当に作って

```ruby:testapp/views.py
def list_view(request):
    return render(request, 'testapp/list_view.html')
```
そんでもって`testapp/templates/testapp/list_view.html`を作る。
これで実行してみたら何もないページが表示されるはずです。

最後にmigrateしてスーパーユーザーを作りましょう。適当にadminにしていますが、お好みでどうぞ。

```ruby:Terminal
python manage.py createsuperuser
> Username (leave blank to use 'vagrant'): admin
> Email address:
...
```
メアドは何も書かなくても大丈夫です。
パスワードを指定したとき、短かったり、よくありそうだったりしたら警告出るので、yでスルーしちゃいましょう。


# Djangoからデータを追加してみる
##viewの記述
とりあえず適当なデータを入力してみましょう。
testapp/views.pyをいじっていきます。

```ruby:testapp/views.py
from django.shortcuts import render
import mysql.connector  # 追加
from datetime import datetime  # 追加


def list_view(request):
    user_name = request.user.username
    age = 17
    height = 186.2
    weight = 61.5
    song = 'きらりんロボのテーマ'
    add_day = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    connect = mysql.connector.connect(
        database='test_DB',
        user="root",
        charset='utf8'
    )
    cur = connect.cursor(dictionary=True)

    cur.execute(
        """
        INSERT INTO test_Table(
            user_name ,
            age,
            height ,
            weight,
            song,
            add_day
        )
        VALUES (%s,%s,%s,%s,%s,%s)
        """, [user_name, age, height, weight, song, add_day]
    )
    connect.commit()
    cur.execute('SELECT * FROM test_Table WHERE user_name  = %s', [request.user.username])
    rows = cur.fetchall()
    cur.close()
    connect.close()

    return render(request, 'testapp/list_view.html', context={
        'data': rows
    })
```

まず上の方で変数に適当なデータを与えておきます。
`user_name`に入れている`request.user.username`はログインユーザー名を持ってくる命令です。

`mysql.connector.connect`のところでDBにアクセスしてます。既存のDBにアクセスしたい場合は`host`とか`password`とかが必要になるかもしれないので、適宜追加していきましょう。

接続出来たら`connect.cursor`を使います。どうやらこれをするとMySQL側でコマンドを実行できるっぽい？のですが詳しくはわからないです。(おべんきょしないと)
ただ、この引数に`dictionary=True`としているのは、データの出力を辞書型で行ってほしいのでこのように書いています。
`cur.execute`以下に実際に動作させたいコマンドを記入していきます。

一回目の`execute`はデータの挿入コードを実行しています。
DBへの変更系のコマンドは`connect.commit()`を実行しないと適用されないっぽいので忘れないようにしましょう。

二回目の`execute`はデータの取得をしています。この命令だとテーブル上にあるユーザー名が特定のデータを持ってくる命令です。今回は`request.user.username`を指定しているので、ログインユーザー名と同じデータのみを持ってくることになるわけです。
出力結果を`cur.fetchall()`を用いることで出力します。
その後、close()で接続を終わらせています。
最後に`context`でテンプレートにデータを渡します。
## テンプレートの記述
続いてテンプレートを編集していきましょう。

```ruby:list_view.html
{{data.0}}
```
はい。データの表示だけでしたらこれで十分です。
実行してみましょう。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/3461f9df-d2be-d36c-a3bc-badeb07a674b.png)

データが表示されました。
でもユーザー名が表示できてませんね。これはまだログインしていないからです。
`http://localhost:18000/admin/login/?next=/admin/`へ移動して、ログインしましょう。
ログインは先ほど作ったスーパーユーザーで入れます。
ログインしたらもう一度トップに戻ってみましょう。![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/cbb9fa67-2e50-d68a-4a7b-96e41056158e.png)

ユーザー名が記入されていますね。

ところでなんで`{{data.0}}`と`0`が付いてるのでしょう。
これは全部のデータを表示するとわかります。（このページを起動するたびにデータを追加してるのでめちゃくちゃ多いかもしれないです。）
後ろの`.0`を消して実行してみましょう。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/e53910b6-2a71-6bdd-20ef-a069abc86d88.png)

小っちゃくてちょっとわかりにくいかもなんで少し簡単に表すと、

```ruby:data
[
  {データたち},
  {データたち},
  …
]
```
こんな感じにひとまとまりの辞書データがリストの中に1つずつ入っているのです。なので最初の一つ目を表示するには後ろに`.0`を記入する必要があるのです。
ではデータ群をそれぞれ1列ずつ表示してみましょう。テンプレートでforを回すことで表示できます。

```ruby:list_view.html
{% for d in data %}
{{d}}<br>
{% endfor %}
```
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/886c3274-7fc8-b8ad-742e-d7627df10e65.png)

このように表示できました。
一応簡単に表示できましたがどうせなので見やすくリストにしてみましょう。

```ruby:list_view.html
<table border="1">
    <thead>
    <tr>
        <th>ユーザー名</th>
        <th>年齢</th>
        <th>身長</th>
        <th>体重</th>
        <th>曲</th>
        <th>追加日</th>
    </tr>
    </thead>
    <tbody>
    {% for d in data %}
    <tr >
        <td class="lead">{{d.user_name}}</td>
        <td class="lead">{{d.age}}</td>
        <td class="lead">{{d.height}}</td>
        <td class="lead">{{d.weight}}</td>
        <td class="lead">{{d.song}}</td>
        <td class="lead">{{d.add_day}}</td>
    </tr>
    {% endfor %}
    </tbody>
</table>
```
めちゃくちゃ適当ですが、実行してみると表になっていると思います。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/1ad47af2-3171-9443-e4c0-002cb9752a1e.png)

# まとめ
同じこと調べまくってしまうので備忘録として書いてますん。
今回はMySQLのDBにアクセスして読み書きを行ってみました。
次回はこれに手を加えてユーザーの入力を書き込んでみたいと思います。
そいでは。