レストランリストの一覧から、エリア(例:渋谷など)で、該当するものだけを表示するようにしたいです。
不足情報などございましたら、随時加筆いたしますので、ご指摘頂けますと幸いです。
レストランを食べログ的にリスト表示するものをオリジナルで作ろうとしていました。
リストを無造作にリスト表示するところはできていたので、それを、条件で絞って表示できるようにアップデートしようとしております。
その条件絞り表示(つまりは検索機能)については、こちらの方のブログを参照しながらつくっていましたが、思い描いた挙動をしてくれませんでした。
DjangoでListViewを用いて検索画面を実装する方法 - 知的好奇心
エリア選択画面 tableplanner/select
(仮画面につき、レイアウトなどが、滅茶苦茶なのはご容赦ください......)
この「エリア」ラベルが付いている検索窓に「渋谷」だとか「新宿」だとか入れたら、
下部、「検索結果が存在しません」になっているところに、お店を表示するイメージで作っております。
しかし、渋谷と入れようと、新宿と入れようと、それらエリアに紐づけてあるid("2"だとか"5"だとか)を直接打ち込もうと、
「検索結果が存在しません」のままになってしまいます。
エラー文が、ワーっと吐き出されるのであればよいのですが、そういうわけでもないので困りました。
なにぶん、visual studio自体も初心者なため、デバッグやらステップ実行で原因突き止めるやり方も今ひとつわかっておらず、
したがって、裏側のどこに原因があるのか自体、ちょっと不明なまま質問投稿をしてしまっております。
ですので、ドンピシャのご回答でなくとも、原因突き止めるお力添えをいただけると非常に嬉しいです。
djando内、model, view, template
python
1#models.py 2from django.db import models 3from django.urls import reverse 4from django.core.validators import RegexValidator 5 6class restaurantGenre(models.Model): 7 restaurantGenre = models.TextField() 8 9 def __str__(self): 10 return self.restaurantGenre 11 12 13class restaurantArea(models.Model): 14 restaurantArea = models.TextField() 15 16 def __str__(self): 17 return self.restaurantArea 18 19class restaurantDetail(models.Model): 20 restaurantImg = models.FileField(verbose_name='店舗写真') 21 restaurantName = models.TextField(verbose_name='店名') 22 tel_number_regex = RegexValidator(regex=r'^[0-9]+$', message = ("Tel Number must be entered in the format: '09012345678'. Up to 15 digits allowed.")) 23 restaurantTelephone = models.CharField(validators=[tel_number_regex], max_length=15,verbose_name='電話番号', default=000000000) 24 restaurantLocationAddress = models.TextField(verbose_name='住所') 25 restaurantHomepageAddress = models.URLField(verbose_name='URL') 26 restaurantRate = models.PositiveIntegerField(verbose_name='レート') 27 restaurantCopywriting = models.TextField(verbose_name='一言コピー', default="一言コピーエリア") 28 restaurantDetailArea = models.ForeignKey(restaurantArea, verbose_name='エリア', on_delete=models.PROTECT, default=1) 29 restaurantDetailGenre = models.ForeignKey(restaurantGenre, verbose_name='ジャンル', on_delete=models.PROTECT, default=1) 30 restaurantBlog = models.TextField(verbose_name='お店紹介', default='ここにお店を紹介する文章が入ります。') 31 32 33 def __str__(self): 34 return self.restaurantName 35 36 def get_absolute_url(self): 37 return reverse("search:index") 38
Python
1#views.py ※更新につき、削除しました。 2
html
1#selectArea.html ※更新につき、削除しました。
restaurantAreaのデータベース仮データ中身
上図のidは、こちらのAreaリストと対応して引っ張っていくようになっています。
「ここのリンクミスかな?」と検索窓に"2"とか"5"とか入れてみましたが、特に効果ありませんでした。
なお、開発環境は以下の通りです。
言語:python3.7.4 フレームワーク:django 2.0.6 ブラウザ:Google Chrome 77 エディタ:visual studio code 1.38 OS:Windows10 home
以下、2019/10/3追記**
views.pyにloggingモジュールを仕込んで、挙動を見てみました。
それでわかったのは、def文の1個目2個目は問題なく出力してくれており、
変数も差し支えなく渡されている模様でした。
しかし、def文の3個目は、どうにも動いてくれすらしていないようでした。
具体的には、以下のようにLoggingを仕込んだ結果、'Test3'と書かれたものが出力されませんでした。
Python
1#views.py ※更新につき、削除しました。 2
ちなみに、仮にフォームに「渋谷」と書いた場合の出力は、
それぞれ以下のように出力されており、ちゃんと受け渡されている模様です。
console
1logger.info(form_value) -> ['渋谷'] 2logger.info(default_data) -> {'area': '渋谷'} 3logger.info(test_form) -> <tr><th><label for="id_area">エリア:</label></th><td><input type="text" name="area" value="渋谷" required id="id_area"></td></tr> 4logger.info(q_context) -> {'view': <restaurantsList.views.selectView object at 0x04734F50>, 'test_form': <searchForm bound=False, valid=False, fields=(area)>}
となると、def get_queryset(self):に該当する部分に問題があるということになるかと思うのですが、
それ以前に動きすらしていないので、原因がわからず......
以下、2019/10/3 夕方追記
@t_obaraさん、引き続きありがとうございます!
いただいたurl拝見しました。
get、get_queryset、get_context_dataの違いについて。
TemplateViewでは、get_querysetがを放ったらかしておくと動いてくれないものなのですね。
python
1class selectView(ListView):
に修正の上、以下を直しました。
(1)"area"という変数を新たにつくってしまっていたことによるエラー
->既存のmodel.pyに準じて、全て"restaurantDetailArea"に修正。
(2)len(restaurantDetailArea)のデフォルト値が、Noneであり、
'NoneType' has no len()エラーを起こす。
->if文で、Noneのときは、無視する条件文を追記することでクリア。
しかし、queryに関する部分のエラーは乗り越えられませんでした......
まず、現状のViews.py(該当のclassのみ)は以下の通りです。
python
1#views.py ※更新につき、削除しました。 2
エラー文は、以下のとおりです。
console
1Related Field got invalid lookup: icontains
明確に該当部分のエラーだとはわかりつつも、ググって出てくる情報に、
日本語のものがいつも以上に少なく、理解に苦しんでいます。。。
まずは、経過だけ書かせていただき、一休みしたらもうワントライしてみます。
以下、2019/10/6 深夜追記
半泣きになりながら調べては試し、失敗してはまた調べを続けて、ようやっとゴールに近づいてきた感じがします......!
「プルダウンメニューをつくる」「postメソッドで値を返す」そこまではできているのです。
あとは、参照した値に応じてフィルターをかけるだけなのですが、そこでエラーが起きてしまいます......
python
1#forms.py 2from django import forms 3from .models import restaurantDetail, restaurantArea, restaurantGenre 4 5areaChoices = [ 6 (1, '中目黒'), 7 (2, '渋谷'), 8 (3, '新宿'), 9 (4, '恵比寿'), 10 (5, '品川'), 11] 12 13class selectForm(forms.Form): 14 area = forms.ChoiceField( 15 label="エリア", 16 required=True, 17 disabled=False, 18 initial=['1'], 19 choices=areaChoices, 20 )
python
1#views.py 2class selectView(ListView): 3 model = restaurantDetail 4 template_name = 'areaSelect.html' 5 6 def get(self, request): 7 f = {'form': selectForm(),} 8 return render(request, 'areaSelect.html', f) 9 10 def post(self, *args, **kwargs): 11 return self.get_queryset(self) 12 13 def get_queryset(self, request): 14 if self.request.method == 'POST': 15 form_selected = [] 16 form_selected.append(self.request.POST.get('area')) 17 form_selected_num = form_selected[0] 18 return restaurantDetail.objects.filter(restaurantDetailArea=form_selected_num) 19 else: 20 d = {'form': selectForm(),} 21 return render(request, 'areaSelect.html', d)
上記コードを動かすと、
console
1too many values to unpack (expected 2)
というエラー文が返ってきてしまいます。
なお、上記からは削除しましたが、
loggingを随所に差し込んで、
form_selected_num = form_selected[0]
までは、値のリレーが思惑通りOKな様子も確認できています。
このエラー文について、他の方の投稿などを拝見するに、
python
1#views.py 2return restaurantDetail.objects.filter(restaurantDetailArea=form_selected_num)
ここの書き方で、引数(上記の場合"restaurantDetailArea")を書きそびれた結果起きているように見受けられます。
しかし、じぶんのコードの場合そこは満たしており、実際直前に別の形でこのfilterだけを動かしていた内は、問題なく稼働していました。
あまり見受けられない書き方でいうと
python
1#views.py 2 def post(self, *args, **kwargs): 3 return self.get_queryset(self)```
この部分が原因かなとも思いつつ、確証はありません。
ここまで来たら、なんとかしたいです!
ので、違和感ある箇所などあれば、ご指摘頂けますと幸いです......!!
あなたの回答
tips
プレビュー