[Django3.0]django-widdget-tweaksを使ったスタイリング

Formクラスを使いつつ、テンプレート側でスタイリングする為、django-widdget-tweaksを使用します。

$ pip install django-widget-tweaks

/hanbai/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'sales',
    'widget_tweaks',
]

/sales/forms.py

from django import forms

class MasterForm(forms.Form):
	name = forms.CharField(label='name')
	office = forms.CharField(label='office')
	zipcode = forms.CharField(label='zipcode')
	prefecture = forms.CharField(label='prefecture')
	address = forms.CharField(label='address')
	tel = forms.CharField(label='tel')
	fax = forms.CharField(label='fax')
	email = forms.EmailField(label='email')
	name_top = forms.CharField(label='name_top')
	position_top = forms.CharField(label='position_top')

/sales/views.py

def master_detail(request):
	data = Master.objects.get(id=1)
	params = {
		'data' : data
	}
	return render(request, 'sales/master_detail.html', params)

/sales/templates/sales/master.html

{% load widget_tweaks %}

// 省略
<form action="{% url 'master_complete' %}" method="post">
					{% csrf_token %}
					<div class="row">
						<div class="col-sm">
							<label for="name">会社名 <span class="badge badge-danger">必須</span></label>
							<!-- <input type="text" class="form-control" id="name" name="name" placeholder="会社名を入力してください" required> -->
							{% render_field form.name class="form-control" placeholder="会社名を入力してください" %}
						</div>
						<div class="col-md-4">
							<label for="office">事業所名</label>
							<!-- <input type="text" class="form-control" id="office" name="office" placeholder="事業所の名称を入力してください" > -->
							{% render_field form.office class="form-control" placeholder="事業所の名称を入力してください" %}
						</div>
					</div>

					<br>

					<div class="row">
						<div class="col-md-4">
							<label for="zipcode">郵便番号(7桁) <span class="badge badge-danger">必須</span></label>
							<!-- <input type="text" class="form-control" id="zip" name="zipcode" size="10" maxlength="8" onKeyUp="AjaxZip3.zip2addr(this,'','prefecture', 'address');" placeholder="7桁の郵便番号を入力してください" > -->
							{% render_field form.zipcode class="form-control" placeholder="都道府県を入力してください" id="zip" name="zipcode" onkeyup="AjaxZip3.zip2addr(this,``,`prefecture`, `address`);" %}
						</div>
						<div class="col-md-4">
							<label for="prefecture">都道府県(自動入力)</label>
							<!-- <input type="text" name="prefecture" class="form-control" id="prefecture" placeholder="都道府県を入力してください" > -->
							{% render_field form.prefecture class="form-control" placeholder="都道府県を入力してください" %}
						</div>
					</div>
					<div class="form-group">
						<label for="address">住所 <span class="badge badge-danger">必須</span></label>
						<!-- <input type="text" name="address" class="form-control" id="address" placeholder="住所を入力してください" > -->
						{% render_field form.address class="form-control" placeholder="住所を入力してください" %}
					</div>

					<br>

					<div class="row">
						<div class="col-sm">
							<label for="tel">電話番号 <span class="badge badge-danger">必須</span></label>
							<!-- <input type="text" class="form-control" id="tel" name="tel" placeholder="電話番号を入力してください" > -->
							{% render_field form.tel class="form-control" placeholder="電話番号を入力してください" %}
						</div>
						<div class="col-sm">
							<label for="fax">FAX</label>
							<!-- <input type="text" class="form-control" id="fax" name="fax" placeholder="FAX番号を入力してください" > -->
							{% render_field form.fax class="form-control" placeholder="FAX番号を入力してください" %}
						</div>
					</div>

					<div class="form-group">
						<label for="email">会社メールアドレス <span class="badge badge-danger">必須</span></label>
						<!-- <input type="email" class="form-control" id="email" name="mail" placeholder="担当者のメールアドレスを入力してください" > -->
						{% render_field form.email class="form-control" placeholder="担当者のメールアドレスを入力してください" %}
					</div>

					<div class="row">
						<div class="col-sm">
							<label for="name_top">代表者 <span class="badge badge-danger">必須</span></label>
							<!-- <input type="text" class="form-control" id="name_top" name="name_top" placeholder="代表者名を入力してください" > -->
							{% render_field form.name_top class="form-control" placeholder="代表者名を入力してください" %}
						</div>
						<div class="col-sm">
							<label for="position_top">代表者役職</label>
							<!-- <input type="text" class="form-control" id="position_top" name="position_top" placeholder="代表者の役職を入力してください" > -->
							{% render_field form.position_top class="form-control" placeholder="代表者の役職を入力してください" %}
						</div>
					</div>

					<br><br>

					<div class="col text-center">
						<button class="btn" type="submit">更新</button>
					</div>
				</form>

ajaxの部分も問題なく動きます。

[Django3.0]Formクラスを試してみる

Djangoの入力フォームをフォームクラスを使って書いていきたい。
HTMLでベタ書きしているものをフォームクラスに移管する。

### Form Class
まずfomrs.pyを作ります。
/sales/forms.py

from django import forms

class MasterForm(forms.Form):
	name = forms.CharField(label='name')
	office = forms.CharField(label='office')
	zipcode = forms.CharField(label='zipcode')
	prefecture = forms.CharField(label='prefecture')
	address = forms.CharField(label='address')
	tel = forms.CharField(label='tel')
	fax = forms.CharField(label='fax')
	email = forms.EmailField(label='email')
	name_top = forms.CharField(label='name_top')
	position_top = forms.CharField(label='position_top')

次にビュー関数を編集する。
/sales/views.py

from .forms import MasterForm

def master(request):
	params = {
		'form': MasterForm()
	}
	return render(request, 'sales/master.html', params)

/sales/templates/sales/master.html

<form action="{% url 'master_complete' %}" method="post">
					{% csrf_token %}
					{{ form }}
					<br><br>
					<div class="col text-center">
						<button class="btn" type="submit">更新</button>
					</div>
				</form>

forms.pyの使い方はわかったが、view側のスタイリングをどうにかしないといけない。

form.as_tableやform.as_pだと、inputのcol-md-*の調整ができないないので、方法を考える必要がある。

[Django3.0]MySQLへのデータ登録

受け取る側のviews.pyでModesに入れれば良い

/sales/views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import Master

def master_complete(request):
	if(request.method == 'POST'):
		name = request.POST['name']
		office = request.POST['office']
		zipcode = request.POST['zipcode']
		prefecture = request.POST['prefecture']
		address = request.POST['address']
		tel = request.POST['tel']
		fax = request.POST['fax']
		mail = request.POST['mail']
		name_top = request.POST['name_top']
		position_top = request.POST['position_top']
		master = Master(name=name, office=office, zipcode=zipcode, prefecture=prefecture, address=address,
			tel=tel,fax=fax, mail=mail, name_top=name_top, position_top=position_top)
		master.save()
	return render(request, 'sales/master_complete.html')

mysql> select * from sales_master;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect…
Connection id: 44
Current database: hanbai

+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| id | name | office | zipcode | prefecture | address | tel | fax | mail | name_top | position_top | created_at | updated_at |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| 1 | 東京テクノロジー株式会社 | 本社 | 100-6321 | 東京都 | 千代田区丸の内2-4-1 | 03-1234-5678 | 03-1234-5679 | info@tokyotech.com | 山田太郎 | 代表取締役 | 2020-08-22 12:30:30.000000 | 2020-08-22 12:30:30.000000 |
| 2 | テスト | 本社 | 100-0001 | 東京都 | 千代田区千代田1-1-1 | 03-1234-5678 | 03-1234-5679 | test@gmail.com | 山田太郎 | | 2020-08-26 22:03:28.299894 | 2020-08-26 22:03:28.299937 |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
2 rows in set (0.00 sec)

[Django3.0]フォーム送信の基本機能を実装する

まず、登録完了ページのurls.py, views.pyを追記し、完了画面のhtml(master_complete.html)をサクッと作ります。

/sales/urls.py

urlpatterns = [
	// 省略
	path('master/complete', views.master_complete, name='master_complete'),
	// 省略
]

/sales/views.py

def master_complete(request):
	return render(request, 'sales/master_complete.html')

### フォーム画面
フォーム送信先を登録完了画面のnameに設定し、csrf_tokenを設定する

/sales/templates/sales/master.html

<form action="{% url 'master_complete' %}" method="post">
    {% csrf_token %}
</form>

### フォーム関数
登録完了画面で、request.POST[‘*’]で送られてきた値を受け取ります。

/sales/views.py

def master_complete(request):
	name = request.POST['name']
	office = request.POST['office']
	zipcode = request.POST['zipcode']
	prefecture = request.POST['prefecture']
	address = request.POST['address']
	tel = request.POST['tel']
	fax = request.POST['fax']
	mail = request.POST['mail']
	name_top = request.POST['name_top']
	position_top = request.POST['position_top']
	return render(request, 'sales/master_complete.html')

挙動確認

OK
次に入力画面でformクラスを使いたいんだけど、form.as_tableやform.as_pなどではデザインを再現できないような気がするんだが、やり方あるんだろうか?

[Django3.0]datetime型をviewで表示させる

デフォルトではY年n月j日H:i で表示される。
表示を変更するには、view側で以下のように書けば良い。

{{data.created_at|date:"Y/n/j H:i:s"}}

登録日時 2020/8/22 21:30:30 更新日時 2020年8月22日21:30

OK
${className}.objects.get(id=1) で取得して表示する方法はわかった。
次は、createの手順を行こう

[Django3.0]mysqlのデータをviewに表示

前提: MySQLの中にデータが入っています。

mysql> select * from sales_master;
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| id | name | office | zipcode | prefecture | address | tel | fax | mail | name_top | position_top | created_at | updated_at |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| 1 | 東京テクノロジー株式会社 | 本社 | 100-6321 | 東京都 | 千代田区丸の内2-4-1 | 03-1234-5678 | 03-1234-5679 | info@tokyotech.com | 山田太郎 | 代表取締役 | 2020-08-22 15:00:00.000000 | 2020-08-22 15:00:00.000000 |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
1 row in set (0.00 sec)

### template側
まず、データを表示させるtemplateを作成します。

/sales/urls.py

urlpatterns = [
	// 省略
	path('master/edit', views.master, name='master'),
	path('master/detail', views.master_detail, name='master_detail'),
	// 省略
]

/sales/views.py

def master_detail(request):
	return render(request, 'sales/master_detail.html')

/templates/sales/master_detail.html

{% extends 'sales/layout.html' %}
{% load static %}

{% block title %}自社基本情報 | hanbai - 自社基本情報を表示しています{% endblock %}

{% block description %}<meta name="Description" content="見積管理、在庫管理、販売管理はhanbai">{% endblock %}

{% block header_script %}
	// 省略
{% endblock %}

	
{% block content %}
			<div class="client">

				<nav aria-label="パンくずリスト">
					<ol class="breadcrumb">
	  					<li class="breadcrumb-item" aria-current="page">得意先詳細:○○株式会社</li>
					</ol>
				</nav>

				<table class="table">
					<tr>
						<td class="bg">会社名</td>
						<td>ABC商事株式会社</td>
						<td class="bg">事業所</td>
						<td>本社</td>
					</tr>
					<tr>
						<td class="bg">郵便番号</td>
						<td>100-0001</td>
						<td class="bg">都道府県</td>
						<td>東京都</td>
					</tr>
					<tr>
						<td class="bg">住所</td>
						<td colspan="3">千代田区大手町1-1-1</td>
					</tr>
					<tr>
						<td class="bg">電話番号</td>
						<td>03-1234-5678</td>
						<td class="bg">FAX</td>
						<td>03-1234-5679</td>
					</tr>
					<tr>
						<td class="bg">会社メールアドレス</td>
						<td colspan="3">info@abc.co.jp</td>
					</tr>
					<tr>
						<td class="bg">代表者</td>
						<td>山田太郎</td>
						<td class="bg">代表者役職</td>
						<td>代表取締役</td>
					</tr>
					<tr>
						<td class="bg">登録日時</td>
						<td>2020/08/20</td>
						<td class="bg">更新日時</td>
						<td>2020/08/20</td>
					</tr>
				</table>

			<br>
			</div>
{% endblock %}

{% block script %}
{% endblock %}

ここにmysqlからデータを引っ張ってくる

### views.pyの編集
/sales/views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import Master

def master_detail(request):
	data = Master.objects.get(id=1)
	params = {
		'data' : data
	}
	return render(request, 'sales/master_detail.html', params)

### template側
/templates/sales/master_detail.html

<table class="table">
					<tr>
						<td class="bg">会社名</td>
						<td>{{data.name}}</td>
						<td class="bg">事業所</td>
						<td>{{data.office}}</td>
					</tr>
					<tr>
						<td class="bg">郵便番号</td>
						<td>{{data.zipcode}}</td>
						<td class="bg">都道府県</td>
						<td>{{data.prefecture}}</td>
					</tr>
					<tr>
						<td class="bg">住所</td>
						<td colspan="3">{{data.address}}</td>
					</tr>
					<tr>
						<td class="bg">電話番号</td>
						<td>{{data.tel}}</td>
						<td class="bg">FAX</td>
						<td>{{data.fax}}</td>
					</tr>
					<tr>
						<td class="bg">会社メールアドレス</td>
						<td colspan="3">{{data.mail}}</td>
					</tr>
					<tr>
						<td class="bg">代表者</td>
						<td>{{data.name_top}}</td>
						<td class="bg">代表者役職</td>
						<td>{{data.position_top}}</td>
					</tr>
					<tr>
						<td class="bg">登録日時</td>
						<td>{{data.created_at}}</td>
						<td class="bg">更新日時</td>
						<td>{{data.updated_at}}</td>
					</tr>
				</table>

おおおお、何事もなく表示できました。割と簡単すぎた。
1件だけ取得した場合はforループで回す必要がない為、html側では{{data.${カラム名}}}とするだけですね。
created_atとupdate_atは、mysql側では”2020-08-22 15:00:00.000000″で入っているのに、view側では”2020年8月23日0:00″で表示されているので、ここを直したい。

[Django3.0]mysqlで日本語入力できない時2

$ sudo vi /etc/mysql/my.cnf

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

[mysqld]
character-set-server=utf8mb4
skip-character-set-client-handshake
default-storage-engine=INNODB

[client]
# default-character-set=utf8mb4

[mysqldump]
default-character-set=utf8

[mysql]
# default-character-set=utf8

$ sudo /etc/init.d/mysql restart
$ mysql -u root -p
mysql> use hanbai;

mysql> insert into sales_master (name, office, zipcode, prefecture, address, tel, fax, mail, name_top, position_top, created_at, updated_at) values (‘東京テクノロジー株式会社’, ‘本社’, ‘100-6321’, ‘東京都’, ‘千代田区丸の内2-4-1′, ’03-1234-5678′, ’03-1234-5679’, ‘info@tokyotech.com’, ‘山田太郎’, ‘代表取締役’, ‘2020-08-22 15:00:00’, ‘2020-08-22 15:00:00’);
Query OK, 1 row affected (0.01 sec)

mysql> select * from sales_master;
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| id | name | office | zipcode | prefecture | address | tel | fax | mail | name_top | position_top | created_at | updated_at |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| 3 | | | 100-6321 | | 2-4-1 | 03-1234-5678 | 03-1234-5679 | info@tokyotech.com | | | 2020-08-22 15:00:00.000000 | 2020-08-22 15:00:00.000000 |
| 4 | 東京テクノロジー株式会社 | 本社 | 100-6321 | 東京都 | 千代田区丸の内2-4-1 | 03-1234-5678 | 03-1234-5679 | info@tokyotech.com | 山田太郎 | 代表取締役 | 2020-08-22 15:00:00.000000 | 2020-08-22 15:00:00.000000 |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+

あれ? 普通に出来たな。さっきまで出来なかったのに。。

mysql> TRUNCATE table sales_master;
Query OK, 0 rows affected (0.04 sec)

mysql> select * from sales_master;
Empty set (0.00 sec)

mysql> insert into sales_master (name, office, zipcode, prefecture, address, tel, fax, mail, name_top, position_top, created_at, updated_at) values (‘東京テクノロジー株式会社’, ‘本社’, ‘100-6321’, ‘東京都’, ‘千代田区丸の内2-4-1′, ’03-1234-5678′, ’03-1234-5679’, ‘info@tokyotech.com’, ‘山田太郎’, ‘代表取締役’, ‘2020-08-22 15:00:00’, ‘2020-08-22 15:00:00’);
Query OK, 1 row affected (0.00 sec)

mysql> select * from sales_master;
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| id | name | office | zipcode | prefecture | address | tel | fax | mail | name_top | position_top | created_at | updated_at |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
| 1 | 東京テクノロジー株式会社 | 本社 | 100-6321 | 東京都 | 千代田区丸の内2-4-1 | 03-1234-5678 | 03-1234-5679 | info@tokyotech.com | 山田太郎 | 代表取締役 | 2020-08-22 15:00:00.000000 | 2020-08-22 15:00:00.000000 |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
1 row in set (0.00 sec)

OK
次はこの入力された値をDjangoで表示させたい。

[Django3.0]mysqlに日本語入力できない

migrationで作成したカラム
mysql> describe sales_master;
+————–+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————–+————–+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| office | varchar(255) | YES | | NULL | |
| zipcode | varchar(8) | NO | | NULL | |
| prefecture | varchar(20) | NO | | NULL | |
| address | varchar(255) | NO | | NULL | |
| tel | varchar(15) | NO | | NULL | |
| fax | varchar(15) | YES | | NULL | |
| mail | varchar(255) | NO | | NULL | |
| name_top | varchar(255) | NO | | NULL | |
| position_top | varchar(100) | YES | | NULL | |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
+————–+————–+——+—–+———+—————-+
13 rows in set (0.00 sec)

これに手動でデータを挿入します。
mysql> insert into sales_master (name, office, zipcode, prefecture, address, tel, fax, mail, name_top, position_top) values (‘東京テクノロジー株式会社’, ‘本社’, ‘100-6321’, ‘東京都’, ‘千代田区丸の内2-4-1′, ’03-1234-5678′, ’03-1234-5679’, ‘info@tokyotech.com’, ‘山田太郎’, ‘代表取締役’);
ERROR 1366 (HY000): Incorrect string value: ‘\xE6\x9D\xB1\xE4\xBA\xAC…’ for column ‘name’ at row 1

mysql> show variables like “chara%”;
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+
8 rows in set (0.01 sec)

$ sudo vi /etc/mysql/my.cnf

[mysqld]
character-set-server=utf8
skip-character-set-client-handshake
default-storage-engine=INNODB

[mysqldump]
default-character-set=utf8

[mysql]
# default-character-set=utf8

$ sudo /etc/init.d/mysql restart
mysql> status;
————–
mysql Ver 14.14 Distrib 5.7.31, for Linux (x86_64) using EditLine wrapper

Connection id: 2
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ”
Using delimiter: ;
Server version: 5.7.31-0ubuntu0.18.04.1 (Ubuntu)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/run/mysqld/mysqld.sock
Uptime: 24 sec

Threads: 1 Questions: 5 Slow queries: 0 Opens: 105 Flush tables: 1 Open tables: 98 Queries per second avg: 0.208
————–

$ sudo apt-get install language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF-8

だめだ、万事休す
adminから入力できるようにする
/sales/admin.py

from django.contrib import admin
from .models import Master

admin.site.register(Master)

mysql> insert into sales_master (name, office, zipcode, prefecture, address, tel, fax, mail, name_top, position_top, created_at, updated_at) values (”, ”, ‘100-6321’, ”, ‘2-4-1′, ’03-1234-5678′, ’03-1234-5679’, ‘info@tokyotech.com’, ”, ”, ‘2020-08-22 15:00:00’, ‘2020-08-22 15:00:00’);
Query OK, 1 row affected (0.00 sec)

mysql> select * from sales_master;
+—-+——+——–+———-+————+———+————–+————–+——————–+———-+————–+—————————-+—————————-+
| id | name | office | zipcode | prefecture | address | tel | fax | mail | name_top | position_top | created_at | updated_at |
+—-+——+——–+———-+————+———+————–+————–+——————–+———-+————–+—————————-+—————————-+
| 3 | | | 100-6321 | | 2-4-1 | 03-1234-5678 | 03-1234-5679 | info@tokyotech.com | | | 2020-08-22 15:00:00.000000 | 2020-08-22 15:00:00.000000 |
+—-+——+——–+———-+————+———+————–+————–+——————–+———-+————–+—————————-+—————————-+
1 row in set (0.00 sec)

何故だ。。。取り敢えず頭を冷やそう。

[Django3.0]migrationしてテーブル作成する手順

Djangoでmigrationを実行するには、
1.Models.pyにテーブル名とカラムを記載
2.migrationファイルの作成
3.マイグレーションで実行されるSQL確認
4.マイグレーションの実行

その為、まずUIを元にデータ型を整理します。

UI

データ型

データ型を元にmodels.pyを書いていきます。
/sales/models.py

from django.db import models

class Master(models.Model):
	name = models.CharField(max_length=255)
	office = models.CharField(max_length=255, null=True)
	zipcode = models.CharField(max_length=8)
	prefecture = models.CharField(max_length=20)
	address = models.CharField(max_length=255)
	tel = models.CharField(max_length=15)
	fax = models.CharField(max_length=15, null=True)
	mail = models.EmailField(max_length=255)
	name_top = models.CharField(max_length=255)
	position_top = models.CharField(max_length=100, null=True)
	created_at = models.DateTimeField(auto_now_add=True)
	updated_at = models.DateTimeField(auto_now=True)

	def __str__(self):
		return self.name

– max_lengthは基本はvarchar(255)とします
– 郵便番号、TEL、FAXはハイフンなしであればIntegerですが、ハイフンありで入力する場合もあるのでCharFieldにしておきます
– null可のカラムは null=Trueと書いておきます
– __str__の使い方がよくわからないので、とりあえずreturn self.nameとしておきます。

$ python manage.py makemigrations sales

/sales/migrations/0001_initial.py

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Master',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=255)),
                ('office', models.CharField(max_length=255, null=True)),
                ('zipcode', models.CharField(max_length=8)),
                ('prefecture', models.CharField(max_length=20)),
                ('address', models.CharField(max_length=255)),
                ('tel', models.CharField(max_length=15)),
                ('fax', models.CharField(max_length=15, null=True)),
                ('mail', models.EmailField(max_length=255)),
                ('name_top', models.CharField(max_length=255)),
                ('position_top', models.CharField(max_length=100, null=True)),
                ('created_at', models.DateField(auto_now_add=True)),
                ('updated_at', models.DateField(auto_now=True)),
            ],
        ),
    ]

$ python manage.py migrate
mysql> show tables;
+—————————-+
| Tables_in_hanbai |
+—————————-+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
| sales_master |
+—————————-+
11 rows in set (0.00 sec)

mysql> describe sales_master;
+————–+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————–+————–+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| office | varchar(255) | YES | | NULL | |
| zipcode | varchar(8) | NO | | NULL | |
| prefecture | varchar(20) | NO | | NULL | |
| address | varchar(255) | NO | | NULL | |
| tel | varchar(15) | NO | | NULL | |
| fax | varchar(15) | YES | | NULL | |
| mail | varchar(255) | NO | | NULL | |
| name_top | varchar(255) | NO | | NULL | |
| position_top | varchar(100) | YES | | NULL | |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
+————–+————–+——+—–+———+—————-+
13 rows in set (0.00 sec)

tableの作成方法まできました。
table nameはアプリケーション名が先頭に付くので、sales_masterになっていることがわかります。ER図のtable名も直しておきます。
続いて、手動でデータをinsertして、表示するところまで行きたい。

[Django3.0]migrationしていこう

auth_userの構造がわかったので、appの方で実装していきます。

mysql> create database hanbai;
Query OK, 1 row affected (0.00 sec)

/hanbai/settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'myapp',
        'USER': 'root',
        'PASSWORD': '***',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

$ python manage.py makemigrations sales
No changes detected in app ‘sales’
$ python manage.py migrate

mysql> show tables;
+—————————-+
| Tables_in_hanbai |
+—————————-+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+—————————-+
10 rows in set (0.00 sec)

$ python manage.py createsuperuser
Username (leave blank to use ‘vagrant’): admin
Email address: admin@gmail.com
Password:
Password (again):
Superuser created successfully.

$ python manage.py runserver 192.168.33.10:8000

aplicationのデータ構造上、hasManyの親となるテーブルから順番にmigrationしていく。

自社基本情報を入れるmasterテーブルから作っていく。