最終投稿日:2022年6月18日
Django(プロフィールフォーム)
設定関連
※ DBは、PostgreSQL を使用する
※ prof アプリを想定
※ prof アプリを想定
● settings.py
INSTALLED_APPS に prof アプリの登録
抜粋)
INSTALLED_APPS = [
~ 省略 ~
'prof.apps.ProfConfig',
]
抜粋)
INSTALLED_APPS = [
~ 省略 ~
'prof.apps.ProfConfig',
]
● urls.py( プロジェクト側 )
from django.contrib import admin
from django.conf.urls import include, url
from django.views.generic import RedirectView
urlpatterns = [
url(r'^$', RedirectView.as_view(url='prof/')),
url(r'^prof/', include('prof.urls', namespace='prof')),
url('admin/' , admin.site.urls),
]
from django.conf.urls import include, url
from django.views.generic import RedirectView
urlpatterns = [
url(r'^$', RedirectView.as_view(url='prof/')),
url(r'^prof/', include('prof.urls', namespace='prof')),
url('admin/' , admin.site.urls),
]
● urls.py( アプリ側 )
from django.conf.urls import url
from django.views.generic import RedirectView
from .views import IndexView, DataSaveView
app_name = 'prof'
urlpatterns = [
url(r'^$', RedirectView.as_view(url='index/')),
url(r'^index/$', IndexView.as_view(), name='index'),
url(r'^data_save/$', DataSaveView.as_view(), name='data_save'),
]
from django.views.generic import RedirectView
from .views import IndexView, DataSaveView
app_name = 'prof'
urlpatterns = [
url(r'^$', RedirectView.as_view(url='index/')),
url(r'^index/$', IndexView.as_view(), name='index'),
url(r'^data_save/$', DataSaveView.as_view(), name='data_save'),
]
モデル関連
● models.py
from django.db import models
class MPref(models.Model):
class Meta:
db_table = 'm_pref'
tdk = models.CharField(max_length = 20)
tdk_k = models.CharField(max_length = 20)
tks = models.CharField(max_length = 1, default =' ') class MSyumi(models.Model):
class Meta:
db_table = 'm_syumi'
sname = models.CharField(max_length = 50)
sname_k = models.CharField(max_length = 50)
tks = models.CharField(max_length = 1, default =' ')
class Profile(models.Model):
class Meta:
db_table = 'profile'
mail = models.CharField(primary_key = True, max_length = 50)
fname = models.CharField(max_length = 10)
lname = models.CharField(max_length = 10)
fname_k = models.CharField(max_length = 10)
lname_k = models.CharField(max_length = 10)
sex = models.CharField(max_length = 1)
birth = models.CharField(max_length = 8)
zipn = models.CharField(max_length = 8)
m_pref = models.ForeignKey(MPref, to_field = 'id', on_delete=models.PROTECT)
pref1 = models.CharField(max_length = 100)
pref2 = models.CharField(max_length = 100, null = True, default = '')
tel = models.CharField(max_length = 13)
syumi = models.TextField()
bikou = models.TextField(null = True, default = '')
insert_date = models.DateTimeField(null = True)
update_date = models.DateTimeField(null = True)
tks = models.CharField(max_length = 1, default =' ')
class Meta:
db_table = 'm_pref'
tdk = models.CharField(max_length = 20)
tdk_k = models.CharField(max_length = 20)
tks = models.CharField(max_length = 1, default =' ') class MSyumi(models.Model):
class Meta:
db_table = 'm_syumi'
sname = models.CharField(max_length = 50)
sname_k = models.CharField(max_length = 50)
tks = models.CharField(max_length = 1, default =' ')
class Profile(models.Model):
class Meta:
db_table = 'profile'
mail = models.CharField(primary_key = True, max_length = 50)
fname = models.CharField(max_length = 10)
lname = models.CharField(max_length = 10)
fname_k = models.CharField(max_length = 10)
lname_k = models.CharField(max_length = 10)
sex = models.CharField(max_length = 1)
birth = models.CharField(max_length = 8)
zipn = models.CharField(max_length = 8)
m_pref = models.ForeignKey(MPref, to_field = 'id', on_delete=models.PROTECT)
pref1 = models.CharField(max_length = 100)
pref2 = models.CharField(max_length = 100, null = True, default = '')
tel = models.CharField(max_length = 13)
syumi = models.TextField()
bikou = models.TextField(null = True, default = '')
insert_date = models.DateTimeField(null = True)
update_date = models.DateTimeField(null = True)
tks = models.CharField(max_length = 1, default =' ')
● サンプルテーブルのSQLy
[都道府県TBL]
create table M_pref(
-- id
id serial PRIMARY KEY NOT NULL
-- 都道府県名
,tdk VARCHAR(20) NOT NULL
-- 都道府県名カナ
,tdk_k VARCHAR(20) NOT NULL
-- 取り消しフラグ
,tks char(1) default ' '
);
insert into M_pref (tdk, tdk_k) values('東京都', 'トウキョウト');
insert into M_pref (tdk, tdk_k) values('埼玉県', 'サイタマケン');
insert into M_pref (tdk, tdk_k) values('千葉県', 'チバケン'); [趣味TBL]
create table M_syumi(
-- id
id serial PRIMARY KEY NOT NULL
-- 趣味名
,sname VARCHAR(50) NOT NULL
-- 趣味名カナ
,sname_k VARCHAR(50) NOT NULL
-- 取り消しフラグ
,tks char(1) default ' '
);
insert into M_syumi (sname, sname_k) values('釣り', 'ツリ');
insert into M_syumi (sname, sname_k) values('ドライブ', 'ドライブ');
insert into M_syumi (sname, sname_k) values('ギャンブル', 'ギャンブル');
insert into M_syumi (sname, sname_k) values('貯金', 'チョキン');
insert into M_syumi (sname, sname_k) values('旅行', 'リョコウ');
insert into M_syumi (sname, sname_k) values('お酒', 'オサケ'); [プロフィールTBL]
create table profile(
-- メールアドレス
mail VARCHAR(50) PRIMARY KEY NOT NULL
-- 名
,fname VARCHAR(10) NOT NULL
-- 姓
,lname VARCHAR(10) NOT NULL
-- 名カナ
,fname_k VARCHAR(10) NOT NULL
-- 姓カナ
,lname_k VARCHAR(10) NOT NULL
-- 性別
,sex char(1) NOT NULL
-- 誕生日
,birth VARCHAR(8) NOT NULL
-- 郵便番号
,zipn VARCHAR(8) NOT NULL
-- 都道府県
,m_pref_id integer NOT NULL
references M_pref(id)
-- 住所1
,pref1 VARCHAR(100) NOT NULL
-- マンション名等
,pref2 VARCHAR(100)
-- 電話番号
,tel VARCHAR(13)
-- 趣味
,syumi text NOT NULL
-- 備考
,bikou text
-- 登録日時
,insert_date timestamp
-- 更新日時
,update_date timestamp
-- 取り消しフラグ
,tks char(1) default ' '
);
create table M_pref(
-- id
id serial PRIMARY KEY NOT NULL
-- 都道府県名
,tdk VARCHAR(20) NOT NULL
-- 都道府県名カナ
,tdk_k VARCHAR(20) NOT NULL
-- 取り消しフラグ
,tks char(1) default ' '
);
insert into M_pref (tdk, tdk_k) values('東京都', 'トウキョウト');
insert into M_pref (tdk, tdk_k) values('埼玉県', 'サイタマケン');
insert into M_pref (tdk, tdk_k) values('千葉県', 'チバケン'); [趣味TBL]
create table M_syumi(
-- id
id serial PRIMARY KEY NOT NULL
-- 趣味名
,sname VARCHAR(50) NOT NULL
-- 趣味名カナ
,sname_k VARCHAR(50) NOT NULL
-- 取り消しフラグ
,tks char(1) default ' '
);
insert into M_syumi (sname, sname_k) values('釣り', 'ツリ');
insert into M_syumi (sname, sname_k) values('ドライブ', 'ドライブ');
insert into M_syumi (sname, sname_k) values('ギャンブル', 'ギャンブル');
insert into M_syumi (sname, sname_k) values('貯金', 'チョキン');
insert into M_syumi (sname, sname_k) values('旅行', 'リョコウ');
insert into M_syumi (sname, sname_k) values('お酒', 'オサケ'); [プロフィールTBL]
create table profile(
-- メールアドレス
mail VARCHAR(50) PRIMARY KEY NOT NULL
-- 名
,fname VARCHAR(10) NOT NULL
-- 姓
,lname VARCHAR(10) NOT NULL
-- 名カナ
,fname_k VARCHAR(10) NOT NULL
-- 姓カナ
,lname_k VARCHAR(10) NOT NULL
-- 性別
,sex char(1) NOT NULL
-- 誕生日
,birth VARCHAR(8) NOT NULL
-- 郵便番号
,zipn VARCHAR(8) NOT NULL
-- 都道府県
,m_pref_id integer NOT NULL
references M_pref(id)
-- 住所1
,pref1 VARCHAR(100) NOT NULL
-- マンション名等
,pref2 VARCHAR(100)
-- 電話番号
,tel VARCHAR(13)
-- 趣味
,syumi text NOT NULL
-- 備考
,bikou text
-- 登録日時
,insert_date timestamp
-- 更新日時
,update_date timestamp
-- 取り消しフラグ
,tks char(1) default ' '
);
フォーム関連
● forms.py
from django import forms
from .models import Profile, MPref, MSyumi
from mycommon import *
import re
from datetime import date, time, datetime class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
exclude = ('tks', 'insert_date', 'update_date', 'm_pref')
#初期設定(全てのカラムに適用する)
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
for field in self.fields.values():
#html5の必須を解除
field.required = False
#都道府県取得
__PREF_option = [(s.id,s.tdk) for s in MPref.objects.all().exclude(tks='1').order_by('tdk_k')]
__PREF_option.insert(0,(0,'--'))
#趣味取得
__SYUMI_option = [(s.id,s.sname) for s in MSyumi.objects.all().exclude(tks='1').order_by('sname_k')]
mail = forms.CharField(
label = 'E-Mail',
max_length = 50,
widget = forms.TextInput(
attrs = {'size':'30'}
),
)
fname = forms.CharField(
label ='名',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
lname = forms.CharField(
label = '姓',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
fname_k = forms.CharField(
label = 'メイ',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
lname_k = forms.CharField(
label = 'セイ',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
sex = forms.ChoiceField(
label = '性別',
widget = forms.RadioSelect(),
choices=(('1','男'),('2','女')),
)
#モデルにはない項目(年月日を3つのプルダウンにわける)
birth_y = forms.ChoiceField(
label = '生年月日',
widget = forms.Select(),
choices = yearNowToXXX(100,'---'),
)
birth_m = forms.ChoiceField(
widget = forms.Select(),
choices = intToXX(1, 12, '--')
)
birth_d = forms.ChoiceField(
widget = forms.Select(),
choices = intToXX(1, 31, '--')
)
zipn = forms.CharField(
label = '郵便番号',
max_length = 8,
widget = forms.TextInput(
attrs = {'size':'10'}
),
)
m_pref_id = forms.ChoiceField(
label = '都道府県',
widget = forms.Select(),
choices = __PREF_option,
)
pref1 = forms.CharField(
label = '住所1',
max_length = 100,
widget = forms.TextInput(
attrs = {'size':'40'}
),
)
pref2 = forms.CharField(
label = '住所2',
max_length = 100,
widget = forms.TextInput(
attrs = {'size':'40'}
),
)
tel = forms.CharField(
label = '電話番号',
max_length = 13,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
syumi = forms.MultipleChoiceField(
label = '趣味',
widget = forms.CheckboxSelectMultiple(),
choices = __SYUMI_option,
)
bikou = forms.CharField(
label = '備考',
widget = forms.Textarea(attrs={'cols': 50, 'rows': 4}),
required = False,
)
"""
------------ ここからバリデーション ------------
"""
def clean(self):
""" メールチェック """
s = self.cleaned_data['mail']
if s == '':
self.add_error('mail', 'メールアドレスは必須項目です')
else:
m = re.search(r'^[^0-9][a-zA-Z0-9_-]+([.][a-zA-Z0-9_-]+)*[@][a-zA-Z0-9_-]+([.][a-zA-Z0-9_-]+)*[.][a-zA-Z]{2,4}$', s)
if m == None:
self.add_error('mail', 'メールアドレスの型式ではありません!')
""" 名前 """
name1 = self.cleaned_data['fname']
name2 = self.cleaned_data['lname']
if name1 =='' or name2 == '':
self.add_error('lname', '名前は必須項目です')
""" 名前カナ """
name1 = self.cleaned_data['fname_k']
name2 = self.cleaned_data['lname_k']
if name1 =='' or name2 == '':
self.add_error('lname_k', '名前(カナ)は必須項目です')
else:
m1 = re.search(r'^[ァ-ヶー]+$', name1)
m2 = re.search(r'^[ァ-ヶー]+$', name2)
if m1 == None or m2 == None:
self.add_error('lname_k', '名前(カナ)は全角カタカナで入力してください')
""" 性別 """
s = self.cleaned_data['sex']
if s == '':
self.add_error('sex', '性別を選択してください')
""" 生年月日 """
y = self.cleaned_data['birth_y']
m = self.cleaned_data['birth_m']
d = self.cleaned_data['birth_d']
if y == '0' or m == '0' or d == '0':
self.add_error('birth_y', '生年月日を選択してください')
else:
try:
datetime(int(y), int(m), int(d))
except:
self.add_error('birth_y', '選択された生年月日は存在しません')
""" 郵便番号 """
s = self.cleaned_data['zipn']
if s == '':
self.add_error('zipn', '郵便番号を記入してください')
else:
m = re.search(r'^\d{3}[-]\d{4}$', s)
if m == None:
self.add_error('zipn', '郵便番号の形式ではありません')
""" 住所 """
v1 = self.cleaned_data['m_pref_id']
v2 = self.cleaned_data['pref1']
if v1 == '0' or v2 == '':
self.add_error('pref1', '住所を選択、記入してください')
""" 電話 """
s = self.cleaned_data['tel']
if s == '':
self.add_error('tel', '電話番号は必須です')
else:
m = re.search(r'^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$', s)
if m == None:
self.add_error('tel', '電話番号の形式ではありません')
""" 趣味 """
s = self.cleaned_data['syumi']
c = len(s)
if c < 2:
self.add_error('syumi', '趣味は最低2つ以上選択してください')
""" 備考 """
s = self.cleaned_data['bikou']
i = len(s) - (s.count('\n') * 2)
if i > 50:
self.add_error('bikou', '備考は50文字以内で記入してください') return self.cleaned_data
from .models import Profile, MPref, MSyumi
from mycommon import *
import re
from datetime import date, time, datetime class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
exclude = ('tks', 'insert_date', 'update_date', 'm_pref')
#初期設定(全てのカラムに適用する)
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
for field in self.fields.values():
#html5の必須を解除
field.required = False
#都道府県取得
__PREF_option = [(s.id,s.tdk) for s in MPref.objects.all().exclude(tks='1').order_by('tdk_k')]
__PREF_option.insert(0,(0,'--'))
#趣味取得
__SYUMI_option = [(s.id,s.sname) for s in MSyumi.objects.all().exclude(tks='1').order_by('sname_k')]
mail = forms.CharField(
label = 'E-Mail',
max_length = 50,
widget = forms.TextInput(
attrs = {'size':'30'}
),
)
fname = forms.CharField(
label ='名',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
lname = forms.CharField(
label = '姓',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
fname_k = forms.CharField(
label = 'メイ',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
lname_k = forms.CharField(
label = 'セイ',
max_length = 10,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
sex = forms.ChoiceField(
label = '性別',
widget = forms.RadioSelect(),
choices=(('1','男'),('2','女')),
)
#モデルにはない項目(年月日を3つのプルダウンにわける)
birth_y = forms.ChoiceField(
label = '生年月日',
widget = forms.Select(),
choices = yearNowToXXX(100,'---'),
)
birth_m = forms.ChoiceField(
widget = forms.Select(),
choices = intToXX(1, 12, '--')
)
birth_d = forms.ChoiceField(
widget = forms.Select(),
choices = intToXX(1, 31, '--')
)
zipn = forms.CharField(
label = '郵便番号',
max_length = 8,
widget = forms.TextInput(
attrs = {'size':'10'}
),
)
m_pref_id = forms.ChoiceField(
label = '都道府県',
widget = forms.Select(),
choices = __PREF_option,
)
pref1 = forms.CharField(
label = '住所1',
max_length = 100,
widget = forms.TextInput(
attrs = {'size':'40'}
),
)
pref2 = forms.CharField(
label = '住所2',
max_length = 100,
widget = forms.TextInput(
attrs = {'size':'40'}
),
)
tel = forms.CharField(
label = '電話番号',
max_length = 13,
widget = forms.TextInput(
attrs = {'size':'15'}
),
)
syumi = forms.MultipleChoiceField(
label = '趣味',
widget = forms.CheckboxSelectMultiple(),
choices = __SYUMI_option,
)
bikou = forms.CharField(
label = '備考',
widget = forms.Textarea(attrs={'cols': 50, 'rows': 4}),
required = False,
)
"""
------------ ここからバリデーション ------------
"""
def clean(self):
""" メールチェック """
s = self.cleaned_data['mail']
if s == '':
self.add_error('mail', 'メールアドレスは必須項目です')
else:
m = re.search(r'^[^0-9][a-zA-Z0-9_-]+([.][a-zA-Z0-9_-]+)*[@][a-zA-Z0-9_-]+([.][a-zA-Z0-9_-]+)*[.][a-zA-Z]{2,4}$', s)
if m == None:
self.add_error('mail', 'メールアドレスの型式ではありません!')
""" 名前 """
name1 = self.cleaned_data['fname']
name2 = self.cleaned_data['lname']
if name1 =='' or name2 == '':
self.add_error('lname', '名前は必須項目です')
""" 名前カナ """
name1 = self.cleaned_data['fname_k']
name2 = self.cleaned_data['lname_k']
if name1 =='' or name2 == '':
self.add_error('lname_k', '名前(カナ)は必須項目です')
else:
m1 = re.search(r'^[ァ-ヶー]+$', name1)
m2 = re.search(r'^[ァ-ヶー]+$', name2)
if m1 == None or m2 == None:
self.add_error('lname_k', '名前(カナ)は全角カタカナで入力してください')
""" 性別 """
s = self.cleaned_data['sex']
if s == '':
self.add_error('sex', '性別を選択してください')
""" 生年月日 """
y = self.cleaned_data['birth_y']
m = self.cleaned_data['birth_m']
d = self.cleaned_data['birth_d']
if y == '0' or m == '0' or d == '0':
self.add_error('birth_y', '生年月日を選択してください')
else:
try:
datetime(int(y), int(m), int(d))
except:
self.add_error('birth_y', '選択された生年月日は存在しません')
""" 郵便番号 """
s = self.cleaned_data['zipn']
if s == '':
self.add_error('zipn', '郵便番号を記入してください')
else:
m = re.search(r'^\d{3}[-]\d{4}$', s)
if m == None:
self.add_error('zipn', '郵便番号の形式ではありません')
""" 住所 """
v1 = self.cleaned_data['m_pref_id']
v2 = self.cleaned_data['pref1']
if v1 == '0' or v2 == '':
self.add_error('pref1', '住所を選択、記入してください')
""" 電話 """
s = self.cleaned_data['tel']
if s == '':
self.add_error('tel', '電話番号は必須です')
else:
m = re.search(r'^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$', s)
if m == None:
self.add_error('tel', '電話番号の形式ではありません')
""" 趣味 """
s = self.cleaned_data['syumi']
c = len(s)
if c < 2:
self.add_error('syumi', '趣味は最低2つ以上選択してください')
""" 備考 """
s = self.cleaned_data['bikou']
i = len(s) - (s.count('\n') * 2)
if i > 50:
self.add_error('bikou', '備考は50文字以内で記入してください') return self.cleaned_data
コントローラ関連
● views.py
from django.shortcuts import render
from django.http.response import HttpResponse
from django.views.generic import View
from . import forms
from .models import MPref, MSyumi, Profile
from datetime import date, time, datetime, timedelta, timezone
from mycommon import * class IndexView(View):
def get(self,request):
form = forms.ProfileForm()
d = {'form':form}
return render(request, 'prof/index.html', d)
def post(self,request):
form = forms.ProfileForm(request.POST)
if form.is_valid():
#エラーなし
ken = MPref.objects.get(id = request.POST.get(key='m_pref_id'))
res = MSyumi.objects.all().filter(id__in=request.POST.getlist('syumi'))
syumi = ''
for s in res:
syumi += s.sname + ' '
d = {'form':form,'ken':ken.tdk,'syumi':syumi}
return render(request, 'prof/confirm.html', d)
else:
#エラー
d = {'form':form}
return render(request, 'prof/index.html', d)
class DataSaveView(View):
def post(self,request):
form = forms.ProfileForm(request.POST)
#戻る押下の場合
if request.POST.get('form_back'):
d = {'form':form}
return render(request, 'prof/index.html', d)
#保存押下の場合
else:
#一応バリデーションチェックをする
if form.is_valid():
#仮のインスタンス作成
instance = form.save(commit=False)
#生年月日作成
birth = request.POST['birth_y'] + request.POST['birth_m'].zfill(2) + request.POST['birth_d'].zfill(2)
#誕生日カラムに代入
instance.birth = birth
#都道府県カラムに代入
instance.m_pref_id = request.POST['m_pref_id']
#主キーが存在するか検索
pk = Profile.objects.all().filter(mail = instance.mail)
#タイムゾーンの設定(ワーニング回避)
myJST = timezone(timedelta(hours = 9), 'Japan')
if len(pk) > 0:
#主キーで検索して結果が0件以外の場合は更新処理とする
uf = my_exclude_fields(Profile,True, ['insert_date'])
instance.update_date = datetime.now(tz = myJST)
instance.save(update_fields = uf)
else:
instance.insert_date = datetime.now(tz = myJST)
instance.save()
return render(request, 'prof/thanks.html')
else:
#異常系(本来はスローしてエラーにする)
print('異常系エラー')
from django.http.response import HttpResponse
from django.views.generic import View
from . import forms
from .models import MPref, MSyumi, Profile
from datetime import date, time, datetime, timedelta, timezone
from mycommon import * class IndexView(View):
def get(self,request):
form = forms.ProfileForm()
d = {'form':form}
return render(request, 'prof/index.html', d)
def post(self,request):
form = forms.ProfileForm(request.POST)
if form.is_valid():
#エラーなし
ken = MPref.objects.get(id = request.POST.get(key='m_pref_id'))
res = MSyumi.objects.all().filter(id__in=request.POST.getlist('syumi'))
syumi = ''
for s in res:
syumi += s.sname + ' '
d = {'form':form,'ken':ken.tdk,'syumi':syumi}
return render(request, 'prof/confirm.html', d)
else:
#エラー
d = {'form':form}
return render(request, 'prof/index.html', d)
class DataSaveView(View):
def post(self,request):
form = forms.ProfileForm(request.POST)
#戻る押下の場合
if request.POST.get('form_back'):
d = {'form':form}
return render(request, 'prof/index.html', d)
#保存押下の場合
else:
#一応バリデーションチェックをする
if form.is_valid():
#仮のインスタンス作成
instance = form.save(commit=False)
#生年月日作成
birth = request.POST['birth_y'] + request.POST['birth_m'].zfill(2) + request.POST['birth_d'].zfill(2)
#誕生日カラムに代入
instance.birth = birth
#都道府県カラムに代入
instance.m_pref_id = request.POST['m_pref_id']
#主キーが存在するか検索
pk = Profile.objects.all().filter(mail = instance.mail)
#タイムゾーンの設定(ワーニング回避)
myJST = timezone(timedelta(hours = 9), 'Japan')
if len(pk) > 0:
#主キーで検索して結果が0件以外の場合は更新処理とする
uf = my_exclude_fields(Profile,True, ['insert_date'])
instance.update_date = datetime.now(tz = myJST)
instance.save(update_fields = uf)
else:
instance.insert_date = datetime.now(tz = myJST)
instance.save()
return render(request, 'prof/thanks.html')
else:
#異常系(本来はスローしてエラーにする)
print('異常系エラー')
独自ライブラリ関連
● my_lib/mycommon.py (共通処理ファイル)
from datetime import date, time, datetime
"""
現在年からマイナス第1引数分の年を以下の型式で返却する
[(2018,2018),(2017,2017)...]
また、第2引数に文字列があれば初期値のタプルを先頭に追加する
※年のプルダウン用として使用する
"""
def yearNowToXXX(i = 0, s = ''):
nen = int(datetime.now().strftime('%Y'))
l = [(y,y) for y in range(nen, nen - i, -1)]
if s != '':
l.insert(0, (0, s))
return l
"""
メソッドyearNowToXXXの数字バージョン
"""
def intToXX(st=0, ed=0, s=''):
l = [(i,i) for i in range(st, ed + 1)]
if s != '':
l.insert(0, (0, s))
return l
"""
任意のモデルインスタンスを受け取り、除外カラム名を除いたカラム名の配列を返却する
引数1:モデルインスタンス
引数2:主キーを除外の対象とするか(True:する)
引数3:除外カラム名リスト
"""
def my_exclude_fields(MyModel,pkey, l):
res = []
for f in MyModel._meta.get_fields():
if pkey == True:
#主キーも除隊対象とする
if f.primary_key != True and f.name not in l:
res.append(f.name)
else:
#主キーは除外対象としない
if f.name not in l:
res.append(f.name)
return res
"""
現在年からマイナス第1引数分の年を以下の型式で返却する
[(2018,2018),(2017,2017)...]
また、第2引数に文字列があれば初期値のタプルを先頭に追加する
※年のプルダウン用として使用する
"""
def yearNowToXXX(i = 0, s = ''):
nen = int(datetime.now().strftime('%Y'))
l = [(y,y) for y in range(nen, nen - i, -1)]
if s != '':
l.insert(0, (0, s))
return l
"""
メソッドyearNowToXXXの数字バージョン
"""
def intToXX(st=0, ed=0, s=''):
l = [(i,i) for i in range(st, ed + 1)]
if s != '':
l.insert(0, (0, s))
return l
"""
任意のモデルインスタンスを受け取り、除外カラム名を除いたカラム名の配列を返却する
引数1:モデルインスタンス
引数2:主キーを除外の対象とするか(True:する)
引数3:除外カラム名リスト
"""
def my_exclude_fields(MyModel,pkey, l):
res = []
for f in MyModel._meta.get_fields():
if pkey == True:
#主キーも除隊対象とする
if f.primary_key != True and f.name not in l:
res.append(f.name)
else:
#主キーは除外対象としない
if f.name not in l:
res.append(f.name)
return res
HTML関連
● layout/base.html
<html>
<head>
<title>{{my_title}}</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
{% block my_body %}{% endblock %}
</body>
</html>
<head>
<title>{{my_title}}</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
{% block my_body %}{% endblock %}
</body>
</html>
● prof/index.html
{% extends 'layout/base.html' %}
{% block my_body %}
いんでっくす<br>
<form method='POST' action="{% url 'prof:index' %}">
<table border='0' width='600'>
<tr>
<th width='200' style='vertical-align:bottom;'>{{form.mail.label}}</th>
<td width='400'>
<div style='color:red;'> {% if form.mail.errors.as_text != '' %}
{{form.mail.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.mail}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>お名前</th>
<td>
<div style='color:red;'> {% if form.lname.errors.as_text != '' %}
{{form.lname.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.lname.label}} {{form.lname}} {{form.fname.label}} {{form.fname}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>オナマエ</th>
<td>
<div style='color:red;'> {% if form.lname_k.errors.as_text != '' %}
{{form.lname_k.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.lname_k.label}} {{form.lname_k}} {{form.fname_k.label}} {{form.fname_k}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>{{form.sex.label}}</th>
<td>
<div style='color:red;'> {% if form.sex.errors.as_text != '' %}
{{form.sex.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.sex.0}} {{form.sex.1}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>{{form.birth_y.label}}</th>
<td>
<div style='color:red;'> {% if form.birth_y.errors.as_text != '' %}
{{form.birth_y.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.birth_y}}年 {{form.birth_m}}月 {{form.birth_d}}日
</td>
</tr>
<tr>
<th>ご住所</th>
<td>
<div style='color:red;'> {% if form.zipn.errors.as_text != '' %}
{{form.zipn.errors.as_text|cut:'* '}}
{% endif %}
</div>
〒 {{form.zipn}}
<div style='color:red;'> {% if form.pref1.errors.as_text != '' %}
{{form.pref1.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.m_pref_id}}<br> {{form.pref1}}<br> {{form.pref2}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>{{form.tel.label}}</th>
<td>
<div style='color:red;'> {% if form.tel.errors.as_text != '' %}
{{form.tel.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.tel}}
</td>
</tr>
<tr>
<th>{{form.syumi.label}}</th>
<td>
<div style='color:red;'> {% if form.syumi.errors.as_text != '' %}
{{form.syumi.errors.as_text|cut:'* '}}
{% endif %}
</div>
{% for field in form.syumi %}
<nobr>{{field}}</nobr>
{% endfor %}
</td>
</tr>
<tr>
<th>{{form.bikou.label}}</th>
<td>
<div style='color:red;'> {% if form.bikou.errors.as_text != '' %}
{{form.bikou.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.bikou}}
</td>
</tr>
<tr>
<td colspan='2' align='center' height='100'>
{% csrf_token %}
<input type='submit' value=' 登 録 '>
</td>
</tr>
</table>
</form>
{% endblock %}
{% block my_body %}
いんでっくす<br>
<form method='POST' action="{% url 'prof:index' %}">
<table border='0' width='600'>
<tr>
<th width='200' style='vertical-align:bottom;'>{{form.mail.label}}</th>
<td width='400'>
<div style='color:red;'> {% if form.mail.errors.as_text != '' %}
{{form.mail.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.mail}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>お名前</th>
<td>
<div style='color:red;'> {% if form.lname.errors.as_text != '' %}
{{form.lname.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.lname.label}} {{form.lname}} {{form.fname.label}} {{form.fname}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>オナマエ</th>
<td>
<div style='color:red;'> {% if form.lname_k.errors.as_text != '' %}
{{form.lname_k.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.lname_k.label}} {{form.lname_k}} {{form.fname_k.label}} {{form.fname_k}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>{{form.sex.label}}</th>
<td>
<div style='color:red;'> {% if form.sex.errors.as_text != '' %}
{{form.sex.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.sex.0}} {{form.sex.1}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>{{form.birth_y.label}}</th>
<td>
<div style='color:red;'> {% if form.birth_y.errors.as_text != '' %}
{{form.birth_y.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.birth_y}}年 {{form.birth_m}}月 {{form.birth_d}}日
</td>
</tr>
<tr>
<th>ご住所</th>
<td>
<div style='color:red;'> {% if form.zipn.errors.as_text != '' %}
{{form.zipn.errors.as_text|cut:'* '}}
{% endif %}
</div>
〒 {{form.zipn}}
<div style='color:red;'> {% if form.pref1.errors.as_text != '' %}
{{form.pref1.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.m_pref_id}}<br> {{form.pref1}}<br> {{form.pref2}}
</td>
</tr>
<tr>
<th style='vertical-align:bottom;'>{{form.tel.label}}</th>
<td>
<div style='color:red;'> {% if form.tel.errors.as_text != '' %}
{{form.tel.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.tel}}
</td>
</tr>
<tr>
<th>{{form.syumi.label}}</th>
<td>
<div style='color:red;'> {% if form.syumi.errors.as_text != '' %}
{{form.syumi.errors.as_text|cut:'* '}}
{% endif %}
</div>
{% for field in form.syumi %}
<nobr>{{field}}</nobr>
{% endfor %}
</td>
</tr>
<tr>
<th>{{form.bikou.label}}</th>
<td>
<div style='color:red;'> {% if form.bikou.errors.as_text != '' %}
{{form.bikou.errors.as_text|cut:'* '}}
{% endif %}
</div>
{{form.bikou}}
</td>
</tr>
<tr>
<td colspan='2' align='center' height='100'>
{% csrf_token %}
<input type='submit' value=' 登 録 '>
</td>
</tr>
</table>
</form>
{% endblock %}
● prof/confirm.html
{% extends 'layout/base.html' %}
{% block my_body %} こんふぁ~む
<form method='POST' action="{% url 'prof:data_save' %}">
<table width='600'>
<tr>
<th width='200'>{{form.mail.label}}</th>
<td width='400'>{{form.mail.value}}</td>
</tr>
<tr>
<th>お名前</th>
<td>{{form.lname.value}} {{form.fname.value}}<br>{{form.lname_k.value}} {{form.fname_k.value}}</td>
</tr>
<tr>
<th>{{form.sex.label}}</th>
<td>
{% if form.sex.value == '1' %}
男性
{% else %}
女性
{% endif %}
</td>
</tr>
<tr>
<th>{{form.birth_y.label}}</th>
<td>{{form.birth_y.value}} 年 {{form.birth_m.value}} 月 {{form.birth_d.value}} 日</td>
</tr>
<tr>
<th>ご住所</th>
<td>
{{ken}} {{form.pref1.value}} {{form.pref2.value}}<br>
</td>
</tr>
<tr>
<th>{{form.tel.label}}</th>
<td>{{form.tel.value}}</td>
</tr>
<tr>
<th>{{form.syumi.label}}</th>
<td>{{syumi}}</td>
</tr>
<tr>
<th>{{form.bikou.label}}</th>
<td>{{form.bikou.value|linebreaks}}</td>
</tr>
<tr>
<td colspan='2'>
<input type='submit' name='form_back' value='戻る'>
<input type='submit' name='form_save' value='登録'>
</td>
</tr>
</table>
{% for field in form.visible_fields %}
{{ field.as_hidden }}
{% endfor %}
{% csrf_token %} </form>
{% endblock %}
{% block my_body %} こんふぁ~む
<form method='POST' action="{% url 'prof:data_save' %}">
<table width='600'>
<tr>
<th width='200'>{{form.mail.label}}</th>
<td width='400'>{{form.mail.value}}</td>
</tr>
<tr>
<th>お名前</th>
<td>{{form.lname.value}} {{form.fname.value}}<br>{{form.lname_k.value}} {{form.fname_k.value}}</td>
</tr>
<tr>
<th>{{form.sex.label}}</th>
<td>
{% if form.sex.value == '1' %}
男性
{% else %}
女性
{% endif %}
</td>
</tr>
<tr>
<th>{{form.birth_y.label}}</th>
<td>{{form.birth_y.value}} 年 {{form.birth_m.value}} 月 {{form.birth_d.value}} 日</td>
</tr>
<tr>
<th>ご住所</th>
<td>
{{ken}} {{form.pref1.value}} {{form.pref2.value}}<br>
</td>
</tr>
<tr>
<th>{{form.tel.label}}</th>
<td>{{form.tel.value}}</td>
</tr>
<tr>
<th>{{form.syumi.label}}</th>
<td>{{syumi}}</td>
</tr>
<tr>
<th>{{form.bikou.label}}</th>
<td>{{form.bikou.value|linebreaks}}</td>
</tr>
<tr>
<td colspan='2'>
<input type='submit' name='form_back' value='戻る'>
<input type='submit' name='form_save' value='登録'>
</td>
</tr>
</table>
{% for field in form.visible_fields %}
{{ field.as_hidden }}
{% endfor %}
{% csrf_token %} </form>
{% endblock %}
● prof/thanks.html
{% extends 'layout/base.html' %}
{% block my_body %}
あんがとん。。。
{% endblock %}
{% block my_body %}
あんがとん。。。
{% endblock %}



