0
0

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 1 year has passed since last update.

【Django】DBに保存した文字列をボタンでコピーする方法

Posted at

こんにちは、k_ukiです。現在卒業研究でDjangoを用いたwebアプリの開発を行っております。
その中で、ボタンを押すことでその文字列をクリップボードにコピーする機能を実装しました。今回はその実装方法について述べていきます。
Videotogif (1).gif

また、この記事ではオブジェクトを出力する方法(通常のCRUDの処理)やルーティングなどの実装方法は省略いたします。

テンプレートの作成

以下は、ボタンを配置するページのコードです。

{% extends 'base.html' %}
{%block title%}提案結果 {%endblock%}
{% block content %}
<div class="container">
    <div class="row">
        <div class="col-lg-8">
            <h2>提案結果</h2>
            <h3>こちらのワードなどいかがでしょうか?</h3>
            <table>
                <tbody>
                    <!-- ここから -->
                    <!-- ワードを繰り返し出力 -->
                    {% for word in suggest_result %}
                    <tr>
                        <!-- viewに情報を送信するためのフォーム -->
                        <form action="{% url 'search_word' object.pk %}" method="post">
                            {% csrf_token %}
                            <!-- ワードをボタンにして出力({{word}}に格納) -->
                            <td><input type="submit" name="copy_word" value="{{word}}"></td>
                        </form>
                    </tr>
                    {% endfor %}
                    <!-- 確認用のテキストフィールド(必要はありません) -->
                    <td><input type="text"></td>
           <!-- ここまで -->
                </tbody>
            </table>
        </div>
    </div>
</div>
{% endblock content %}

記述について、一つひとつ解説していきます。

{% for word in suggest_result %}

ここでは、配列"suggest_result"に格納されたワードを一つずつ"word"に格納して出力できるようにしています。for文をテンプレートに書く際には"{% endfor %}"を忘れずに書きましょう。

    <!-- viewに情報を送信するためのフォーム -->
 <form action="{% url 'search_word' object.pk %}" method="post">
    {% csrf_token %}
    <!-- ワードをボタンにして出力({{word}}に格納) -->
    <td><input type="submit" name="copy_word" value="{{word}}"></td>
 </form>

 ここでは、viewに値を送信するためのフォームを作成しています。
 formタグの"action"では、formの送信先を指定しています。ここでは、'search_word'となっていますが、実際は"search_word/:pk"に送信していることになります。また、urlの:pkに該当する部分が"object.pk"になります。"search_word/:pk"というurlはボタンを表示させているページと同じurlになるため、ユーザーから見たら何も起きていないように見えます。

{% csrf_token %}

 この記述によってcsrfトークンを同時に送信しています。Djangoではフォームを用いる際にはcsrfトークンを同時に送信する必要があります。

<input type="submit" name="copy_word" value="{{word}}">

 この記述では、コピーしたい文字列が含まれたボタンを生成しています。 
 type="submit" とすることで、入力の形式をsubmitボタンに変更しています。また、submitボタンをクリックした時点でフォームが送信されます。"name"はそのボタンに対する名づけをしており、view側で何をコピーすれば良いか識別するために記述しています。最後に"value"では、ボタンを押下した際に送信したい文字列を指定しています。ここでは、for文で繰り返し出力できるようにしている"word"という変数をしています。

コピーをするために必要なモジュールをインストールする

 Pythonでクリップボードを操作するために、「pyperclip」と呼ばれる外部モジュールを使用します。このモジュールはPython標準ではないため個別にインストールを行う必要があります。
 pyperclip はpipコマンドでインストール可能です。

$ pip install pyperclip

viewで処理を記述する。

# views.py
import pyperclip
def detail_func(request, pk):
    #ページを表示させる記述は省略
    .....
    .....
    .....
    if request.method == "POST":
        if "copy_word" in request.POST:
          pyperclip.copy(request.POST["copy_word"])

    .....

 view側では、送られてきたリクエストのhttpメソッドが"POST"だった場合の条件分岐をし、その中で実際の処理を記載していきます。

if "copy_word" in request.POST:

 こちらでは、もし送られてきたPOSTのリクエストの中にcopy_wordという名前のものがあればという条件分岐をしています。"copy_word"とはテンプレート側のinputタグで記載したものです。つまり、この条件分岐によって、送られてきたリクエストがコピーをするものなのかを識別しているということです。

pyperclip.copy(request.POST["copy_word"]

 ここで、実際コピーを行うためにpyperclipを使用します。pyperclip.copy()を使用することで簡単にクリップボードにコピーを行うことができます。引数に request.POST["copy_word"]を記述することで、送信されてきたPOSTメソッドのリクエストの中でも"copy_word"という名前のvalueを取得することができます。こうすることで、ボタンを押した箇所のvalueが自動的に格納され、その文字列がクリップボードにコピーされるのです。

さいごに

 以上が、今回私の実装したテンプレートに表示したオブジェクトの文字列をクリップボードにコピーする方法です。今回の実装では、クリップボードにコピーする方法だけではなく、htmlのformタグの仕組みについても詳しく知ることができました!また、views.pyにおけるrequestの用途も知ることができました!!

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?