ラズパイにDjango 3.0.6の環境を構築（MySQL）

ラズパイにdjango環境を構築します。したくなったので。
使用したラズパイは Raspberry pi 3B+ 。

Django環境の構築情報が調べると古いものばかりなのと、ラズパイにはMySQLが入らないのでmariadbで設定する際に苦戦したのでメモです。

作業内容を動画にしましたので、実際に設定している様子は[こちら](https://youtu.be/ZYVdewrX4Zg)を確認してください。

## バージョン確認
```bash
$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 9.11 (stretch)
Release: 9
Codename: stretch
$ uname -a
Linux raspberry 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv71 GNU/Linux
```

## アップデート
```bash
$ sudo apt update
$ sudo apt upgrade -y
$ sudo reboot
```

## Python
最初からインストールされてるはずなので飛ばして良い。
バージョンが低い場合は3.7.xまでアップデートした方がいいかも。

```bash
$ sudo apt install python3 python3-dev
$ python3 -V
Python 3.7.3
```

## Django
### 本体をインストール

```bash
$ sudo apt install python3-django
$ pip3 install Django==3.0.6
$ django-admin --version
3.0.6
```

`$ pip3 list --outdated` で最新バージョンか確認できる。

## MySQL（mariadb）
MySQL自体はインストールできないのでmariadbをインストールする。

### 本体をインストール
```bash
$ sudo apt install mariadb-server
$ mysql --version
mysql  Ver 15.1 Distrib 10.3.22-MariaDB, for debian-linux-gnu (i686) using readline 5.2
```

### クライアントをインストール
```bash
$ sudo apt install libmariadb-dev
$ pip3 install --no-binary :all: mysqlclient
~ 
Successfully installed mysqlclient-1.4.6
```

### 初期設定
rootユーザーのパスワードを設定する。
`'********'`を任意のパスワードにする。

```bash
$ sudo -i
# mysql -u root
mysql> use mysql;
mysql> update user set plugin='' where user='root';
mysql> update user set password=password('********') where user='root';
mysql> flush privileges;
```
update文はまとめてしまっても良い。

`select user,password,plugin from user;` で設定情報を確認できる。
![vlcsnap-2020-05-27-16h16m34s284.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126147/46eb1533-dfcb-38b0-3be6-1f3915a1cc45.png)

### DBを作成
```bash
mysql> create database mydb;
```

## プロジェクトを作成して起動
### Djangoプロジェクトを作成
```bash
$ django-admin startproject mysite
```

### 設定を変更
`settings.py`の以下の2点を変更する。

```bash
$ sudo nano mysite/mysite/settings.py
```

`ALLOWED_HOSTS = []`の[]に'*'を入力する。

```settings.py
# ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']
```

初期ではsqlite3を指定しているんでコメントアウト（または削除）し、MySQLの設定を記述する。
`NAME`には作成したDB名を指定する。
`'********'`を設定したパスワードにする。

```settings.py
DATABASES = {
#    'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb',
        'USER': 'root',
        'PASSWORD': '********',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}
```

### 設定が正しく行えたか確認する
```bash
$ python3 mysite/manage.py migrate
```
![vlcsnap-2020-05-27-16h15m56s570.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126147/e37e2cd8-a81a-7f9e-0d06-915124507b70.png)

### 問題がなければ起動
```bash
$ python3 mysite/manage.py runserver
```

起動したらブラウザで確認しよう。
ローカルの8000番ポートで接続できる。
http://127.0.0.1:8000

これで土台ができたのであとは参考サイトを見ながらアプリを作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126147/5d52b48a-7ceb-59d1-69a2-3807523708ac.png)

お疲れさまでした。

## トラブルシューティング
### mysqlclientをインストールできない
`Error Code 1`とか以下の様な文言が出てインストールできない場合。

```bash
OSError: mysql_config not found
```

以下をインストールすること。

```bash
$ sudo apt install python3-dev libmariadb-dev
```

### MySQLにrootユーザーで入れない。
rootユーザーのパスワードを忘れた場合、パスワードを再設定。

```
$ mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
```

### パスワード再設定
#### MySQLをセーフモードで起動
```bash
$ sudo -i
# service mysqld stop
# mysqld_safe --skip-grant-tables &
```

#### rootユーザーのパスワードを設定
```bash
# mysql -u root
mysql> use mysql;
mysql> update user set plugin='' where user='root';
mysql> update user set password=password('********') where user = 'root';
mysql> flush privileges;
```

#### セーフモードで起動したMySQLを終了する
```bash
# kill -KILL [mysqld_safe のPID]
# kill -KILL [mysqld のPID]
```

#### ※mysqldのPIDの調べ方
```bash
$ ps aux | grep mysqld
```

#### MySQLを起動させる
```bash
# service mysqld start
```

### 権限を再設定
※権限で怒られてなかったらやらなくていいです。コマンドの内容を理解して行ってください。
userテーブルを全削除してrootユーザーに全権限を付与してみます。

```
mysql> use mysql;
mysql> select * from user;
mysql> truncate table user;
mysql> flush privileges;
mysql> grant all privileges on *.* to root@localhost identified by '********' with grant option;
mysql> flush privileges;
```

### セーフモードで起動しない場合
```bash
# mysqld_safe --skip-grant-tables &
$ 2018-08-05T15:34:57.6NZ mysqld_safe A mysqld process already exists
```
既に起動していると言われて怒られたら既に動いているプロセスを止めましょう。
上記にあるPIDを確認してKILLすること。

### MySQLクライアントが無いと怒られる時
古い情報を見ながらやってると起きがちなやつ。

```bash
Error loading MySQLdb module: No module named 'MySQLdb'.
Did you install mysqlclient or MySQL-python?
```

以前のバージョンでの解決策として `$ pip install mysqlclient` とかやったり`setting.py`に以下のようなプログラムを書くようで、エラーをそのまま調べるとこの情報ばかりでてくるけど、この解決策自体が古い。

```settings.py
# この解決策は古いので削除してください
import pymysql
pymysql.install_as_MySQLdb()
```

django2.0からは`pymysql`は非推奨となっているので、もしインストールしているならアンインストールしてください。
現在は`mysqlclient`を使うので、以下の内容でインストールしてください。

```bash
$ pip3 install --force-reinstall --ignore-installed --no-binary :all: mysqlclient
```

普通にインストール（ `$ pip3 install mysqlclient` ）するだけではdjangoは参照してくれない様で同様のエラーになります。

# 参考

- [Django3入門: 初心者でも10分でWebサービスを作れる！PythonフレームワークDjangoとPaizaCloudの使い方](https://paiza.hatenablog.com/entry/2018/02/28/paizacloud_django)
- [SQLユーザー要注意！意外と知らないMySQLのrootパスワード設定方法](https://blog.codecamp.jp/root-password)
- [MySQLインストール時に遭遇する「アクセス拒否エラー(Access denied for user ‘root’@’localhost’)」の対処](https://www.aiship.jp/knowhow/archives/28257)
- [mysqld_safe A mysqld process already existsが出た時の対処方法](https://www.takafumitaba.com/mysql-already-exists)
- [MySQL 8.0 を yum でインストール&設定メモ](https://blog.apar.jp/linux/9868/#MySQL_80-2)
- [#25 ラズパイにMySQLをインストール](https://ameblo.jp/raspberrypi-blueberry/entry-12578724754.html)