見出し画像

Webアプリ開発(Django+Vue.js+Docker)#6

こちらの記事の続きになります。

今回はテストを登録する仕組みを作ってみましょう!

テスト作成画面

バックエンド

まず、作成したテストを保管する場所を作成しましょう。

models.py

models.pyに移動し、以下を追加しましょう

from django.contrib.auth.models import User

# Create your models here.
class Test(models.Model):
  ## testの科目
  subject = models.CharField(max_length=255, default='')
  ## testの問題・解答
  que = models.CharField(max_length=255)
  ans = models.CharField(max_length=255)
  ## testの出題数
  total = models.IntegerField(default=0)
  ## testの正解回数
  correct = models.IntegerField(default=0)
  ## testの正答率
  percent = models.IntegerField(default=0)
  ## ユーザ
  user = models.ForeignKey(User, default=1, on_delete=models.CASCADE)

これは、テストを保管する場所にどのような形式でテストを保管するのかを定めています。
今回の内容は、科目・問題・解答・出題数・正解回数・正答率・ユーザです。

admin.py

次に、adminサイトと関連付けるため、admin.pyに以下を追加してください。

from .models import Test

# Register your models here.
admin.site.register(Test)

これで、管理方法の設定ができました。

views.py

次は、views.pyでフロントエンドから送られてきたデータをデータベースに登録する部分を作成しましょう。

まずは以下の様に変更します。

from django.core import serializers

from .models import Test

def index(request){----}

def create_test(request):
  if request.method == 'GET':
    return render(request, 'create_test.html')
  elif request.method == 'POST':
    Test.objects.create(subject=request.POST.get('subject'), que=request.POST.get('question'), ans=request.POST.get('answer'), user=request.user)
    return HttpResponseRedirect(reverse('test:create_test'))

今回は、メソッドのPOSTの処理を追加しました。

内容は、
まず、先ほど設定した内容で新規Testの入れ物を作成します。
次に、その入れ物のsubjectには送られてきたデータ内のsubjectと名付けられている部分を格納し、queには同じくqueと名付けられている部分という感じでフロントから送られてきた情報をそれぞれ適した位置に格納していき、テストを作ります。
最後に、全て登録が終わると保管場所に保存されます。

テストを登録すると、元のページに戻ります。(リダイレクト)

では次に、フロントエンドを変更していきましょう。

フロントエンド

前回と同様、フロントエンドからバックエンドへ送信するためには<form>タグを使用し、methodを指定する必要がありました。

そのため、以下を追記します。

<form method="post" action="{% url 'test:create_test' %}"> 
{% csrf_token %}

</form>

ここでは、methodにpostを指定しました。
methodの違いは、完成してからこの部分をgetに変えてみるとわかりやすいです。URLに送る内容が全て表示されてしまいます。

ここに書いてある、{% csrf_token %}の意味をせつめいします。
フロントエンドからデータベースに保存する際に、鍵が必要になります。
これはそのカギだと思っていただければ大丈夫です。

以降もフロントからデータベースの内容を変更する部分が出てきますが、全ての場合でこの記述が必要になります。

バックエンドに送る内容を入力する部分を作っていきます。
formタグ内に以下を追記してください。

<!-- 科目のプルダウンメニュー -->
<div>
    <label class="form-label">科目<br>
      <input name="subject" placeholder="未分類" type="subject" list="subject">
      <datalist id="subject">
        もしくはリストから選択
        <select>
        {% for subject in tests_list %}
          <option value="{{ subject }}"></option>
        {% endfor %}
        </select>
      </datalist>
    </label>
  </div>

まずはプルダウンメニューです。
この部分に関しては、再度バックエンドに戻って記述していきます。
データベースに登録されている科目をとってきてプルダウンメニューの選択項目にしています。

<input>タグは新たにユーザ自身が入力出来るようにしている部分で、<datalist>内の<select>タグはプルダウンメニューを作るときのタグです。

また、その中でジャンゴのテンプレート言語を使用してforループを回してデータベースからとってきた科目を全部表示しています。

プルダウンメニューはこんな感じです。

次は、以下をその下に追記して見ましょう。

  <!-- 問題・解答 -->
  <div>
    <label class="form-label">問題</label>
    <textarea  rows="5" cols="50" class="form-control" placeholder="問題文を入力してください" name="question"></textarea>
  </div>
  <div>
    <label class="form-label">解答</label>
    <textarea  rows="5" cols="50" class="form-control" placeholder="解答を入力してください" name="answer"></textarea>
  </div>

これは以下を参考にしたものになってます。
タグを<textarea>に変更しました。

ここで、<textarea>タグの中にrow・colとありますが、これはテキストエリアのサイズを決定しています。

また、idを設定する理由は、バックエンドで新規テストに登録する際にsubjectやque等を分けないといけませんでした。
ここで、それぞれの文章に名前(id)をつけることで、バックエンドでそれぞれの内容を抽出できるようになります。

最後に、送信ボタンを設定します。

<!-- 追加ボタン -->
  <button type="submit" class="btn btn-primary">テストを追加</button>

ボタンは、前ページ遷移をさせる際に追加したものと同様のものになっています。

これでひとまずフロントエンドは終了です。
それでは、ページ表示時に最後にプルダウンメニューへ登録されている科目を送る部分を作っていきます。

バックエンド

views.py

プルダウンメニューに科目を送るのは画面表示の際なので、create_test関数のgetメソッドの部分に記述していきます。

内容は以下のようになってます。

if request.method == 'GET':
    tests_list = {}
    tests = Test.objects.filter(user=request.user).distinct().values_list('subject', flat=True)
    tests_list["tests_list"] = tests
    return render(request, 'create_test.html', tests_list)

まず、tests_listというフロントに送るための配列を作成します。
次に、testsに保管されているテストにフィルタリングを施しながら科目を重複を許さずに抽出していきます。
最後にそれをtests_listに格納し、フロントエンドにページを表示するのと同じタイミングで送ります。

スーパーユーザの設定

是だけでは、データベースにどのようなテストが登録されているのか見ることができません。
そのため、その保管庫(adminサイト)を見れるようにアカウント登録しましょう。

以下を参考にしました。

スーパーユーザの設定のためにはdockerのコンテナ内に入りバッシュを表示する必要があります。

ではまず、今から入るコンテナの名前を確認しましょう。
docker psと打ち込んで、現在起動中のコンテナを確認します。
そこで、NAMESの部分をコピーし、以下のコマンドを自分のコンテナの名前に書き換えて打ち込みます。

docker psコマンド
コンテナに入りbashを表示する

バッシュを表示すると、今までフォルダの構成を表していた左の部分が変わり、「root@~~~~#」という表記になります。

ここで、以下を実行し、登録を始めます。

python3 manage.py createsuperuser

これを実行すると、ユーザ名から順に登録していくことができるようになるので、お好きなように登録してください。
※パスワードは入力が見えないようになっているのでびっくりしないでください。
※当たり前ですが、登録内容を忘れずに

Username (leave blank to use 'root'): お好きなように
Email address: Enterでもいい
Password: お好きなように
Password (again): お好きなように
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
Bypass password validation and create user anyway? [y/N]: 

最後にyを押して登録完了です。

exitと入力し、bashを抜けましょう。

これで登録完了!

確認

http://localhost/admin/

に接続し、先ほどのユーザ名とパスワードを入力して見ましょう。
これでは入れたら完成!

最終確認

それでは、今回の変更を確認して見ましょう。
まず、テストの型を追加したので、もう一度ビルドをし直す必要があります。

一度docker-compose downしてコンテナを終了します。
その後、docker-compose buildした後に、いつも通り、docker-compose upしてください。

テストを作る画面に行き、入力した後にボタンを押した際にエラーが出ていなければ大丈夫です。

adminサイト

テストがちゃんと登録されているかは、adminサイトにログインし、TESTと表示されている部分をクリックすると確認ができます。

以上で完了です!


この記事が参加している募集

スキしてみて

振り返りnote

この記事が気に入ったらサポートをしてみませんか?