django | 14. ModelFormバージョンの追加(CREATE)


質問登録ページの作成とリンク


1.質問登録ページの作成

<!-- home/question_form.html -->

<h1>질문 등록 페이지</h1>

2.質問登録ボタンの作成

<!-- home/question_list.html -->

...

<a href="{% url 'home:question_create' %}">질문 등록하기</a>
ボタンをクリックして、ホームアプリケーションのquestion createというパスに移動します.(作成されていません)

3. urls.pyでのパスの作成

# home/urls.py
	
urlpatterns = [
  ...
  path('question_create', question_create, name="question_create"),
]
question cerateという関数を実行します.(作成されていません)

4. views.pyで関数を作成するには

# home/views.py

...

def question_create(request):
  return render(request, 'home/question_form.html')

ページを作り直し、つながった.

モデルフォームの使用


1. forms.pyでコメントフォームを作成する

# home/forms.py

from django import forms
from home.models import Question

class QuestionForm(forms.ModelForm): # 모델 폼을 상속받은 QuestionForm 클래스
  class Meta: # 내부 Meta 클래스
    model = Question
    fields = ['subject', 'content']
上記のカテゴリをドラム形と呼ぶ.ドラム形は2種類に分けられ、継承したforms.Formの場合は形、継承したforms.ModelFormの場合は形と呼ぶ.
モデルフォームが作成されました.モデルフォームはモデルに関連付けられたフォームで、モデルフォームオブジェクトを保存して関連モデルのデータを格納できます.
ロングライブラリモデルフォームは内部クラスでなければなりません.モデルクラスには、モデルフォームで使用するモデルとモデルのフィールドが含まれている必要があります.
QuestionFormクラスはQuisionモデルに関連付けられており、subjectとcontentをフィールドとして使用するように定義されています.

2. views.py関数の変更

# home/views.py

...
from .forms import QuestionForm # QuestionForm 클래스 import 하기

...

def question_create(request):
  a_form = QuestionForm() # QuestionForm 클래스로 생성한 객체 a_form을 사용할 것이다.
  context = {'form' : a_form }
  return render(request, 'home/question_form.html', context)

3.質問登録ページの変更

<!-- home/question_form.html -->

{% extends 'base.html' %}
{% block content %}

<div>
  <h5>질문 등록</h5>
  <form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <!-- form이 views.py > question_create 함수에서 전달한 QuestionForm 객체이다. -->
    <!-- {{ form.as_p }} 이 코드는 모델 폼과 연결된 입력 항목 subject, content에 값을 입력할 수 있는 HTML 코드를 자동으로 만들어 준다. -->
    <button>저장하기</button>
  </form>
</div>

{% endblock %}

4.入力データの保存>views。pyの変更

# home/views.py

...

def question_create(request):
  if request.method == 'POST':
    a_form = QuestionForm(request.POST)
    if a_form.is_valid():
      question = a_form.save(commit=False) # 폼에 없는 필드인 create_date부분을 자동입력으로 모델을 설정하였기 때문에 a_form.save()라고 작성하여도 오류가 발생하지는 않는다.
      question.save()
      return redirect('home:question_list')
  else: # request.method == 'GET'인 경우
    a_form = QuestionForm() # QuestionForm 클래스로 생성한 객체 a_form을 사용할 것이다.
  context = {'form' : a_form }
  return render(request, 'home/question_form.html', context)
  • 問題登録ボタンをクリックすると、GET 방식問題登録画面が表示され、保存ボタンをクリックして、POST 방식データの保存を要求します.
  • QuestionFormオブジェクトがGET 방식の場合、QuestionForm()のように入力値なしにオブジェクトが生成され、POST 방식QuestionForm(request.POST)のように、画面から転送されたデータでフォームの値が埋め込まれるようにオブジェクトが生成される.
  • a_form.is_valid関数POSTリクエストが受信したa formが有効かどうかをチェックします.フォームが無効な場合は、フォームにエラーが格納され、画面に渡されます.
  • question = a_form.save(commit=False)問題モデルデータをフォーム形式で格納するためのコードです.ここで、commit=Falseは一時貯蔵を意味する.つまり、実際のデータはまだ保存されていません.このテンポラリ・ストレージを使用する理由は、フォームを使用して問題データを格納する場合、Questionモデルのcreate dateに値が設定されていないため、エラーが発生するためです.(フォームには現在subject、contentフィールドのみがあり、create dateフィールドはありません)そのため、一時的に保存した問題オブジェクトを返し、create dateで値を設定し、実際にquestion save()として保存します.
  • question = a_form.save()実行すると、create date属性値がないエラーメッセージが表示されます.
    ->create dateセクションを現在の自動入力に設定し、このブログに従うと、エラーは発生しません.models.pyからcreate_date = models.DateTimeField()と書くとエラーになります.

  • かっこいいね

    もったいぶる


    1.labelを使用してハングルに変更

    # home/forms.py
    
    ...
    
    class QuestionForm(forms.ModelForm): # 모델 폼을 상속받은 QuestionForm 클래스
      class Meta: # 내부 Meta 클래스
        model = Question
        fields = ['subject', 'content']
        # labels 코드 추가하기
        labels = {
          'subject' : '제목',
          'content' : '내용',
        }

    モデルフォームを使用せずにCREATEを実装


    モデルフォームを使用しないcreateを実装するロジックは、次のとおりです.
    1.作文ボタン->問題newをクリックします.htmlに移動
    2.記事の作成を完了するには、完了ボタンをクリックします->question create関数を実行して記事の作成を完了します.

    合成ページの作成


    htmlファイルの作成

    <!-- question_new.html -->
    
    {% extends 'base.html' %}
    {% block content %}
    
    <h1>질문 등록</h1>
    <form action="#" method="POST" enctype="multipart/form-data">
      {% csrf_token %}
      <div>
        <label>글 제목</label>
        <input type="text" name="subject">
      </div>
    
      <div>
        <label>글 내용</label>
        <textarea name="content"></textarea>
      </div>
    
      <input type="submit" value="글 작성">
    </form>
    
    {% endblock %}
    まずformタグのactionメソッドを空にします.作成ボタンをクリックするとactionが実行され、createが完了します.

    views.pyから関数を作成するには

    # views.py
    
    def question_new(request):
      return render(request, 'home/question_new.html')

    urls.pyからurlを接続する

    # urls.py
    
    ...
      path('question_new', question_new, name="question_new"), # 작성 페이지로 이동
    
    ページまで完成しました.

    接続ボタン

    <!-- question_list.html -->
    
    ...
    
    <a href="{% url 'home:question_new' %}">질문 등록하기</a>
    質問の登録ボタンをクリックしてquestion newというurlを実行します.

    create関数の作成

    def question_create(request):
      if request.method == "POST":
        subject=request.POST.get('subject') # HTML의 name에서 받아온 값을 subject에 담는다.
        content=request.POST.get('content')
        Question.objects.create(subject=subject, content=content)
      return redirect('home:question_list')

    create関数をformに接続するaction

    <!-- question_new.html -->
    
    {% extends 'base.html' %}
    {% block content %}
    
    <h1>질문 등록</h1>
    <form action="{% url 'home:question_create' %}" method="POST" enctype="multipart/form-data">
      {% csrf_token %}
      <div>
        <label>글 제목</label>
        <input type="text" name="subject">
      </div>
    
      <div>
        <label>글 내용</label>
        <textarea name="content"></textarea>
      </div>
    
      <input type="submit" value="글 작성">
    </form>
    
    {% endblock %}
    書くボタンをクリックするとformのactionが実行されます.ホームappというquestion createという関数が実行されます.