[Django3.0]viewのループ処理でremodalにidを渡して各レコードを削除したい

得意先リスト一覧ページで、各クライアントの行で削除ボタンを押下した時に、操作ミスによる削除を防ぐため、直ぐに削除するのではなく、remodalで一度確認画面をかまして削除するようにしたい。

### document.getElementsByNameで値を渡そうとした場合
渡す値が一つであれば、getElementsByName、getElementByIdなどで取得が出来る
ただし、forループで回している場合、同じ値を渡してしまい上手くいかない
*.html

{% for item in data %}
						<tr>
							<td id="hoge">{{item.id}}</td>
							<td class="text-nowrap">{{item.name}}</td>
							<td class="text-nowrap">〒{{item.zipcode}} {{item.prefecture}}{{item.address|truncatechars:20}}</td>
							<td>4</td>
							<td>6</td>
							<td class="text-nowrap"><button class="btn btn-light" onclick="location.href='/client/detail#{{item.id}}'">詳細</button> <button class="btn btn-light" onclick="location.href='/client/edit#{{item.id}}'">編集</button> <button class="btn btn-light" onclick="location.href='#modal'" name="target" value="{{item.id}}">削除</button></td>
						</tr>
						{% endfor %}

remodal & javascript

<div class="remodal" data-remodal-id="modal">
		<form method="post" action="/client/delete" id="form_id">
			{% csrf_token %}
			<button data-remodal-action="close" class="remodal-close"></button>
				<input type="hidden" id="client_id" name="client_id" value="00">
			    <h1>得意先削除</h1>
			    <p>
			    東京商事株式会社を削除して宜しいでしょうか?
			    </p>
			    <br>
			<button data-remodal-action="cancel" class="remodal-cancel">Cancel</button>
			<button data-remodal-action="confirm" class="remodal-confirm">OK</button>
		</form>
	</div>
	<script src="{% static 'sales/js/remodal.min.js' %}"></script>
	<script>
		var remodal = $('[data-remodal-id=modal]').remodal();

		$(document).on('opened', remodal, function () {
		     var target = document.getElementsByName('target').value;
		     console.log(target);
		});

		$(document).on('confirmation', remodal, function(){
			$('#form_id').submit();
		});
	</script>

### buttonをaタグで囲って、idを渡す
*.html

<a href="#modal"><button class="btn btn-light del" id="{{item.id}}">削除</button></a>

remodal & javascript

// remodal
<div class="remodal" data-remodal-id="modal">
		<form method="post" action="/client/delete" id="form_id">
			{% csrf_token %}
			<button data-remodal-action="close" class="remodal-close"></button>
				<input type="hidden" id="client_id">
			    <h1>得意先削除</h1>
			    <p>
			    東京商事株式会社を削除して宜しいでしょうか?
			    </p>
			    <br>
			<button data-remodal-action="cancel" class="remodal-cancel">Cancel</button>
			<button data-remodal-action="confirm" class="remodal-confirm">OK</button>
		</form>
	</div>

// javascript
$('.del').on('click', function(){
			var id = $(this).attr("id");
			document.getElementById("client_id").setAttribute("value", id);
		})

js側では、on clickでidの値を取得して、getElementById(“client_id”).setAttribute(“value”, id);でformのhiddenのinputにセットすると上手くいきます。idをセットする場所をinputではなくactionのリンク先につけてgetでidを取得しても良いでしょう。

laravelで同じような仕組みを作っていたので、githubでソースコードを確認して実装しました。ここはDjangoってよりもループ処理の時のremodalとJavaScriptの実装の仕方ですね。

[Django3.0]DBのリストをviewに表示

sales_clientsテーブルのレコードを得意先一覧ページで表示させたい。
レコード全てを取得する際には、views.pyで${modelName}.objects.all()として取得する。

mysql> select * from sales_clients;
+—-+——————————————–+———————————–+——–+————+—————–+————–+————————–+———-+————+———————————————————————–+————–+————–+————–+—————–+——–+—————————-+—————————-+
| id | name | name_kana | office | department | position | charge | charge_mail | zipcode | prefecture | address | tel | fax | name_top | position_top | remark | created_at | updated_at |
+—-+——————————————–+———————————–+——–+————+—————–+————–+————————–+———-+————+———————————————————————–+————–+————–+————–+—————–+——–+—————————-+—————————-+
| 1 | ジャパンソフトウェア株式会社 | ジャパンソフトウェア | 本社 | 営業部 | 代表取締役 | 佐藤太郎 | staro@japansoftware.com | 100-0002 | 東京都 | 千代田区皇居外苑1-2-3 | 03-1234-5678 | 03-1234-5679 | 山本五郎 | 代表取締役 | | 2020-08-30 02:09:35.555187 | 2020-08-30 02:09:35.555259 |
| 16 | 六本木ソフトウェア株式会社 | ロッポンギソフトウェア | 本社 | 営業部 | 課長 | 田中太郎 | ttanaka@roppongisoft.com | 106-6240 | 東京都 | 港区六本木住友不動産六本木グランドタワー40階 | 03-1234-5678 | 03-1234-5679 | 山田一郎 | 代表取締役 | | 2020-09-05 03:18:49.981333 | 2020-09-05 03:18:49.981377 |
+—-+——————————————–+———————————–+——–+————+—————–+————–+————————–+———-+————+———————————————————————–+————–+————–+————–+—————–+——–+—————————-+—————————-+
2 rows in set (0.00 sec)

sales/views.py

def client(request):
	data = Clients.objects.all()
	params = {
		'data' : data
	}
	return render(request, 'sales/client.html', params)

/templates/sales/client.html

<table class="table table-striped">
					<thead >
						<tr>
							<th scope="col" class="font-weight-normal">ID</th>
							<th scope="col" class="font-weight-normal">会社名</th>
							<th scope="col" class="font-weight-normal">住所</th>
							<th scope="col" class="font-weight-normal">見積</th>
							<th scope="col" class="font-weight-normal">受注</th>
							<th scope="col" class="font-weight-normal">アクション</th>
						</tr>
					</thead>
					<tbody>
						{% for item in data %}
						<tr>
							<td>{{item.id}}</td>
							<td class="text-nowrap">{{item.name}}</td>
							<td class="text-nowrap">〒{{item.zipcode}} {{item.prefecture}}{{item.address|truncatechars:20}}</td>
							<td>4</td>
							<td>6</td>
							<td class="text-nowrap"><button class="btn btn-light">詳細</button> <button class="btn btn-light">編集</button> <button class="btn btn-light" onclick="location.href='#modal'">削除</button></td>
						</tr>
						{% endfor %}
					</tbody>	
				</table>

住所の文字数を制限するため、item.address|truncatechars:20とすると、20文字以上は自動的に三点リーダで表示されます。

続いて、詳細、編集、削除ボタンのリンクを作成していきます。

[Django3.0]エラーメッセージで辞書型のvalueを表示する書き方

forms.pyで、全角カナ以外の入力があった場合にname_kanaにエラーメッセージを割り当てています。

forms.py

	def clean_name_kana(self):
		name_kana = self.cleaned_data['name_kana']
		p = re.compile('[\u30A1-\u30F4]+')
		if not(p.fullmatch(name_kana)):
			raise forms.ValidationError("全角カナで入力してください。")

### keyが表示される駄目な例
view側で、form.errorsは辞書型のデータを取得するので、form.name_kana.errorsとすれば辞書型のvalueが表示されますが、errorだけだと、辞書型のkeyを表示します。
以下のように書くとエラーメッセージはname_kana となります。

client_input.html

{% for error in form.errors %}
{{ error }}
{% endfor %}

### 辞書型のvalueが表示される例
このように書くと、辞書型のkeyとvalueを取得できるので、指定したバリデーションメッセージを表示させる事ができます。

client_input.html

{% for key, value in form.errors.items %}
{{ value }}
{% endfor %}

これ修正するのに凄い時間かかった。もー

[Django3.0]Viewでのエラーメッセージの書き方

エラーメッセージがあった場合にはforループで回すのが一般的?

モデルで正規表現でカタカナのみ入力可としてる所で、漢字で入力してエラーメッセージを表示させる。

/sales/models.py


class Clients(models.Model):
	name = models.CharField(max_length=255)
	name_kana = models.CharField(max_length=255, null=True, blank=True, validators=[RegexValidator(r"\u30A1-\u30F4")])
	office = models.CharField(max_length=255, null=True, blank=True)
	department = models.CharField(max_length=255, null=True, blank=True)
	position = models.CharField(max_length=255, null=True, blank=True)
	charge = models.CharField(max_length=255)
	charge_mail = models.EmailField(max_length=255)
	zipcode = models.CharField(max_length=8, validators=[RegexValidator(r"\d{3}-\d{4}")])
	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, blank=True)
	name_top = models.CharField(max_length=255)
	position_top = models.CharField(max_length=100, null=True, blank=True)
	remark = models.TextField(max_length=300, null=True, blank=True)
	created_at = models.DateTimeField(auto_now_add=True)
	updated_at = models.DateTimeField(auto_now=True)

/templates/sales/client_input.html

{% for error in form.errors %}
<div class="text-danger">
    {{ error }}
</div>
{% endfor %}

エラーメッセージを定義していないから、kana_nameだけ表示される。

class ClientsForm(forms.ModelForm):
	class Meta:
		model = Clients
		fields = ['name', 'name_kana', 'office', 'department', 'position', 'charge', 'charge_mail', 'zipcode', 'prefecture', 'address', 'tel', 'fax', 'name_top', 'position_top', 'remark']

	def clean_name_kana(self);
		name_kana = self.cleaned_data['name_kana']
		p = u'^[\u30A1-\u30F4]+$'
		if(re.match(p, name_kana))
			raise forms.ValidationError("全角カナで入力してください")
		return name_kana

上手くいかない。正規表現を変更する。

	def clean_name_kana(self):
		name_kana = self.cleaned_data['name_kana']
		p = re.compile('[\u30A1-\u30F4]+')
		if not(p.fullmatch(name_kana)):
			raise forms.ValidationError("全角カナで入力してください")
{% for error in form.errors %}
				<div class="text-danger">
				{{ form.name_kana.errors }}
			   </div>
				{% endfor %}

上手く行ったが、なんかモヤモヤするな。

[Django3.0]カタカナのバリデーション

まずER図とデータ型を編集しながらmodels.pyを作成します。

/sales/models.py

class Clients(models.Model):
	name = models.CharField(max_length=255)
	name_kana = models.CharField(max_length=255, null=True)
	office = models.CharField(max_length=255, null=True)
	department = models.CharField(max_length=255, null=True)
	position = models.CharField(max_length=255, null=True)
	charge = models.CharField(max_length=255)
	charge_mail = models.EmailField(max_length=255)
	zipcode = models.CharField(max_length=8, validators=[RegexValidator(r"\d{3}-\d{4}")])
	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)
	name_top = models.CharField(max_length=255)
	position_top = models.CharField(max_length=100, null=True)
	remark = models.TextField(max_length=300, null=True)
	created_at = models.DateTimeField(auto_now_add=True)
	updated_at = models.DateTimeField(auto_now=True)

$ python manage.py makemigrations sales
$ python manage.py migrate
mysql> show tables;
mysql> describe sales_clients;
+————–+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————–+————–+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| name_kana | varchar(255) | YES | | NULL | |
| office | varchar(255) | YES | | NULL | |
| department | varchar(255) | YES | | NULL | |
| position | varchar(255) | YES | | NULL | |
| charge | varchar(255) | NO | | NULL | |
| charge_mail | varchar(255) | NO | | 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 | |
| name_top | varchar(255) | NO | | NULL | |
| position_top | varchar(100) | YES | | NULL | |
| remark | longtext | YES | | NULL | |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
+————–+————–+——+—–+———+—————-+
18 rows in set (0.00 sec)

/sales/forms.py

class ClientsForm(forms.ModelForm):
	class Meta:
		model = Clients
		fields = ['name', 'name_kana', 'office', 'department', 'position', 'charge', 'charge_mail', 'zipcode', 'prefecture', 'address', 'tel', 'fax', 'name_top', 'position_top', 'remark']

/sales/views.py

from .models import Clients
form .forms import ClientsForms

def client_complete(request):
	if(request.method == 'POST'):
		name = request.POST['name']
		name_kana = request.POST['name_kana']
		office = request.POST['office']
		department = request.POST['department']
		position = request.POST['position']
		charge = request.POST['charge']
		charge_mail = request.POST['charge_mail']
		zipcode = request.POST['zipcode']
		prefecture = request.POST['prefecture']
		address = request.POST['address']
		tel = request.POST['tel']
		fax = request.POST['fax']
		name_top = request.POST['name_top']
		position_top = request.POST['position_top']
		remark = request.POST['remark']
		clients = Clients(name=name, name_kana=name_kana, office=office, department=department, position=position, charge=charge, charge_mail=charge_mail, zipcode=zipcode, prefecture=prefecture, address=address, tel=tel,fax=fax, name_top=name_top, position_top=position_top, remark=remark)
		clients.save()        
	return render(request, 'sales/client_complete.html')

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

/templates/sales/client_input.html
// 省略
-> django-widdget-tweaksではTextFieldは自動的にtextareaになるが、rowsを指定してあげる

{% render_field form.remark class="form-control" rows="2" placeholder="" %}

mysql> select * from sales_clients;
+—-+——————————————–+——————————–+——–+————+—————–+————–+————————-+———-+————+——————————-+————–+————–+————–+—————–+——————–+—————————-+—————————-+
| id | name | name_kana | office | department | position | charge | charge_mail | zipcode | prefecture | address | tel | fax | name_top | position_top | remark | created_at | updated_at |
+—-+——————————————–+——————————–+——–+————+—————–+————–+————————-+———-+————+——————————-+————–+————–+————–+—————–+——————–+—————————-+—————————-+
| 1 | ジャパンソフトウェア株式会社 | ジャパンソフトウェア | 本社 | 営業部 | 代表取締役 | 佐藤太郎 | staro@japansoftware.com | 100-0002 | 東京都 | 千代田区皇居外苑1-2-3 | 03-1234-5678 | 03-1234-5679 | 山本五郎 | 代表取締役 | | 2020-08-30 02:09:35.555187 | 2020-08-30 02:09:35.555259 |
| 2 | アジアテック株式会社 | アジアテック | 本社 | 営業部 | 課長 | 山本太郎 | yamamoto@asiatech.com | 100-0002 | 東京都 | 千代田区皇居外苑1-2-3 | 03-1234-5678 | 03-1234-5679 | 山田一郎 | 代表取締役 | 佐藤氏の紹介 | 2020-08-30 02:54:20.407693 | 2020-08-30 02:54:20.407756 |
+—-+——————————————–+——————————–+——–+————+—————–+————–+————————-+———-+————+——————————-+————–+————–+————–+—————–+——————–+—————————-+—————————-+
2 rows in set (0.00 sec)

zipcodeのバリデーションを\d{3}-\d{4}として、会社名カナのバリデーションを\u30A1-\u30F4とした場合に、form.is_valid():として複数のエラーメッセージを出し分ける方法がわからんな。

[Django3.0] ModelFormのバリデーション

Djangoでは、Forms.FormのバリデーションとModelFormのバリデーション2種類がある
ModelFormでのバリデーションについて考える。

文字数とnull, Emailは既にモデルに書かれているので、郵便番号を英数字とハイフンだけにする
正規表現で、\d{3}-\d{4}とする

/sales/models.py

from django.db import models
from django.core.validators import RegexValidator

class Master(models.Model):
	name = models.CharField(max_length=255)
	office = models.CharField(max_length=255, null=True)
	zipcode = models.CharField(max_length=8, validators=[RegexValidator(r"\d{3}-\d{4}")])
	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)

/sales/views.py

def master_complete(request):
	data = Master.objects.get(id=1)
	if(request.method == 'POST'):
		master = MasterForm(request.POST, instance=data)
		if(master.is_valid()):
			master.save()
			return render(request, 'sales/master_complete.html')
		else:
			params = {
				'form': MasterForm(instance=data),
				'message': "郵便番号は数字7桁とハイフンで入力してください"
			}
			return render(request, 'sales/master.html', params)
	return render(request, 'sales/master_complete.html')

/sales/templates/sales/master.html

<div class="text-danger">{{ message}}</div>

OK
自社基本情報の更新までできました。
続いて得意先の登録に行きます。

[Django3.0] ModelFormによるデータ更新の書き方2

views.pyでは、*.objects.get(id=*)としてレコードを取り出し、save()で更新する。

/sales/views.py

def master_complete(request):
	data = Master.objects.get(id=1)
	if(request.method == 'POST'):
		master = MasterForm(request.POST, instance=data)
		master.save()
	return render(request, 'sales/master_complete.html')

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-2 | 03-1234-5678 | 03-1234-5679 | info@tokyotech.com | 山田太郎 | 代表取締役 | 2020-08-22 12:30:30.000000 | 2020-08-27 11:50:16.915337 |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
1 row in set (0.00 sec)

get, create, updateはマスターしました。
次はバリデーションでしょうか。

[Django3.0] ModelFormによるupdateの書き方

sales_masterテーブルのid=1のレコードをformに表示させたい
forms.pyでModelFormを使用する
view側ではdjango-widdget-tweaksを引き続き使用

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 12:30:30.000000 | 2020-08-22 12:30:30.000000 |
+—-+————————————–+——–+———-+————+—————————-+————–+————–+——————–+————–+—————–+—————————-+—————————-+
1 row in set (0.00 sec)

/sales/forms.py

from django import forms
from.models import Master

class MasterForm(forms.ModelForm):
	class Meta:
		model = Master
		fields = ['name', 'office', 'zipcode', 'prefecture', 'address', 'tel', 'fax', 'mail', 'name_top', 'position_top']

/sales/views.py

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

/sales/templates/sales/master.html
-> 変更なし

上手く引っ張ってこれました。

[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-*の調整ができないないので、方法を考える必要がある。