SEの転職活動で使うべきサイト・エージェント 目指せ年収アップ
SEの転職活動で使うべきサイト・エージェント 目指せ年収アップ
東南アジアをバックパッカーしながら転職活動をした記録
東南アジアをバックパッカーしながら転職活動をした記録
7年目で初の転職活動 2カ月で内定獲得した記録
7年目で初の転職活動 2カ月で内定獲得した記録
おすすめのプログラミングスクール めざせ就職・年収アップ!
おすすめのプログラミングスクール めざせ就職・年収アップ!
メンズクリア2年通い放題入会! その後のヒゲ状況(不定期更新)
メンズクリア2年通い放題入会! その後のヒゲ状況(不定期更新)
ブログ開始3年が経った月収が1万超えてた!
ブログ開始3年が経った月収が1万超えてた!
プログラミング独学・スクール・就職(目次)
プログラミング独学・スクール・就職(目次)
previous arrowprevious arrow
next arrownext arrow
 
Shadow
Django

Django独学 フォームを使ってDBを更新する

Djangoのユーザ管理アプリ作成の目次ページはこちらです。

Djangoでユーザ管理アプリ デモ動画とソースコード公開 Djangoのユーザ管理アプリ作成の目次ページはこちらです。 Djangoでユーザ管理アプリの作ったので、ソースコ...

 

今回は、フォーム機能を使ってDBへ新規登録をさせます。

UdemyのDjangoの基礎をマスターして、3つのアプリを作ろう!を参考に勉強していています。

また、フォームを扱っていくのでHTMLの基本的な知識がある方でないとも難しいかもしれません。

更新処理の流れ

登録の時と同じで、以下の流れです。

①入力フォームをリクエストから呼び出す

②入力フォームをブラウザに表させる

③フォームに入力したデータをサーバに渡して更新

④更新した結果をブラウザに表示

この順番で処理を作成していきます。

Django独学 フォームを使ってDBに新規登録をする Djangoのユーザ管理アプリ作成の目次ページはこちらです。 https://loosecarrot.com/2023/0...

①入力フォームをリクエストから呼び出す(urls.py)

まず最初に「~users/edit/id」と言うURLをユーザー更新のURLにします。

そのために、URLへアクセスされたときの動作をアプリのurls.pyに記入します。

from django.urls import path
from . import views
#import views

urlpatterns = [
    path('', views.showUsers, name='showUsers'),

    #ユーザの詳細情報を表示する処理を呼び出す
    path('<int:id>', views.showDetail, name='showDetail'),
    #ユーザの登録フォームを呼び出す
    path('create', views.showCreateUserForm, name='showCreateUserForm'),
    #ユーザ登録する処理を呼び出す
    path('add', views.addUser, name='addUser'),
    #ユーザ編集するフォームを呼び出す
    path('<int:id>/edit', views.showEditUserForm, name='showEditUserForm'),
]

15行目に追記をしました。

※この次にviews.pyの説明を記載します。

一旦viewsのことは置いておいて、やっていることだけ理解してみて下さい。

path(‘<int:id>/edit’, views.showEditUserForm, name=’showEditUserForm’),の解説です。

‘<int:id>/edit’:URLがusers/id/edit/場合の指定した処理を呼ぶという意味

views.showEditUserForm:views.pyのshowEditUserFormの処理を呼ぶという意味です。

name=’showEditUserForm’:リンク先に指定するときの名前で後で使います。

②編集フォームをブラウザに表させる

新規登録フォームは入力欄は空白でしたが、

編集フォームではユーザの情報をフォームに表示させます。

そのため、

以下の流れになります。

①更新対象のユーザ情報を取得

②htmlへフォームを渡す

③ブラウザにフォームを表示させる

※フォームは前回新規登録の時に作成したものを使います。

ブラウザに編集フォームを表示させる(views.py)

①~③はすべてviews.pyで作ります。

以下を追記しています。

# 編集フォームをHTMLへ返す
def showEditUserForm(request,id):

    #idをもとにユーザ情報を取得
    userinfo = get_object_or_404(UserInfo,pk=id)
    #フォームをオブジェクトを作成
    userForm = UserForm(instance=userinfo)
    
    #ユーザ情報をフォームに格納
    context = {
        'userinfo':userinfo,
        'userForm':userForm,
    }

    #user.htmlへデータを渡す
    return render(request, 'myapp/edit.html',context)

5行目で更新対象のユーザ情報を取得しています。

7行目ではフォームをインスタンス化して、

16行目でHTML側に情報を渡しています。

ユーザ情報は更新した後に、対象のユーザページを表示するために渡しています。

フォームを表示するHTML作成(edit.html)

edit.htmlはまだ作っていないので、以下に作成します。

C:\django\myproject\myapp\templates\myapp

htmlの中身は以下です。

{% extends './base.html' %}
{% load bootstrap4 %}

{% block app %}
    <h1>ユーザ編集</h1>

    <form action='{% url "showUsers" %}' method='post' class='form'>
        <!-- ユーザー編集フォームを表示 -->
        {% csrf_token %}
        {% bootstrap_form userForm %}
        <button type='submit' class='btn btn-outline-primary'>更新</button>
        <a href='{% url "showUsers" %}' class='btn btn-outline-secondary'>戻る</a>
    </form>
{% endblock %}

ほとんどcreate.htmlのコピペです。

ボタンクリック時のactionで呼び出す関数を変えるだけです。

※ユーザを更新する処理はこの次に書きます。

今はエラー回避のためにユーザ一覧へ遷移するようにしています。

表示させてみるとこんな形で、idをもとにユーザ情報を表示できています。

③フォームに入力したデータを登録後、結果表示

現状は更新ボタンクリック時にユーザ一覧を表示していますが、ユーザ一情報を更新する処理を呼ぶようにします。

まずは更新ボタンをクリックした後、DBに登録する処理を作っていきます。

更新処理を呼び出す(urls.py)

まずはurls.pyにユーザを更新する処理を呼ぶように記載します。

#ユーザ更新する処理を呼び出す
path('<int:id>/update', views.updateUser, name='updateUser'),

この処理をアプリのurls.pyに追記します。

編集フォームの時と同じで、

<int:id>/updateのURLであれば、viewsのupdateUserを呼び出すという意味です。

updateUserの処理は次で作成します。

ユーザ情報DBに更新する処理を作成(views.py)

処理の流れとしては、以下になります。

①フォームデータをDBに更新

②ユーザ詳細ページを表示

以下の処理を追加して①②両方ともviews.pyに記載しています。

#~~~~~~~~~~~~~~~~~
# フォームから受取ったデータをDBに更新する
def updateUser(request,id):
    #リクエストがPOSTの場合
    if request.method == 'POST':
        #idからユーザデータを取得
        userInfo = get_object_or_404(UserInfo,pk=id)
        #ユーザ情報と、リクエストをもとにフォームをインスタンス化
        userForm = UserForm(request.POST,instance=userInfo)
        if userForm.is_valid():
            userForm.save()

    #更新後、対象ユーザの情報を表示
    userInfo = get_object_or_404(UserInfo,pk=id)
    context = {
        'userinfoDetail': userInfo,
    }

    #detail.htmlへデータを渡す
    return render(request, 'myapp/detail.html',context)

9行目について

userFormに変数にPOSTで受取った情報と、対象ユーザーの情報を入れています。

11行目のuserForm.save()

登録の時と同じsave()を使っています。

なぜ全く同じメソッドを呼んで、登録と更新が勝手に分かれるのか調べてみたところ、djangoの仕様で以下になっているそうです。

既にプライマリキーがあるデータの条件を指定した場合は、INSERTでなく
UPDATE SQL 文が実行されます。

Django SQL データベース INSERT UPDATE 追加更新方法 save() create() add() update()

userFormの引数になっているuserInfoはPKが入っているので、自動的に更新になります。

デバッグ実行で止めて、userForm → instanceとたどっていくと、確かにプライマリキー(pk)がありました。

14行目~20行目で、更新した後のユーザ情報を取得して、詳細ページに表示させています。

更新ボタンクリック後にupdateUserを呼ぶ(edit.html)

これでユーザ更新する処理が作成できました。

最後に、edit.htmlの更新ボタンクリックした後の処理を書き換えます。

{% extends './base.html' %}
{% load bootstrap4 %}

{% block app %}
    <h1>ユーザ編集</h1>

    <form action='{% url "updateUser" userinfo.id %}' method='post' class='form'>
        <!-- ユーザー編集フォームを表示 -->
        {% csrf_token %}
        {% bootstrap_form userForm %}
        <button type='submit' class='btn btn-outline-primary'>更新</button>
        <a href='{% url "showUsers" %}' class='btn btn-outline-secondary'>戻る</a>
    </form>
{% endblock %}

7行目の{% url “showUsers” %}を

{% url “updateUser” userinfo.id %}に書き換えました。

これで、ユーザー詳細ページに遷移できます。

編集フォームを呼び出すshowEditUserFormで、userinfoをHTMLへ渡していたのは、

ユーザ情報のidを遷移先のURLにするためです。

localhost:8000/users/1/editにアクセスして、

事項紹介のサッカーを野球にして更新ボタンを押してみると。

更新されて、「サッカー」が「野球」に変わりました!

ユーザ編集ボタンをユーザ一覧に作成(users.html)

最後に、このままだとユーザ編集画面に行くことができません。

なのでユーザ一覧画面に、編集ボタンを作っておきます。

{% extends './base.html' %}
{% block app %}

    <h1>ようこそ!</h1>
    <!-- テーブル -->
    <table class="table table-striped table table-bordered ">
        <thead>
            <tr>
                <th colspan="3">{{msg}}:{{count}}名</th>
            </tr>
        </thead>
        <tbody align="center">
            <!-- count件(行)数分をループ -->
            {% for user in userinfo %}
            <tr>
                <!-- 4列分ユーザ情報を出力 -->
                <td>{{user.userName}}</td>
                <td><a href="{% url 'showDetail' user.id %}" class="btn btn-outline-primary">詳細</a> </td>
                <!-- 編集ボタン -->
                <td><a href="{% url 'showEditUserForm' user.id %}" class="btn btn-outline-primary">編集</a> </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <a href="{% url 'showCreateUserForm' %}" class='btn btn-outline-primary'>ユーザ追加</a>
    
{% endblock %}

20行目でユーザ編集ボタンを追加しました。

引数にはユーザ情報のidをセットしています。

これで編集ボタンが追加できました。

(おまけ)ModelFormに複数行入力のテキストエリアを表示(forms.py)

よく見てみると、自己紹介は500文字まで入力可能なのに、改行をすることができませんでした…

テキストボックスではなく、テキストエリアに変えてあげればOKです。

forms.pyを以下のように修正しました。

from django import forms
from . models import UserInfo

class UserForm(forms.ModelForm):
    class Meta:
        model = UserInfo
        fields = ('userName', 'country','sex','address','selfIntroduction')
        labels={
           'userName':'名前',
           'country':'出身国',
           'address':'住所',
           'sex':'性別',
           'selfIntroduction':'自己紹介',
           }
	    
        #自己紹介をテキストエリアにする
        widgets = {
            'selfIntroduction': forms.Textarea(attrs={'rows':4, 'cols':30}),
        }

17行目の記述方法でテキストエリアに変えることができます。

 

今回はここまでです!

ABOUT ME
LooseCarrot
LooseCarrot
ブログ運営をしているLooseCarrotです。 興味のあることにトライして発信していきます! プロフィール

関連している記事