Vue.jsで検索フォームを作る

Python,TIPS,Vue.jsDjango

前回の投稿ではDjangoのテンプレート内でVueを使用し簡単なCRUDアプリを作成しました。
今回はとても簡単にすぐ実装できる検索フォームを追加したいと思います。



DjangoのViewSetにSearchFilterを作成する

from rest_framework import viewsets, filters # 追加
from .models import Article
from .serializers import ArticleSerializer


class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    filter_backends = (filters.SearchFilter,) # 追加
    search_fields = ('article_id', 'article_heading','article_body') # 追加

前回作成したコードへfiltersのインポートを追加します。
バックエンドを指定し、ArticleViewSetクラスへsearch_fieldsを追加しましょう。


SearchAPIの呼び出し方

検索結果を取得するためにSearchAPIを呼び出す必要があります。
前回作成したrouters.pyを確認してみましょう。

from rest_framework import routers
from article.viewsets import ArticleViewSet


router = routers.DefaultRouter()
router.register('article', ArticleViewSet)

前回の投稿では、APIエンドポイント /api/article でAPI呼び出しを行いました。
実は検索の場合では /api/article?search=harimo のようにgetリクエストに検索パラメーターを追加するだけでOKなのです。


Vueに検索APIを紐付ける

まずはArticleの新規追加ボタンの横に検索ボックスを追加します。

<h1>
  投稿一覧
  <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addArticleModal">
    新規追加
  </button>
</h1>
 

<!--ここから追加-->
<div class="form-inline my-2 my-lg-0">
  <input class="form-control mr-sm-2" type="text" placeholder="Search" v-model="search_term" aria-label="Search" />
  <button class="btn btn-outline-success my-2 my-sm-0" v-on:click.prevent="getArticles()">
    Search
  </button>
</div>
<!--ここまで-->

今回設置した検索フォームは検索ボタンが押下されると getArticles() を呼び出します。
それではgetArticles()をmethodに実装しましょう。

data: {
  articles: [],
  loading: true,
  currentArticle: {},
  message: null,
  newArticle: { article_heading: null, article_body: null },
  search_term: ""
},
methods: {
  getArticles: function() {
    let api_url = "/api/article/";
    if (this.search_term !== "" || this.search_term !== null) {
      api_url = `/api/article/?search=${this.search_term}`;
    }
    this.loading = true;
    this.$http
    .get(api_url)
    .then(response => {
      this.articles = response.data;
      this.loading = false;
    })
    .catch(err => {
    this.loading = false;
    console.log(err);
    });
  }
}

まずはdata内の search_term: "" という部分で検索用の変数を用意しています。
この変数は検索ワードがあるかどうかのチェックに使用します。
もし何かしらの検索ワードが入力された状態でSearchボタンが押下された場合、search_themの中に格納されている文字列をパラメータに含ませてGetリクエストを送ります。

たったこれだけで完成してしまいました。
早速動作確認してみましょう。


まとめ

以上でとても簡単に実装することが出来ました。

今回は自力で検索機能を実装しましたが、Vuetifyを使用すればData-tablesを使用することでも簡単に検索とページング機能ををテーブルへ反映させることが出来ます。

ただし、とても大きなデータを取扱う際は全ての検索結果をVueへ一度に渡さずある程度の件数ごとに結果を取得し直すなどの対策を行わないと動作が遅くなってしまうので注意が必要です。



前回GitHubへアップしたコードをアップデートしました。

Python,TIPS,Vue.jsDjango

Posted by Kenny