質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.79%

Djangoでform作成時にviews.pyで使うgetメソッドとpostメソッドについて

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,624

前提・実現したいこと

Django初心者です。

現在、データベースに登録した本の一覧を表示したり、新しい本を作成したりできる簡単なDjangoプロジェクトを作っています。
アプリケーション名は「shop」です。

今回はこのプロジェクトに関して、特にエラーが出ているわけではないですが、formについて疑問が生じたので、質問させて頂きました。

疑問の部分は、フォームから本を新規登録するところです。
具体的には、shop/views.py内にあるBookCreateViewクラスの中のgetメソッドとpostメソッドです。

まずは、以下にmodels.py、views.py 、forms.pyを示します。

models.pyのコード

from django.db import models


class Book(models.Model):
    """本モデル"""

    class Meta:
        db_table = 'book'

    title = models.CharField(verbose_name='タイトル', max_length=20)
    price = models.IntegerField(verbose_name='価格', null=True, blank=True)

    def __str__(self):
        return self.title

urls.pyのコード

from django.urls import path

from . import views

app_name = 'shop'
urlpatterns = [
    path('', views.index, name='index'),
    path('create/', views.create, name='create'),
]

views.pyのコード

import logging

from django.shortcuts import render
from django.views.generic import View
from django.shortcuts import render, redirect

from .forms import BookForm
from .models import Book
logger = logging.getLogger(__name__)


class BookIndexView(View):
    def get(self, request, *args, **kwargs):
        context = {
            # 本レコードの一覧を取得
            'book_list': Book.objects.all(),
        }
        # ショップ画面を表示
        return render(request, 'shop/book_list.html', context)


index = BookIndexView.as_view()


class BookCreateView(View):
    def get(self, request, *args, **kwargs):
        context = {
            # 空のフォームを作成
            'form': BookForm(),
        }
        # 登録画面を表示
        return render(request, 'shop/book_form.html', context)

    def post(self, request, *args, **kwargs):
        # リクエストの入力データをフォームオブジェクトに変換
        form = BookForm(request.POST)
        # バリデーション実行
        if not form.is_valid():
            context = {
                'form': form,
            }
            # 登録画面を再表示
            return render(request, 'shop/book_form.html', context)
        # モデルオブジェクトを保存
        form.save()
        # ショップ画面にリダイレクト
        return redirect('/shop/')

create = BookCreateView.as_view()

forms.pyのコード

from django import forms

from .models import Book


class BookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ('title', 'price',)

book_form.htmlのコード

<!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>サンプル</title>
        <style>
        form label {
          width: 20%;
          float: left;
        }
        </style>
    </head>
    <body>
    <form method="post" action="/shop/create/">
        {{ form.as_p }}
        {% csrf_token %}
        <button type="submit">登録</button>
    </form>
    </body>
    </html>

疑問点

気になった部分は、views.pyのBookCreateViewの中のgetメソッドとpostメソッドについてです。

まず、私の認識に間違いがあるかもしれないので、getメソッド、postメソッドについて確認させてください。

どこか別のページから、ユーザーがshop/createページ(空のフォームを表示するページ)にアクセスした際に、GETメソッドでやり取りするため、BookCreateViewのgetメソッド(postメソッドではなく)が呼び出されると認識しております。

また、shop/createページでユーザーからformが送信されると、POSTメソッドでやり取りするため、BookCreateViewのpostメソッドが呼び出されると認識しております。

ここで、疑問なのですが、form送信をGETメソッドに変更した場合、BookCreareViewのpostメソッドをgetメソッドにする必要があると思います。

しかし、そうすると、同じBookCreateViewクラス内にgetメソッドが2つあることになってしまい(元々あったgetメソッドとpostメソッドから変更したgetメソッド)、Djangoがどっちのgetメソッドを使えば良いのか判断できなくなってしまうと考えられます。

このようにformをGETメソッドに書き換えた場合に、上手くgetメソッドを使用して、form画面の表示から送信、データベースへの反映を行う方法はありますでしょうか?

もちろん、クラスベースViewを使うなど、他に方法はあると思うのですが、Djangoについての理解を深めるためにgetメソッドを使う方法があれば教えて頂きたいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

ちょっと端的な回答になってしまいますが、、
ウェブをクロールしているときは、常にGETメソッドです。
他方、html内のformでPOSTの指定をすることで、POSTメソッドとしてデータが送信されます。
ですので、GETが重複することはありません。
request.method='GET'という形で指定することが可能です。
そして、GETメソッドを指定して実行される内容は、リンクをたどってウェブサイトを見た時と同じ処理になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/08 08:50

    ご回答ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る