質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1215閲覧

django データベースのテキストをテンプレートで一部表示する方法

hiroikawa55

総合スコア26

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/03/17 14:24

編集2020/03/29 13:36

Djangoで、データベースの①テキストを検索し(Filterをかける)、②抽出されたテキストについて、さらに③検索語の含まれる文('。'で区切られた、検索語の含まれる文)を示す方法を探しています。
○動作の例
①検索(フィルター):「蛍」
テキストを抽出「春はあけぼの。やうやう白くなりゆく山際、少し明かりて、紫だちたる雲の細くたなびきたる。夏は夜。月のころはさらなり、闇もなほ、蛍の多く飛びちがひたる。また、ただ一つ二つなど、ほのかにうち光て行くもをかし。雨など降るもをかし。」
③検索語の含まれる文を示す「月のころはさらなり、闇もなほ、蛍の多く飛びちがひたる。」
Templateタグを利用して、下記のようなプログラムをつくりました。
ただ、item_filter.htmlで検索語を関数(filter_age)に渡そうとしても、検索語が特定できずに足踏みをしています。
"filter"
form
等、片っ端から試してみたのですが、うまくいっていません(下のプログラムでは"filter"を入れていますが、動かしても検索語が含まれる文を表示するところまでは至っていません。
下記のページを読んでも、方法がわからず、お伺いする次第です。どうぞよろしくお願いいたします。
https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/

python

1#templatetags/item_extras.py 2from django import template 3from django.template.defaultfilters import stringfilter 4register = template.Library() 5 6@register.filter 7@stringfilter 8def filter_age(value1, value2): 9 s = value1 10 f = '\n'.join(s.splitlines()) 11 s_l = f.split('。') 12 word = value2 13 for i in s_l: 14 if word in i: 15 return i

python

1{% extends "./_base.html" %} 2{% block content %} 3{% load crispy_forms_tags %} 4<div class="container"> 5 <div id="myModal" class="modal fade" tabindex="-1" role="dialog"> 6 <div class="modal-dialog" role="document"> 7 <div class="modal-content"> 8 <div class="modal-header"> 9 <h5 class="modal-title">検索条件</h5> 10 <button type="button" class="close" data-dismiss="modal" aria-label="閉じる"> 11 <span aria-hidden="true">&times;</span> 12 </button> 13 </div> 14 <form id="filter" method="get"> 15 <div class="modal-body"> 16 {{filter.form|crispy}} 17 </div> 18 </form> 19 <div class="modal-footer"> 20 <a class="btn btn-outline-secondary" data-dismiss="modal">戻る</a> 21 <button type="submit" class="btn btn-outline-secondary" form="filter">検索</button> 22 </div> 23 </div> 24 </div> 25 </div> 26 <div class="row"> 27 <div class="col-12"> 28 <a class="btn btn-secondary filtered" style="visibility:hidden" href="/?page=1">検索を解除</a> 29 <div class="float-right"> 30 <a class="btn btn-outline-secondary" href="{% url 'create' %}">新規</a> 31 <a class="btn btn-outline-secondary" data-toggle="modal" data-target="#myModal" href="#">検索</a> 32 </div> 33 </div> 34 </div> 35 36 <div class="row" > 37 <div class="col-12"> 38 {% include "./_pagination.html" %} 39 </div> 40 </div> 41 <div class="row"> 42 <ul class="list-group"> 43 {% for item in item_list %} 44 <li class="list-group-item"> 45 <div class="row"> 46 <div class="col-3"> 47 <p>名称</p> 48 </div> 49 <div class="col-9"> 50 <p>{{ item.name }}</p> 51 </div> 52 </div> 53 <div class="row"> 54 <div class="col-3"> 55 <p></p> 56 </div> 57 <div class="col-9"> 58 {% load item_extras %} 59 <p>{{ item.age | filter_age:"filter" }}</p> 60 </div> 61 </div> 62 <div class="row"> 63 <div class="col-12"> 64 <div class="float-right"> 65 <a class="btn btn-outline-secondary " href="{% url 'detail' item.pk %}">詳細</a> 66 <a class="btn btn-outline-secondary " href="{% url 'update' item.pk %}">編集</a> 67 <a class="btn btn-outline-secondary " href="{% url 'delete' item.pk %}">削除</a> 68 </div> 69 </div> 70 </div> 71 </li> 72 {% empty %} 73 <li class="list-group-item"> 74 対象のデータがありません 75 </li> 76 {% endfor %} 77 </ul> 78 </div> 79 </div> 80 <div class="row" > 81 <div class="col-12"> 82 <div class="float-right"> 83 <a class="btn btn-outline-secondary" href="{% url 'create' %}">新規</a> 84 <a class="btn btn-outline-secondary" data-toggle="modal" data-target="#myModal" href="#">検索</a> 85 </div> 86 </div> 87 </div> 88</div> 89{% endblock %}

python

1from django.contrib.auth.mixins import LoginRequiredMixin 2from django.urls import reverse_lazy 3from django.views.generic import DetailView 4from django.views.generic.edit import CreateView, UpdateView, DeleteView 5from django_filters.views import FilterView 6 7from .filters import ItemFilter 8from .forms import ItemForm 9from .models import Item 10 11# Create your views here. 12# 検索一覧画面 13class ItemFilterView(LoginRequiredMixin, FilterView): 14 model = Item 15 16 # django-filter用設定 17 filterset_class = ItemFilter 18 strict = False 19 20 # 1ページあたりの表示件数 21 paginate_by = 10 22 23 # 検索条件をセッションに保存する 24 def get(self, request, **kwargs): 25 if request.GET: 26 request.session['query'] = request.GET 27 else: 28 request.GET = request.GET.copy() 29 if 'query' in request.session.keys(): 30 for key in request.session['query'].keys(): 31 request.GET[key] = request.session['query'][key] 32 33 return super().get(request, **kwargs) 34 35 36# 詳細画面 37class ItemDetailView(LoginRequiredMixin, DetailView): 38 model = Item 39 40 41# 登録画面 42class ItemCreateView(LoginRequiredMixin, CreateView): 43 model = Item 44 form_class = ItemForm 45 success_url = reverse_lazy('index') 46 47 48# 更新画面 49class ItemUpdateView(LoginRequiredMixin, UpdateView): 50 model = Item 51 form_class = ItemForm 52 success_url = reverse_lazy('index') 53 54 55# 削除画面 56class ItemDeleteView(LoginRequiredMixin, DeleteView): 57 model = Item 58 success_url = reverse_lazy('index') 59

html

1{% extends "./_base.html" %} 2{% load crispy_forms_tags %} 3{% block content %} 4{{ form.certifications.errors }} 5<div class="container"> 6 <div class="row"> 7 <div class="col-12"> 8 <h2 class="text-center">データ入力</h2> 9 </div> 10 </div> 11 <div class="row"> 12 <div class="col-12"> 13 <div class="float-right"> 14 <a class="btn btn-outline-secondary" href="{% url 'index' %}">戻る</a> 15 <a class="btn btn-outline-secondary save" href="#">保存</a> 16 </div> 17 </div> 18 </div> 19 <div class="row"> 20 <div class="col-12"> 21 <form method="post" id="myform"> 22 {%crispy form%} 23 </form> 24 </div> 25 </div> 26 <div class="row"> 27 <div class="col-12"> 28 <div class="float-right"> 29 <a class="btn btn-outline-secondary" href="{% url 'index' %}">戻る</a> 30 <a class="btn btn-outline-secondary save" href="#">保存</a> 31 </div> 32 </div> 33 </div> 34</div> 35{% endblock %}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

llr114

2020/03/20 08:47

views.pyの内容はどのようになっていますでしょうか? もしくはそもそも、views.pyを使わずに、Models.pyからテンプレートに出力したいということでしょうか?
hiroikawa55

2020/03/20 13:00

実は、views.pyを使おうと、あれこれ余所のページをみて、 def my_function(self): s = 'ここに、データベースの値をいれる。句読点で、文を区切る。' s_l = s.split('。') if request.method == "GET": form = ItemForm(request.GET) if form.is_valid(): d = form.cleaned_data['rows'] for i in s_l: if d in i: return render(request,'',{'rows':d,},) のように見よう見まねで、コードを追記してみたのですが、 こちらは出力の兆候すらなく、Models.pyからテンプレートに出力した方が、とりあえずなにか動いた、という体で、Models.pyから出力をした次第です・・。
llr114

2020/03/20 17:11

状況把握しました。 views.pyでクラスビューを使うのが慣れてしまえば一番楽かと思います。 https://qiita.com/felyce/items/7d0187485cad4418c073 今回のケースですが、やりたいこととしては フォームに入力→文字を含むものを検索→出力 ということでしょうか?
hiroikawa55

2020/03/21 12:41

お礼が遅くなり、申し訳ありません。クラスビューのページ、本当に参考になります。 やりたかったことの大枠をつかむことができました。 ああ、こういうことだったのか・・と、腑に落ちる感覚で、がんばれそうです。 やりたかったことは、ご推察の通り、フォームに入力→文字を含むものを検索→出力です。 早速、教えいていただいたViews関数で、試行錯誤を進めたいと思います。
llr114

2020/03/22 09:46

お力になれて何よりです。 また何かございましたら、お気軽にご質問ください。
hiroikawa55

2020/03/28 16:14

Templateタグを利用して、検索する方法がわかり、もうすこしでできるところまで近づいたのですが、最後のところで躓いています。
llr114

2020/03/28 18:08

該当するview.pyの追記をお願い致します。
hiroikawa55

2020/03/29 02:16

ご連絡、ありがとうございます。なるほど、views.pyに検索条件がセッションに保存されているので、その値を使えばいいのか!と思い、 'query' ['query'] [key] 'key' をItem.filter.html {{ item.age | filter_age:'key'}} に入れてみたのですが、うまくいきませんでした・・。 すみません、クエリの理解が足りないようです。
llr114

2020/03/29 10:10

{{filter.form|crispy}} で、検索用のボックスを表示するという認識で間違いないでしょうか? その場合、生成された<input>のnameが何になっているのかを知りたいです。
hiroikawa55

2020/03/29 13:43

その通りなのですが、生成された<input>nameの確認方法がわからず、お伺いする次第です。 appフォルダには下記のhtmlファイルを作成しています。 _base.html _pagination.html index.html item_card.html item_confirm_delete.html item_detail.html item_filter.html item_form.html
llr114

2020/03/29 13:48

ChromeやsafariでWebサイトの検証モードはご存知でしょうか? https://ferret-plus.com/1880 それで該当するinputを確認すれば、nameがあれば書いているはずです。
hiroikawa55

2020/03/29 14:10

すみません、理解しました。 input を表示したところ、下記のようになっていました。 "検索語"→入力した値です。 </label> <div class=""> <input type="text" name="age" value="検索語" class="textinput textInput form-control" id="id_age"> </div> </div> <div id="div_id_order_by" class="form-group"> <label for="id_order_by" class="col-form-label ">
llr114

2020/03/29 14:47

有難うございます。 とすると、検索のために取得したいものはageでよろしいでしょうか?
hiroikawa55

2020/03/29 23:12

はい、そうです。 お教え頂いたことをヒントに、 "id_age" "value" などを値にいれてみたのですが、うまくいきませんでした。 ひとつひとつの理解が追いついておらず、お手数をお掛けします・・。
llr114

2020/03/30 02:25

それでしたら、 def get(self, request, **kwargs): if request.GET: request.session['query'] = request.GET.get('age') のように request.GET.get('age')を指定すれば取得できると思いますが、いかがでしょうか?
hiroikawa55

2020/03/30 07:23

ありがとうございます。 早速 views.pyで、 def get(self, request, **kwargs): if request.GET: request.session['query'] = request.GET.get('age') を指定し、 item_filter.htmlに、下記のように入れてみたのですが、 <p>{{ item.age | filter_age:'age' }}</p> 下記のエラーが出てしまい、 AttributeError at / 'str' object has no attribute 'keys' 目下、原因を特定中です。
hiroikawa55

2020/03/30 12:45

views.pyの ーーーーーーーーーー else: request.GET = request.GET.copy() if 'query' in request.session.keys(): for key in request.session['query'].keys(): request.GET[key] = request.session['query'][key] ーーーーーーーー を消去したところ、エラーが出なくなりました(根本的な解決ではないかもしれませんが)
llr114

2020/03/30 16:09

エラー文的にも for key in request.session['query'].keys(): の箇所かと思われます。 request.session['query']にkeysがないってエラーですね。 else:以降でやりたい処理はなんでしょうか?
hiroikawa55

2020/04/06 14:14

IIr114様 長きにわたり、お付き合いをいただき、ありがとうございました。 上記のコードは、 https://qiita.com/okoppe8/items/54eb105c9c94c0960f14 を参考とさせていただいておりまして、自分も意味がわからず、ここ1週間ほど、 あれこれ調べたところ、session(一時的なデータの保管?)のために付加されているのではないかと思われます。 ただ、やはり人のコードをそのままコピーして書き換えるだけでは、いつまでたってもDjangoの理解にはほど遠いことが、ここ数週間長々とコードと格闘してわかった次第です・・。あらてめてUdemyの講座で1から勉強してみたいと思います。 これまで、親切に教えていただき、本当にありがとうございました。 重ねて御礼申し上げます。
llr114

2020/04/06 16:29

ご丁寧にありがとうございます。 私もまだまだ勉強中の身ですが、また何かお力になれたらと思います。
guest

回答2

0

どのような結果が欲しいかを正確に理解していませんが、下記のようなことをしたいのでしょうか?

python

1text = """ 2春はあけぼの。やうやう白くなりゆく山際、少し明かりて、 3紫だちたる雲の細くたなびきたる。夏は夜。月のころはさ 4らなり、闇もなほ、蛍の多く飛びちがひたる。また、ただ 5一つ二つなど、ほのかにうち光て行くもをかし。雨など降 6るもをかし。 7""" 8print(f'text: {text}') 9 10keyword = '蛍' 11 12lines = [line for line in text.splitlines() if line] 13print(f'lines: {lines}') 14 15document = ''.join(lines) 16print(f'document: {document}') 17 18sentences = document.split('。') 19print(f'sentences: {sentences}') 20 21for s in sentences: 22 if keyword in s: 23 print(f'found: {s}。') 24 # found: 月のころはさらなり、闇もなほ、蛍の多く飛びちがひたる。

投稿2020/03/30 06:59

hasami

総合スコア1277

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiroikawa55

2020/03/30 07:05

ご回答の件、たいへんありがとうございます。 実行したいのは、お教えていただいたことです。 ただ目下引っかかっているのが、keywordに、djangoのformで入力した値を代入する方法でして、コメント欄を利用して、お力添えをいただいている状況です。
guest

0

ベストアンサー

Stack Overflowには、カンマ区切りの文字列で渡す方法が、回答にありました。
Djangoはテンプレートフィルタに1つの引数しか渡せないようです。

ドキュメントのサイズが大きい場合、テンプレートフィルタはあまり良い選択ではないような気がします。

How do I add multiple arguments to my custom template filter in a django template?

投稿2020/03/30 07:31

hasami

総合スコア1277

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiroikawa55

2020/03/30 12:50

ありがとうございます。引数を2つ渡しているようで、そうではないことがなんとなくわかりました。 イレギュラーなやり方をしていたようで、また方法を考えてみたいと思います。
hasami

2020/03/30 12:58

テンプレートタグであれば、複数の引数を渡すことができ、テンプレートフィルタよりも柔軟にコントロールできますので、よろしければ検討してみてください。
hiroikawa55

2020/04/06 14:10

お礼が遅くなり、申し訳ありません。テンプレートタグのことが完全にはわからず、解決には至っていないのですが、あらためてdjangoのことを勉強しなおして、再度問題に取り組みたいと思います。
hasami

2020/04/06 14:29

テンプレートタグは、単に関数の様に実装できます。悪用もできますが...。 要件が合えば、テンプレートタグで処理するのではなく、レンダリングしたい内容をコンテキストで渡す方法もあると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問