djangoで便利なモジュールでのログインクラスを使用せずに自前で実装するコードを書きます。
そしてプロフィールを作成はしたものの、更新するにはどうすれば・・・って時に役立つコードです。
CRUD概念の
- create
- read
- update
を習得できます。
コンテンツ
開発環境
・Python 3.8
・django 2.2
・OS / Mac
更新するデータの事前準備
データの作成をする
まずはモデルにデータベースを作成します。
問合せ(inquiry)に投稿する、というイメージです。
そのままコピペして使えます。
models.py
1 2 3 4 5 6 7 8 9 10 11 12 |
from django.db import models class Inquiry(models.Model): class Meta: db_table = 'inquiry' name = models.CharField(verbose_name='name', max_length=255) subject = models.CharField(verbose_name='subject', max_length=255) message = models.CharField(verbose_name='message', max_length=500) email = models.EmailField(verbose_name='email') |
作れましたらコンソールで以下のコマンドを実行しましょう。
1 |
$python manage.py makemigrations |
1 |
$python manage.py migrate |
データの入力フォームの作成
こちらはhtml側で、formを作成するのと、データ入力された際のバリデーション(妥当性チェック)をするためのコードです。
そのままコピペして使えます。
forms.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
from django import forms class InquiryAddForm(forms.Form): name = forms.CharField(required=True, max_length=255,) email = forms.EmailField(required=True, max_length=255,) subject = forms.CharField(required=False, max_length=255,) message = forms.CharField(required=True, max_length=1000, widget=forms.Textarea( attrs={ 'placeholder': 'input some words', } ),) def clean(self): cleaned_data = super().clean() return cleaned_data def clean_name(self): name = self.cleaned_data['name'] return name def clean_email(self): email = self.cleaned_data['email'] return email def clean_subject(self): subject = self.cleaned_data['subject'] return subject def clean_message(self): message = self.cleaned_data['message'] return message |
フロント作成
そのままコピペして反映させれば下記画面のようになります。cssは割愛しています。
inquiry_add.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<h1>Inquiry form</h1> <form action="" method="post"> <table class="inquiry_table"> {% csrf_token %} <tr> <th>Name:</th> <td>{{ form.name }}{{ form.name.errors }}</td> </tr> <th>Email:</th> <td>{{ form.email }}{{ form.email.errors }}</td> <tr> <th>Subject:</th> <td>{{ form.subject }}{{ form.subject.errors }}</td> </tr> <tr> <th>Message:</th> <td>{{ form.message }}{{ form.message.errors }}</td> </tr> <tr> <th></th> <td><button type="submit" class="btn">submit</button></td> </tr> </table> </form> |
上記の入力してPOSTが成功した際の遷移先画面が下記になります。
inquiry_add_success.html
1 2 |
<p>Your message has been sent</p> <small><a href="/" data-test-id="{{ posted_inquiry_id }}">Back to Top page</a></small> |
サーバー側の処理
データをsubmitした時の処理をviewsに書きます。
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
from django.urls import reverse from django.http import HttpResponse, HttpResponseRedirect from django.views.decorators.http import require_http_methods from .forms import InquiryAddForm from .models import Inquiry @require_http_methods(['GET']) def index(request): render(request, 'inquiry_apps/index.html') @require_http_methods(['GET', 'POST']) def inquiry_add(request): if request.method == 'GET': items = { 'name': '', 'email': '', 'subject': '', 'message': '', } context = { 'form': InquiryAddForm(initial=items), } else: # POST form = InquiryAddForm(request.POST) if form.is_valid(): inquiry = Inquiry( name=form.cleaned_data['name'], email=form.cleaned_data['email'], subject=form.cleaned_data['subject'], message=form.cleaned_data['message'], ) inquiry.save() return render(request, 'inquiry_apps/inquiry_add/inquiry_add_success.html') return HttpResponseRedirect(reverse('inquiry_apps:inquiry_add_success')) template = loader.get_template('inquiry_apps/inquiry_add/inquiry_add.html') return HttpResponse(template.render(context, request)) |
パスの処理
最後にパスコードの処理を書きます。これで導線ができました。
urls.py
1 2 3 4 5 6 7 8 9 |
from django.urls import path from . import views app_name = 'inquiry_apps' urlpatterns = [ path('', views.index, name='index'), path('inquiry/add/', views.inquiry_add, name='inquiry_add'), path('inquiry/add/success/', views.inquiry_add_success, name='inquiry_add_success'), |
実際に動作実行
実際にデータをポストします。
1 |
$python manage.py runserver |
で起動します。
ここに好きな文言を入力してsubmitボタンをクリックします。
「成功しました」の画面に遷移すれば、データが作成(create)されています。
本題
ここから本題になります。作成されたデータに対して読み込み(read)と更新(update)を実行します。
formの実装
新たにEditInquiryFormというclassを用意します。先ほど作成したforms.pyに下記コードを追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class EditInquiryForm(forms.Form): name = forms.CharField(required=False) message = forms.CharField(required=False, max_length=1000, widget=forms.Textarea() ) email = forms.EmailField(required=False) def clean(self): cleaned_data = super().clean() return cleaned_data def clean_name(self): name = self.cleaned_data['name'] return name def clean_message(self): message = self.cleaned_data['message'] return message def clean_email(self): email = self.cleaned_data['email'] return email |
サーバー側の処理2
ここが今回の一番の基幹コードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
from .forms import EditInquiryForm @require_http_methods(['GET', 'POST']) def index(request): # id=1のユーザーのプロフィールを固定で出力 qs = Inquiry.objects.get(id=1) if request.method != 'POST': item = { 'name': qs.name, 'email': qs.email, 'subject': qs.subject, 'message': qs.message } form = EditInquiryForm(initial=item) else: form = EditInquiryForm(data=request.POST) if form.is_valid(): inquiry = Inquiry.objects.get(id=1) inquiry.name = form.cleaned_data['name'] inquiry.message = form.cleaned_data['message'] inquiry.email = form.cleaned_data['email'] inquiry.save() return HttpResponseRedirect(reverse('inquiry_apps:index')) context = { 'form': form, 'user': qs, } return render(request, 'inquiry_apps/index.html', context) |
1つめの注目点としては、まず6行目でqs(query setの略)をデータベースからid=1を指定して取得します。
取得されたデータを9~14行目のitemの辞書型オブジェクトに格納し、それを15行目のEditInquiryFormに(initial=item)を渡します。
こうすることでデータを初期値としてセットすることが可能になります。
2つめの注目点としては、21-23行目でバリデーションされたデータを、20行目で取得したquery setに対して更新作業しているところです。
このように更新したいデータを各々書いていき、最後にinquiry.save()でデータを更新できるようになっています。
フロントコード
フロントコードになります。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<h1>Index</h1> <p>this is top page here!</p> <table> <tr> <th>name</th> <td>{{ user.id }}</td> </tr> <tr> <th>Name</th> <td>{{ user.name }}</td> </tr> <tr> <th>Subject</th> <td>{{ user.subject }}</td> </tr> <tr> <th>Message</th> <td>{{ user.message }}</td> </tr> <tr> <th>Email</th> <td>{{ user.email }}</td> </tr> </table> <hr> <form action="" method="POST"> {% csrf_token %} <table> <tr> <th>Id</th> <td>{{ user.id }}</td> </tr> <tr> <th>Name</th> <td>{{ form.name }}</td> </tr> <tr> <th>Subject</th> <td>{{ user.subject }}</td> </tr> <tr> <th>Message</th> <td>{{ form.message }}</td> </tr> <tr> <th>Email</th> <td>{{ form.email }}</td> </tr> <tr> <th></th> <td><button type="submit">更新する</button></td> </tr> </table> </form> |
それでは実際に起動をさせて動きをみてみます。
1 |
$python manage.py runserver |
一番の特徴は入力フォーマットに入力し、更新する度に上でデータが更新されていることがわかります。
また同時に入力フォーマットも更新されていることがわかります。
プログラミング学習を効率良く進めるには…
私ヒロヤンがプログラミングを始めた頃は以下のような感じでした。
そしてネットで調べていくうちに膨大な時間が過ぎていきました。
私ヒロヤンの実体験より、プログラミングを効率的に学ぶために大切なことは以下のことだと考えています。
1. いつまでもダラダラとやらないで、目標を決定して短期集中する
2. マンツーマンで、わからない箇所は直ぐに質問をして即レスをもらう
.proでは私ヒロヤンが学習してきたプログラミング経験0からのpython/django、その他webサイト・サービス開発のコースが用意されています。
カウンセリング自体は無料なので話を聞いてみるだけでもいかがでしょうか?
また以下のリンク先ではdjangoを教えてくれるスクールをまとめ紹介しています。