@blog.justoneplanet.info

日々勉強

DjangoでFormを作る

前回の記事のコードをベースに解説する。

■Formクラス

以下のようにFormクラスを継承して、ArticleSearchFormクラスを生成する。

# -*- coding: utf-8 -*-
from django import forms

class ArticleSearchForm(forms.Form):
    word = forms.CharField()

■ビュー関数

以下のようにsearch関数を定義する。

from django.http import HttpResponse
from django.http import Http404
from django.template import Context, loader, RequestContext
from models import Article
from forms import ArticleSearchForm

# Create your views here.
def article(request, id):
    try:
        article = Article.objects.get(id = id)
        tpl     = loader.get_template('page/article.html')
        context = Context({'article' : article})
        return HttpResponse(tpl.render(context))
    except Article.DoesNotExist:
        raise Http404

def search(request):
    if request.method == 'POST':
        form = ArticleSearchForm(request.POST)
        if form.is_valid():
            tpl      = loader.get_template('page/search.html')
            articles = Article.objects.filter(title = form.cleaned_data['word'])
            return HttpResponse(tpl.render(RequestContext(
                request,
                {
                    'form'     : form,
                    'articles' : articles
                }
            )))
    else:
        form = ArticleSearchForm()
    tpl = loader.get_template('page/search.html')
    return HttpResponse(tpl.render(RequestContext(
        request,
        {
            'form' : form
        }
    )))

この場合、タイトルが完全一致しないと検索にヒットしないので以下のように__containsを付加する。これはSQLでいうLIKEのような役割だ。

from django.http import HttpResponse
from django.http import Http404
from django.template import Context, loader, RequestContext
from models import Article
from forms import ArticleSearchForm

# Create your views here.
def article(request, id):
    try:
        article = Article.objects.get(id = id)
        tpl     = loader.get_template('page/article.html')
        context = Context({'article' : article})
        return HttpResponse(tpl.render(context))
    except Article.DoesNotExist:
        raise Http404

def search(request):
    if request.method == 'POST':
        form = ArticleSearchForm(request.POST)
        if form.is_valid():
            tpl      = loader.get_template('page/search.html')
            articles = Article.objects.filter(title__contains = form.cleaned_data['word'])
            return HttpResponse(tpl.render(RequestContext(
                request,
                {
                    'form'     : form,
                    'articles' : articles
                }
            )))
    else:
        form = ArticleSearchForm()
    tpl = loader.get_template('page/search.html')
    return HttpResponse(tpl.render(RequestContext(
        request,
        {
            'form' : form
        }
    )))

更に、条件をORで結合させたい場合は以下のようにする。

from django.http import HttpResponse
from django.http import Http404
from django.template import Context, loader, RequestContext
from models import Article
from forms import ArticleSearchForm
from django.db.models import Q

# Create your views here.
def article(request, id):
    try:
        article = Article.objects.get(id = id)
        tpl     = loader.get_template('page/article.html')
        context = Context({'article' : article})
        return HttpResponse(tpl.render(context))
    except Article.DoesNotExist:
        raise Http404

def search(request):
    if request.method == 'POST':
        form = ArticleSearchForm(request.POST)
        if form.is_valid():
            tpl      = loader.get_template('page/search.html')
            word     = form.cleaned_data['word']
            articles = Article.objects.filter(Q(title__contains = word) | Q(content__contains = word))
            return HttpResponse(tpl.render(RequestContext(
                request,
                {
                    'form'     : form,
                    'articles' : articles
                }
            )))
    else:
        form = ArticleSearchForm()
    tpl = loader.get_template('page/search.html')
    return HttpResponse(tpl.render(RequestContext(
        request,
        {
            'form' : form
        }
    )))

この辺はZendの方がSQLチックで直感的な気がする。

■テンプレート

以下のようにテンプレートを記述する。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>search</title>
<head>

<body>
<p>{{error_msg}}</p>
<form action="/search/" method="POST">
{% csrf_token %}
{{form.word}}
<input type="submit" value="search">
</form>
<br>
<table>
<tr>
<th>title</th>
<th>date</th>
</tr>
{% for article in articles %}
<tr>
<td>{{article.title}}</td>
<td>{{article.date}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>

「setting.pyのMIDDLEWARE_CLASSESにdjango.middleware.csrf.CsrfViewMiddlewareが含まれている」かつ「ビュー関数でRequestContextを使用している」場合、{% csrf_token %}にCSRF対策用のトークンが埋め込まれる。

■URL設定

以下のように記述してURLを設定する。

from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
    (r'^article/(?P<id>[0-9]+)/$', 'dj.article.views.article'),
    (r'^search/$', 'dj.article.views.search'),
)

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment