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

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

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

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

Python 3.x

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

Python

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

Q&A

解決済

1回答

389閲覧

python、djangoでプライマリーキーごとにコメントページを作りたい

sr2460

総合スコア49

Django

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

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2018/12/07 11:20

編集2018/12/08 12:01

前提・実現したいこと

python=3.7.0
django=(2, 0, 2, 'final', 0)

の環境で開発しています。

プライマリーキーごとにコメントページを作りたいと思っているのですが実際にはurlの数値が変わっても同じページに飛んでしまいます。

URLが/4/commentでフォームを送信したコメントはURLが/4/comment_listの結果ページで表示されるようにしたい。
![イメージ説明]
イメージ説明

URLが/5/commentでフォームを送信したコメントはURLが/5/comment_listの結果ページで表示されるようにしたい。
イメージ説明
イメージ説明

フォーム部分に関して。models.pyはこのようになっております。

python

1class Comment(models.Model): 2 question = models.ForeignKey(Question, on_delete=models.PROTECT, default=1) 3 kansou = models.TextField('コメント', blank=True, null=True)

forms.pyは

python

1class CommentForm(forms.ModelForm): 2 3 class Meta: 4 model = Comment 5 fields ="__all__"

本来はfields =('kansou',)としなくてはならないのですが現在は試行錯誤の段階のためallにしております。

python

1def commentview(request, pk): 2 comment = get_object_or_404(Question, pk=pk) 3 form = CommentForm(request.POST or None) 4 if request.method == 'POST' and form.is_valid(): 5 form.save() 6 return redirect('polls:comment_list', comment.pk) 7 context = { 8 'form': form 9 } 10 return render(request, 'polls/comment_form.html', context) 11

views.pyでこのように記載されております。
このようにしてフォームを動かしています。
ただ前述の通りURLが変わっても同じコメントが表示されてしまいます。

試したこと

実験①

views.pyをここから

python

1def commentlist(request, pk): 2 comment = get_object_or_404(Question, pk=pk) 3 context = { 4 'comment_ichiran':Comment.objects.all(), 5 } 6 return render(request, 'polls/comment_list.html', context)

python

1def commentlist(request, pk): 2 comment = get_object_or_404(Question, pk=pk) 3 context = { 4 'comment_ichiran':Comment.objects.filter(pk=pk),**←変更部分** 5 } 6 return render(request, 'polls/comment_list.html', context)

としましたがすべてにフィルターがかかってしまいコメントページでなにも見られなくなってしまいました。
(HTTP/1.1" 200 313)と表示されているのでエラーではありませんでした。

実験②

コメントの一覧表示ページのコードここから

python

1{% for list in comment_ichiran %} 2 3 <h2>{{ list.kansou }}</h2> 4 5{% endfor %}

このように変更しました

python

1{% for list in question.comment_set.all %}←変更部分 2 3 <h2>{{ list.kansou }}</h2> 4 5{% endfor %} 6

しかし結果は先ほどと同じでエラーは出ないもののなにも表示されません。
情報が足りなければ適宜補足いたします。
アドバイスがあればお願いいたします。

ご指摘を受けコードを追加いたしました

これがcommentに紐づくQuestionのコードになります。
models.py

class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') def was_published_recently(self): now = timezone.now() return now - datetime.timedelta(days=1) <= self.pub_date <= now was_published_recently.admin_order_field = 'pub_date' was_published_recently.boolean = True was_published_recently.short_description = 'Published recently?'

またurlに関してはint:pk/comment/でコメントフォームを表示しint:pk/comment_list/でフォームで送ったコメントの一覧に遷移するようにしています。

urls.py

python

1from django.urls import path 2 3from . import views 4 5app_name = 'polls' 6urlpatterns = [ 7 path('', views.IndexView.as_view(), name='index'), 8 path('<int:pk>/', views.DetailView.as_view(), name='detail'), 9 path('<int:pk>/results/', views.ResultsView.as_view(), name='results'), 10 path('<int:question_id>/vote/', views.vote, name='vote'), 11 path('<int:pk>/comment/', views.CommentView.as_view(), name='comment'), 12 path('<int:pk>/comment_list/', views.commentlist, name='comment_list'), 13]

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

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

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

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

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

guest

回答1

0

ベストアンサー

おそらく次の 2 つをお載せになった方が具体的な回答がもらえやすくなるのではないかと思います。

  1. Comment から参照されている Question モデルの定義
  2. 関連するルーティング( urlconf )の設定

とはいえ、現在ご共有いただたいている情報の範囲でわかる部分もありますので、その点だけコメントさせていただきますね。

まず、ここで言う「プライマリーキー」( pk )がどのモデルのものなのかを整理されるとよいかと思います( Question のプライマリーキーと Comment のプライマリーキーでは意味がまったく異なります)。

python

1def commentlist(request, pk): 2 comment = get_object_or_404(Question, pk=pk) 3 context = { 4 'comment_ichiran':Comment.objects.filter(pk=pk),**←変更部分** 5 } 6 return render(request, 'polls/comment_list.html', context)

上のコードだと、関数の引数である(おそらく URL パラメータでもある) pkQuestion のものなのか Comment のものなのかがはっきりしません。

加えて、 get_object_or_404(Question, pk=pk) の戻り値は Question のインスタンスかと思いますので、それに comment という名前をあてるのは混乱のもとになるかと思います。

ですので、例えば、仮に pkQuestion のものであるなら comentlist は次のように書いた方がよいと思います。

python

1def commentlist(request, pk): 2 # 変更点 1. 変数名を変更: `comment` → `question` 3 question = get_object_or_404(Question, pk=pk) 4 context = { 5 # 変更点 2. `filter()` の引数を変更 6 'comment_ichiran':Comment.objects.filter(question=question), 7 } 8 return render(request, 'polls/comment_list.html', context)

一般論として、特定の qustion にひもづく Comment の一覧を取得したい場合は次のようにするのが一般的でしょうか。

python

1question = get_object_or_404(Question, pk=pk) 2comments = Comment.objects.filter(question=question) 3 4# ちなみに 2 行目は次のように書いても同じ結果が取得できます 5comments = Comment.objects.filter(question_id=question.pk) 6comments = Comment.objects.filter(question__pk=question.pk)

上のとおりに commentlist() を書いた場合は、テンプレートのループは {% for list in comment_ichiran %} の方で書く必要があるものと思います。

そうではなく、テンプレートで {% for list in question.comment_set.all %} と書かれたい場合は、 commentlist() を例えば次のように書く必要があります。

python

1def commentlist(request, pk): 2 question = get_object_or_404(Question, pk=pk) 3 context = { 4 'question': question, 5 } 6 return render(request, 'polls/comment_list.html', context)

原則 テンプレートで使える変数は view から context として渡されたものだけ と思っておくのがよいかと思います。

ご参考になるでしょうか。

私のこの説明の中にご不明な点がありましたら、ある程度はご自身でお調べになってみていただければと思いますが、「もう詰まってしまってどうしようもない」という場合はコメントでお知らせください :)

投稿2018/12/08 08:17

gh640

総合スコア1407

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

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

sr2460

2018/12/08 12:02

いつもありがとうございます!質問内容を編集させていただきました。 またご指摘の部分を明日から早速取り組んでまいります!!!ありがとうございます!!
gh640

2018/12/08 12:08

ありがとうございます。編集内容見せていただきました。書かせていただいた回答の方向で間違っていなさそうですので、またお時間が大丈夫なときにお試しになってみてください :)
sr2460

2018/12/09 08:41

ありがとうございます!!回答を何度も読ませていただきある程度理解したと思います。 #filterの()内に条件をフィールド名=値にするという部分を理解していなかったためfilter(pk=pk)という構文になっていたんだと思います。 def commentlist(request, pk): comment_filter = get_object_or_404(Question, pk=pk) context = { 'comment_ichiran':Comment.objects.filter(question=comment_filter), } return render(request, 'polls/comment_list.html', context) questionというコードがたくさん存在するため学習のため暫定的にcomment_filterというコードでフィルターをかけることにしました。 # ちなみに 2 行目は次のように書いても同じ結果が取得できます comments = Comment.objects.filter(question_id=question.pk) comments = Comment.objects.filter(question__pk=question.pk) の部分をまだ試していないのですが、やってみてなんとか理解していこうと思います。 まだもう少し改造が必要なアプリケーションなのですがこれで前に進みました。 本当にありがとうございます!
gh640

2018/12/10 02:27

そうでしたか。ご解決されたようでよかったです! > の部分をまだ試していないのですが、やってみてなんとか理解していこうと思います。 この部分は把握しておかれると後々開発がスムーズになると思いますが、当面必要な情報ではないですし、 Django の公式ドキュメントの `QuerySet` の部分をお読みになれば明らかになるところなので、あくまでも余談として受け取ってください :)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問