2013年1月16日水曜日

Djangoで、キーワード検索

Django(1.4.2)で、キーワード検索です。ブログ一覧表示画面に、タイトル(title)と本文(body)を検索する機能を追加してみました。Julien_Phalipさんのサイトを参考にさせていただきました。実は、ソースがエレガントすぎて、何をやっているのかわからない(笑)。それでも、見事なまでに動いています。今は、このまま利用させていただいて、後から、じっくり悩むことにしましょう。

from django.db.models import Q
import re

# 空白文字の削除
def normalize_query(query_string,
                    findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
                    normspace=re.compile(r'\s{2,}').sub):
    query_string = query_string.replace(u' ', ' ')
    query_string = query_string.replace(u'、', ' ')
    return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)] 

# 検索クエリ作成
def get_query(query_string, search_fields):
    query = None 
    terms = normalize_query(query_string)
    for term in terms:
        or_query = None 
        for field_name in search_fields:
            q = Q(**{"%s__icontains" % field_name: term})
            if or_query is None:
                or_query = q
            else:
                or_query = or_query | q
        if query is None:
            query = or_query
        else:
            query = query & or_query
    return query

# 検索フォーム
class SearchForm(forms.Form):
    q = forms.CharField(label="キーワード")

# ブログ表示
def index(request):
    form = SearchForm(request.GET) 
    if ('q' in request.GET) and request.GET['q'].strip():
        query_string = request.GET['q']
        entry_query = get_query(query_string, ['title', 'body',])
        blogs = Blog.objects.filter(entry_query).order_by('-pub_date')
    else:
        blogs = Blog.objects.all().order_by('-pub_date')
テンプレート
<h2>検索</h2>
<form action="" method="GET">
  <label for="id_q">キーワード</label>
  {{ form.q }}
  <input type="submit" value="検索">
</form>

実際に設定してみたサイトがこちら

参考サイト
Adding search to a Django site in a snap({{ Julien_Phalip }}さん)

5 件のコメント:

  1. http://talkativepg-django.herokuapp.com/blog/
    こちらいいですね!!!

    プラグインとか挿入できるようにしてオープンソースにしましょうよ!
    いろんな人が開発に参加してくれたら、いいCMSになるかもですね。

    返信削除
    返信
    1. ありがとうございます!
      Django初心者なので、全く自信がないんです(笑)。
      また、よろしくお願いします。

      削除
  2. ここまでできたら初心者じゃないですよ。。。
    Django勉強会などもしてます。
    これをもっと膨らませたいです。
    是非お話させてください。
    下記までメールいただけないでしょうか?
    tnajun@gmail.com

    返信削除
  3. こんにちは。
    こちら様のサイトを参考にdjangoを最近勉強させていただいております。

    一つ質問なのですが、
    上記キーワード検索のtemplate側の記述を教えてもらう事は可能ですか?

    kn19870228@gmail.com

    返信削除
    返信
    1. コメントありがとうございます。
      テンプレート部分を追記しておきました。
      参考にしていただければと。
      よろしくお願いします。

      削除