気ままなタンス*プログラミングなどのノートブック

プログラミングやRPGツクール、DTM等について、学んだことや備忘録をアウトプットとして残し、情報を必要としている誰かにとって「かゆいところに手が届く」ブログとなることを願いながら記事を書いています。

【Django】マスタ系のCRUDを書く時の基本的な流れと実際のソースコード

スポンサーリンク

Djangoでマスタ系のCRUDを書く時の基本的な流れを備忘録として記載します。

(タイトルにCRUDと書いたのですが、Deleteに関するコードはありません。予めご了承ください。)

この記事では下記目次の順番でDjangoアプリを作成していきます。

モデルの記述

まずはDjangoモデルを作成します。
models.Modelを継承したモデルクラスを用意し、
nameフィールドとany_choiceフィールドを記述します。

any_choiceフィールドは、朝(0)・昼(1)・夜(2)の選択肢をセットすることにします。

ソースコード
""" any/models.py """
# coding: utf-8
from django.db import models

CHOICES = (
    ('0', '朝'),
    ('1', '昼'),
    ('2', '夜'),
)

class Any(models.Model):
    name = models.CharField(max_length=255)
    any_choice = models.CharField(max_length=10, choices=CHOICES)

    def __unicode__(self):
        return self.name

フォームの記述

続いて、データ登録を行うためのFormクラスを作成します。
モデルからフォームの作成が可能なforms.ModelFormを利用することにします。
(フォームクラス用にモデルと同じフィールドを用意するという冗長な作業が削減できます)

ソースコード
""" any/forms.py """
# coding: utf-8
from django import forms
from any.models import *

class AnyForm(forms.ModelForm):
    class Meta:
        model = Any
        fields = ('name', 'any_choice',)

ビューの記述

上記で作成したモデルに対するデータを登録・編集する際に
呼び出されるビューを記述します。

  • 登録・編集ともに同じビュー関数を利用し、URLスキームとパラメータのみ異なるようにします。
  • Anyデータの一覧を参照するためのビュー関数は用意せず、クラスベースビューdjango.views.generic.list.ListViewを利用します。
ソースコード
""" any/views.py """
# coding: utf-8
from any.models import Any
from any.forms import AnyForm
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from django.views.generic.list import ListView

# 編集及び新規any用ビュー
def any_edit(request, any_id=None):
    if any_id is not None:
        any = get_object_or_404(Any, pk=any_id)
    else:
        any = Any()

    # 登録
    if request.method == "POST":
        any_form = AnyForm(request.POST, instance=any)
        if any_form.is_valid():
            any = any_form.save(commit=False)
            any.save()
            return redirect('any:index')
    else:
        any_form = AnyForm(instance=any)
    
    return render_to_response('any/any_edit.html',
                               dict(any_form=any_form, any_id=any_id),
                               RequestContext(request)
                              )


# Anyの一覧表示は、ListViewを利用する
class AnyList(ListView):
    context_object_name = 'any_objects'
    paginate_by = 10
    template_name = 'any/index.html'

    def get(self, request, *args, **kwargs):
        any_list = Any.objects.all()
        self.object_list = any_list
        context = self.get_context_data(object_list=self.object_list)
        return self.render_to_response(context)

URLの記述

ビューの記述が終わったら、URLの記述を行います。
プロジェクトのurls.pyとDjangoアプリのurls.pyにそれぞれ追記します。

  • クラスベースビューの場合は、as_viewメソッドをコールし、対応するviewとしてセットします
  • add, editそれぞれ同じany_editビューを呼んでいますが、パターンにマッチするスキームが違います
  • プロジェクトのurls内でincludeする時、アプリurlに対して、namespaceを指定しておきます
ソースコード
""" project/urls.py """
from django.conf.urls import patterns, include, url
from django.contrib import admin
    url(r'^admin/', include(admin.site.urls)),
    url(r'^any/', include('any.urls', namespace='any')),

""" any/urls.py """
from django.conf.urls import patterns, url
from any import views

urlpatterns = patterns('',
   url('^index/$', views.AnyList.as_view(), name='index'),
   url('^add/$', views.any_edit, name='any_add'),
   url('^edit/(?P<any_id>)\d+/$', views.any_edit, name='any_edit'),
)

テンプレートの記述

Djangoテンプレートを記述します。
プロジェクトURLのnamespaceでanyを指定したため、ビューのURLが{% url 'any:add' %}で参照できるようになっています。

any/index.htmlでは、Anyデータの一覧を表示するための、any_objectsを参照しています。
これは、クラスベースビューでcontext_object_name = 'any_objects'という形でコンテキストで参照するための名前を設定したからです。

ソースコード
<!-- any/index.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>index</title>
</head>
<body>
    <a href="{% url 'any:add' %}">New</a>
    <table>
        <tr>
            <th>名前</th>
            <th>時間区分</th>
            <th>操作</th>
        </tr>
        {% for any in any_objects %}
        <tr>
            <td>{{ any.name }}</td>
            <td>{{ any.any_choices }}</td>
            <td><a href="{% url 'any:edit' any_id=any_id %}">編集</a></td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>


<!-- any/any_edit.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>index</title>
</head>
<body>
    <form action="{% url 'any:edit' any_id=any_id %}" method="post">
        {{ any_form.name }}
        {{ any_form.any_choices }}
        {% csrf_token %}
        <input type="submit" value="登録">
    </form>
</body>
</html>


今回は、Djangoのマスタ系CRUDにおける基本的な流れを記載しました。

それでは、皆様も楽しいDjangoコーディングを!


おすすめのPython本

Pythonプロフェッショナルプログラミング 第2版

Pythonプロフェッショナルプログラミング 第2版

初めてのPython 第3版

初めてのPython 第3版