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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

0回答

316閲覧

Djangoによる検索フォームの作成について (HTMLテンプレートへのフォームの表示方法)

pyon56_56

総合スコア0

Django

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2023/01/29 17:38

編集2023/01/29 23:10

前提

Windows11
Django4
Pyhton3.11

実現したいこと

1.検索フォームの作成
1)食品名を検索窓へ入力して検索ボタンをクリック。あいまい検索です。
2)検索結果の食品が検索ページと同じページ内(post_photo.html )に一覧で表示されるようにしたい。

Djangoを使ってWebサービスを開発しております。
下記サイトを参考に検索フォームを実装しようとしているのですが、検索窓がHTMLに組み込まれません。
ネットや書籍で検索フォームの作成について調べたのですがうまくできませんでした。

<参考にしているサイト>
12.Djangoに検索フォームを追加してみよう
https://denno-sekai.com/django-searchform/
<参考書籍>
Django4 Webアプリ開発実装ハンドブック--秀和システム

初めての質問で、要領を得ていなくて大変申し訳ないのですが、何卒よろしくお願い申し上げます。

発生している問題・エラーメッセージ

 検索ボタン、検索窓が表示されない

該当のソースコード

※base.htmlについては文字数制限のため記載できなかったため、コメントを頂いた yuma.inaura 様への返信欄へ書かせていただきました。

**_HTML_** post_photo.html {% extends 'base.html' %} {% block title %}Post{% endblock %} {% block search %} <h1>食品検索</h1> {% if searchForm %}<!-- searchFormがあれば --> <form action='{% url "photo:SearchView" %}' method="get"><!-- getメソッドでインデックス関数を呼び出す --> <div> {{ searchForm }}<!-- views.pyから受け取ったsearchFormを表示 --> <input type="submit" value="検索"> <a href='{% url "photo:SearchView" %}'>クリア</a><!-- postメソッドでインデックス関数を呼び出す --> </div> </form> {% endif %} {% for article in articles %} <p> {{ article.user_name }} </p> {% endfor %} {% endblock %} {% block contents %} <hr> <!-- Bootstrapのグリッドシステム --> <br> <div class="container"> <!-- 行を配置 --> <div class="row"> <div class="col offset-2"> <form method="POST" enctype="multipart/form-data"> {% csrf_token %} <table> <tr> <th>カテゴリ</th> <td>{{ form.category }}</td> </tr> <tr> <th>タイトル</th> <td>{{ form.title }}</td> </tr> <tr> <th>コメント</th> <td>{{ form.comment }}</td> </tr> <tr> <th>材料・分量(g)</th> <td>{{ form.foodandweight }}</td> </tr> <tr> <th>人数</th> <td>{{ form.ninzu }}</td> </tr> <th>つくりかた</th> <td>{{ form.howtomake }}</td> </tr> <tr> <th>画像1</th> <td>{{ form.image1 }}</td> </tr> <tr> <th>画像2</th> <td>{{ form.image2 }}</td> </tr> </table> <hr> <button type="submit">投稿する</button> </form> </dv> </dv> </dv> {% endblock %} **_Python Django_** **_models.py_** class FoodListVer8(models.Model): id = models.IntegerField("通番",primary_key=True) foodname = models.TextField("食品名") **_forms.py_** from django.forms import ModelForm from .models import PhotoPost from django import forms class PhotoPostForm(ModelForm): class Meta: model = PhotoPost fields = ['category', 'title', 'comment', 'foodandweight','ninzu', 'howtomake', 'image1', 'image2'] # SearchFormクラスを定義 class SearchForm(forms.Form): keyword = forms.CharField(label='', max_length=50) **_views.py_** from django.shortcuts import render,get_object_or_404 from django.views.generic import TemplateView, ListView from django.views.generic import CreateView from django.urls import reverse_lazy from .forms import PhotoPostForm, SearchForm from django.utils.decorators import method_decorator from django.contrib.auth.decorators import login_required from .models import PhotoPost,FoodListVer8 from django.views.generic import DetailView from django.views.generic import DeleteView from django.http import HttpResponse # 検索用ビュー def SearchView(request): searchForm = SearchForm(request.GET) # searchForm変数に正常なデータがあれば if searchForm.is_valid(): keyword = searchForm.cleaned_data['keyword'] articles = FoodListVer8.objects.filter(foodname__contains=keyword) # それ以外の場合 else: searchForm = SearchForm() # searchForm変数をSearchFormオブジェクトで上書き articles = FoodListVer8.objects.all() # すべてのレコードを取得 context = { 'articles': articles, 'searchForm': searchForm, # テンプレートに渡すために追記 } return render(request, 'post_photo.html', context) def detail(request, id): article = get_object_or_404(FoodListVer8, pk=id) context = { 'article': article, } return render(request, 'post_photo.html', context) class IndexView(ListView): '''トップページのビュー ''' # index.htmlをレンダリングする template_name ='index.html' # モデルBlogPostのオブジェクトにorder_by()を適用して # 投稿日時の降順で並べ替える queryset = PhotoPost.objects.order_by('-posted_at') # 1ページに表示するレコードの件数 paginate_by = 9 @method_decorator(login_required, name='dispatch') class CreatePhotoView(CreateView): '''写真投稿ページのビュー # forms.pyのPhotoPostFormをフォームクラスとして登録 form_class = PhotoPostForm # レンダリングするテンプレート template_name = "post_photo.html" # フォームデータ登録完了後のリダイレクト先 success_url = reverse_lazy('photo:post_done') def form_valid(self, form): '''CreateViewクラスのform_valid()をオーバーライド フォームのバリデーションを通過したときに呼ばれる フォームデータの登録をここで行う parameters: form(django.forms.Form): form_classに格納されているPhotoPostFormオブジェクト Return: HttpResponseRedirectオブジェクト: スーパークラスのform_valid()の戻り値を返すことで、 success_urlで設定されているURLにリダイレクトさせる ''' # commit=FalseにしてPOSTされたデータを取得 postdata = form.save(commit=False) # 投稿ユーザーのidを取得してモデルのuserフィールドに格納 postdata.user = self.request.user # 投稿データをデータベースに登録 postdata.save() # 戻り値はスーパークラスのform_valid()の戻り値(HttpResponseRedirect) return super().form_valid(form) class PostSuccessView(TemplateView): '''投稿完了ページのビュー Attributes: template_name: レンダリングするテンプレート ''' # index.htmlをレンダリングする template_name ='post_success.html' class CategoryView(ListView): '''カテゴリページのビュー Attributes: template_name: レンダリングするテンプレート paginate_by: 1ページに表示するレコードの件数 ''' # index.htmlをレンダリングする template_name ='index.html' # 1ページに表示するレコードの件数 paginate_by = 9 def get_queryset(self): '''クエリを実行する self.kwargsの取得が必要なため、クラス変数querysetではなく、 get_queryset()のオーバーライドによりクエリを実行する Returns: クエリによって取得されたレコード ''' # self.kwargsでキーワードの辞書を取得し、 # categoryキーの値(Categorysテーブルのid)を取得 category_id = self.kwargs['category'] # filter(フィールド名=id)で絞り込む categories = PhotoPost.objects.filter( category=category_id).order_by('-posted_at') # クエリによって取得されたレコードを返す return categories class UserView(ListView): '''ユーザーの投稿一覧ページのビュー Attributes: template_name: レンダリングするテンプレート paginate_by: 1ページに表示するレコードの件数 ''' # index.htmlをレンダリングする template_name ='index.html' # 1ページに表示するレコードの件数 paginate_by = 9 def get_queryset(self): '''クエリを実行する self.kwargsの取得が必要なため、クラス変数querysetではなく、 get_queryset()のオーバーライドによりクエリを実行する Returns: クエリによって取得されたレコード ''' # self.kwargsでキーワードの辞書を取得し、 # userキーの値(ユーザーテーブルのid)を取得 user_id = self.kwargs['user'] # filter(フィールド名=id)で絞り込む user_list = PhotoPost.objects.filter( user=user_id).order_by('-posted_at') # クエリによって取得されたレコードを返す return user_list class DetailView(DetailView): '''詳細ページのビュー 投稿記事の詳細を表示するのでDetailViewを継承する Attributes: template_name: レンダリングするテンプレート model: モデルのクラス ''' # post.htmlをレンダリングする template_name ='detail.html' # クラス変数modelにモデルBlogPostを設定 model = PhotoPost class MypageView(ListView): '''マイページのビュー Attributes: template_name: レンダリングするテンプレート paginate_by: 1ページに表示するレコードの件数 ''' # mypage.htmlをレンダリングする template_name ='mypage.html' # 1ページに表示するレコードの件数 paginate_by = 9 def get_queryset(self): '''クエリを実行する self.kwargsの取得が必要なため、クラス変数querysetではなく、 get_queryset()のオーバーライドによりクエリを実行する Returns: クエリによって取得されたレコード ''' # 現在ログインしているユーザー名はHttpRequest.userに格納されている # filter(userフィールド=userオブジェクト)で絞り込む queryset = PhotoPost.objects.filter( user=self.request.user).order_by('-posted_at') # クエリによって取得されたレコードを返す return queryset class PhotoDeleteView(DeleteView): '''レコードの削除を行うビュー Attributes: model: モデル template_name: レンダリングするテンプレート paginate_by: 1ページに表示するレコードの件数 success_url: 削除完了後のリダイレクト先のURL ''' # 操作の対象はPhotoPostモデル model = PhotoPost # photo_delete.htmlをレンダリングする template_name ='photo_delete.html' # 処理完了後にマイページにリダイレクト success_url = reverse_lazy('photo:mypage') def delete(self, request, *args, **kwargs): '''レコードの削除を行う Parameters: self: PhotoDeleteViewオブジェクト request: WSGIRequest(HttpRequest)オブジェクト args: 引数として渡される辞書(dict) kwargs: キーワード付きの辞書(dict) {'pk': 21}のようにレコードのidが渡される Returns: HttpResponseRedirect(success_url)を返して success_urlにリダイレクト ''' # スーパークラスのdelete()を実行 return super().delete(request, *args, **kwargs) --------------------------------------------- ### 試したこと 書籍、ネットで検索フォームについて多々調べましたが、うまくできませんでした。 ### 補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

yuma.inaura

2023/01/29 19:00

base.html は空白なんですか?
pyon56_56

2023/01/29 23:06

お世話になります。 早々にコメントを頂きありがとうございます。 大変申し訳ありません。 実はbase.htmlについては文字数制限のため、追加できませんでした。 こちらに記載させていただきます。 どうぞよろしくお願い申し上げます。 base.html {% load static %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.84.0"> <!-- ヘッダー情報のタイトルを個別に設定できるようにする--> <title>{% block title %}{% endblock %}</title> <!-- staticでfavicon.icoのURLを生成する --> <link rel="icon" type="image/x-icon"    href={% static 'assets/favicon.ico' %} />    <!-- Bootstrap core CSS --> <!-- Bootstrap core CSSを読み込むコードをBootstrapからコピー--> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <style> .bd-placeholder-img { font-size: 1.125rem; text-anchor: middle; -webkit-user-select: none; -moz-user-select: none; user-select: none; } @media (min-width: 768px) { .bd-placeholder-img-lg { font-size: 3.5rem; } } </style> </head> <body> <!-- ページのヘッダー--> <header> <!-- ナビゲーションバーのヘッダー--> <div class="collapse bg-dark" id="navbarHeader"> <div class="container"> <div class="row"> <div class="col-sm-8 col-md-7 py-4"> <!-- ヘッダーのタイトルと本文--> <h4 class="text-white">お気に入りを見つけよう!</h4> <p class="text-muted"> 誰でも参加できる写真投稿サイトです。 </p> </div> <div class="col-sm-4 offset-md-1 py-4"> <h4 class="text-white">Contact</h4> <ul class="list-unstyled"> <!-- ナビゲーションメニュー--> {% if user.is_authenticated %} <!-- ログイン中のメニュー--> <li><a href="{% url 'photo:mypage' %}" class="text-white">マイページ</a></li> <li><a href="{% url 'accounts:logout' %}" class="text-white">ログアウト</a></li> <li><a href="{% url 'password_reset' %}" class="text-white">パスワードのリセット</a></li> <li><a href="mailto:admin@example.com" class="text-white">Email me</a></li> {% else %} <!-- ログイン状態ではない場合のメニュー--> <li><a href="{% url 'accounts:signup' %}" class="text-white">サインアップ</a></li> <li><a href="{% url 'accounts:login' %}" class="text-white">ログイン</a></li> <li><a href="mailto:admin@example.com" class="text-white">Email me</a></li> {% endif %} </ul> </div> </div> </div> </div> <!-- ナビゲーションバー--> <div class="navbar navbar-dark bg-dark shadow-sm"> <div class="container"> <!-- トップページへのリンク--> <a href="{% url 'photo:index' %}" class="navbar-brand d-flex align-items-center"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" class="me-2" viewBox="0 0 24 24"> <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" /> <circle cx="12" cy="13" r="4" /> </svg> <!-- リンクテキスト--> <strong>Photo Gallery</strong> </a> <!-- トグルボタン--> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> </div> </div> </header> <!-- メインコンテンツ--> <main> <!-- <main>タグの要素をすべて削除して以下に書き換え--> <!-- メインコンテンツの本体部分は各ページのテンプレートで埋め込む--> {% block search %}{% endblock %} {% block contents %}{% endblock %} </main> <!-- フッター --> <footer class="text-muted py-5"> <div class="container"> <p class="float-end mb-1"> <a href="#">Back to top</a> </p> <!-- フッターのテキストを任意のものに書き換え--> <p class="mb-1"> Photo Gallery is &copy; Bootstrap, but please post a lot!</p> </div> </footer> <!-- BootstrapからJavaScriptを読み込むコードをコピーして貼り付け--> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> </body> </html>
yuma.inaura

2023/01/30 10:01

searchFormがnullだったりするんでしょうか if判定が成功してない状態ですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問