12
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Django】forms.ModelFormでフォームの作り方

Posted at

#概要
Djangoのforms.ModelFormで「ユーザーが投稿できるフォーム画面」を実装したいと思います。

前回と同様に、タイトルとメモを投稿するフォームになっています。(掲示板みたいな)

なお、環境はpython 3.7.3django 2.2になります。

#1. プロジェクト作成
1-1. まずはプロジェクトファイルを作りたいので、下記のコマンドでディレクトリを作成します。

terminal
$ mkdir sampleform

1-2. 次にsampleformというプロジェクトを作成します。最後の.は正しいので、そのとおり実行してください。(ディレクトリはsimpleformであることを確認してください)

terminal
~sampleform$ django-admin startproject formproject .

1-3. コマンドを実行するとsampleformディレクトリには、下記のようにファイルが生成されます。

sampleform/
sampleform
├── formproject
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

#2. アプリケーションを作成
2-1. 新しくアプリケーションを作成したいので、下記のコマンドを実行します。今回は、formappというアプリケーションです。

terminal
$ python manage.py startapp formapp

実行したらディレクトリは下記のようになると思います。

ざっくり3つに分けると、sampleformディレクトリ内に、①formappというアプリケーション、②formprojectというプロジェクト、③manage.pyファイルになります。

simpleform/
simpleform
├── formapp
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── formproject
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   └── settings.cpython-37.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

2-2. formprojectsettings.pyにあるINSTALLED_APPSに、formappを追加します。

formproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #追加
    'formapp',
]

2-3. formと投稿一覧のlistを表示できるようTEMPLATESにも設定をします。DIRS[BASE_DIR, 'templates'を追加します。

formproject/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        #追加
        'DIRS': [BASE_DIR, 'templates'],
        #ここまで
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

2-4. モデルの定義をmodels.pyに追加します。

formapp/models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    memo = models.TextField()

2-5. 新しいモデルをデータベースに追加するので、makemigrationsmigrateを実行します。

terminal
$ python manage.py makemigrations
$ python manage.py migrate

#3. Formを表示させよう
3-1. まずは、formproject/urls.pyに下記のように追加してください。

formproject/urls.py
from django.contrib import admin
#includeを追加
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    #追加
    path('', include('formapp.urls')),
]

3-2. formappurls.pyファイルを新規作成して、下記のコードを追加してください。これで、
https://サイト名.com/とアクセスすれば、投稿一覧のlistが表示され、
https://サイト名.com/formとアクセスすれば、新規投稿のformが表示され、
https://サイト名.com/details/番号とアクセスすれば、投稿の詳細であるdetailが表示されるようにします。

formapp/urls.py
from django.urls import path
from .views import listfunc, formfunc, detailfunc

urlpatterns = [
    path('', listfunc, name='list'),
    path('form/', formfunc, name='form'),
    path('detail/<int:pk>', detailfunc, name='detail'),
]

3-3. 後ほど作成するTemplatesにアクセスできるよう、views.pyに処理を追加してください。

formapp/views.py
from django.shortcuts import render, redirect
from django.utils import timezone
from .models import Post
from .forms import PostForm

def formfunc(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            return redirect('list')
    else:
        form = PostForm()
    return render(request, 'form.html', {'form': form})

def listfunc(request):
    posts = Post.objects.all()
    return render(request, 'list.html', {'posts': posts})

def detailfunc(request, pk):
    post = Post.objects.get(pk=pk)
    return render(request, 'detail.html', {'post': post})

3-4. formに必要なforms.pyファイルを、formappに新規作成して、下記のようにしてください。

formapp/forms.py
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('title', 'memo')

3-5. Templatesフォルダーをsampleformに新規作成してください。その中に下記ファイルを作成し、それぞれコードを追加してください。
base.html
detail.html
form.html
list.html

sampleform/templates/base.html
<!DOCTYPE html>
<html>
  <head>
    <title>Post App</title>
  </head>
  <body>
    <a href="/">Home</a> | <a href="{% url 'form' %}">新規投稿</a>
    {% block content %}
    {% endblock %}
  </body>
</html>
sampleform/templates/detail.html
{% extends 'base.html' %}

{% block content %}
  <p>タイトル:{{ post.title }}</p>
  <p>メモ:{{ post.memo }}</p>
{% endblock content %}

sampleform/templates/form.html
{% extends 'base.html' %}

{% block content %}
  <h1>Create New Post</h1>
  <form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">投稿する</button>
  </form>
{% endblock %}

sampleform/templates/list.html
{% extends 'base.html' %}

{% block content %}
  <p>-------------------</p>
  {% for post in posts %}
    タイトル:<a href="{% url 'detail' post.pk %}">{{ post.title }}</a>
    <p>-------------------</p>
  {% endfor %}
{% endblock content %}

ディレクトリは下記のようになるはずです。

sampleform/
sampleform
├── formapp
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── formproject
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   └── settings.cpython-37.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── templates
    ├── base.html
    ├── detail.html
    ├── form.html
    └── list.html

#4. localhost起動
4-1. localhostを起動して、しっかりと表示されるか確認したいので、runserverを実行します。

terminal
$ python manage.py runserver

4-2. http://localhost:8000/をブラウザーで開くと、このようなフォームが表示されるはずです。(まだ何も投稿していないので、一覧に何もありません)
sampleform1.png

①「新規投稿」をクリックして、試しに投稿してみましょう。
sampleform3.png

②そうしたら一覧に、さきほどの投稿が表示されているはずです。

最後に「タイトル(画像ではtest)」をクリックしてみると...
sampleform4.png

③...しっかり詳細が表示されています!
sampleform5.png

このように一覧表示(list)投稿画面(form)詳細画面(detail)が動作していれば、正しく実行できています。

以上

12
19
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?