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

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

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

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

Python 3.x

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

YouTube

YouTubeとはユーザーがビデオをアップロード・共有・閲覧できるビデオ共有ウェブサイトです。

HTML

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

Q&A

解決済

1回答

564閲覧

Djangoで一覧に表示されたリスト項目からDetaileページへの遷移

HIRO150

総合スコア8

Django

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

Python 3.x

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

YouTube

YouTubeとはユーザーがビデオをアップロード・共有・閲覧できるビデオ共有ウェブサイトです。

HTML

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

0グッド

0クリップ

投稿2018/09/05 06:20

編集2018/09/05 07:33

前提・実現したいこと

DjangoでYpuTubeのようなシステムを作っています。
検索キーワードで動画タイトルを一覧表示し、タイトルをクリックすると動画のDetaileページに飛ぶようにしたいです。

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

YouTube APIから取得したタイトルとIDを紐付けることができません。
HTML内の動画タイトルにアンカータグをつけ、リンク先のdetaileページに動画タイトルに紐づく動画IDを渡すような機能を実現したいです。

該当のソースコード

views.py

from django.shortcuts import render from .search import search def top_search(request): return render(request, "youtube/search.html") def index(request): keyword = request.GET.get("keyword") videos_name, videos_id = search(keyword) videos = { 'videos_name':videos_name, 'videos_id':videos_id } return render(request, "youtube/search_list.html", videos) def detaile(request, video_id): return render(request, "youtube/detaile.html",{"video_id":video_id})

search_list.html

{% extends "youtube/base.html" %} {% block content %} <header> <h1>検索結果</h1> </header> {% for name in videos_name %} <div> <a href="{% url 'youtube:detail' id=videos_id %}">{{ name }}</a> </div> {% endfor %} {% endblock %}

search_list.htmlページ

試したこと

上記コードのままでは、Detaileページにvideos_idのリストが渡されてしまいます。
HTML内のforにてpythonのzip関数も試してみましたが、うまくいきませんでした。

HTMLには辞書型で変数が渡されていると思い、

{% extends "youtube/base.html" %} {% block content %} <header> <h1>検索結果</h1> </header> {% for name,id in videos.values() %} <div> <a href="{% url 'youtube:detail' id=id %}">{{ name }}</a> </div> {% endfor %} {% endblock %}

のようにしてみましたが、これもうまくいきませんでした。

実現したいことは、リスト表示された動画タイトルをクリックすると、YoutubeのようにDetaileページに飛ぶような設計です。
ご教授お願いします。

補足情報(FW/ツールのバージョンなど)

Python 3.6.5 Django==2.1.1

###補足
views.py内のsearch関数はYouTubeAPIの公式(https://developers.google.com/youtube/v3/code_samples/python?hl=ja#search_by_keyword)のコードを流用しました。

search.py

from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.tools import argparser from .youtube_data_model import YouTubeData DEVELOPER_KEY = "MY_DEVELOPER_KEY" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" def youtube_search(options): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY) saerch_response = youtube.search().list( q=options.q, part="id,snippet", maxResults=options.max_results ).execute() videos_name = [] videos_id = [] for saerch_result in saerch_response.get("items", []): if saerch_result["id"]["kind"] == "youtube#video": videos_name.append(saerch_result["snippet"]["title"]) videos_id.append(saerch_result["id"]["videoId"]) return videos_name, videos_id def search(keyword): ytdata = YouTubeData(q=keyword, max_results=10) try: return youtube_search(ytdata) except HttpError as e: print("An HTTP error %d occurrede::\n%s" % (e.resp.status, e.content))

youtube_data_model.py

class YouTubeData(): def __init__(self, q, max_results): self.q = q self.max_results = max_results

戻り値は動画タイトルと動画IDのリストです。
戻り値はvideos_name,videos_idの順番で戻っており、views.py内においても、videos_name,videos_idは正しい値が格納されていることは確認できています。

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

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

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

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

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

Meganezaru

2018/09/05 06:49

search()の戻り値は、どんな形式でしょうか?nameの配列とidの配列で、順序が同期していることは保証されていますか?
HIRO150

2018/09/05 07:38

search()の戻り値はリストです。nameとidの順番が正しく同期されていることが保証されいるかわかりませんが、確認できる範囲であれば全てnameとidの順番は同じでした。よろしくお願いします。
Meganezaru

2018/09/05 07:41

配列に、同じタイミングでappendしているので、順序は揃っていますね。
guest

回答1

0

ベストアンサー

forloop.counter0で、index値が取れます。
idの配列の同じ位置をセットすれば、期待通りに動くと思います。

失礼しました。DjangoのTemplateでは、単純な方法で任意のArray要素にアクセスすることができませんでした。
下記回答は誤りですので、無視してください。

{% extends "youtube/base.html" %} {% block content %} <header> <h1>検索結果</h1> </header> {% for name in videos_name %} <div> <a href="{% url 'youtube:detail' id=videos_id[forloop.counter0] %}">{{ name }} </a> </div> {% endfor %} {% endblock %}

search()の戻り値として、現状は、二つの配列を返していますが、video_idをキーとして、video_nameを値に持つ辞書の配列にまとめたほうが、わかりやすいかもですね。

追記

search()の戻り値を辞書にする方法で、できないでしょうか?

Python

1def youtube_search(options): 2 youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, 3 developerKey=DEVELOPER_KEY) 4 5 saerch_response = youtube.search().list( 6 q=options.q, 7 part="id,snippet", 8 maxResults=options.max_results 9 ).execute() 10 11 # videos_name = [] 12 # videos_id = [] 13 videos = [] 14 15 for saerch_result in saerch_response.get("items", []): 16 if saerch_result["id"]["kind"] == "youtube#video": 17 # videos_name.append(saerch_result["snippet"]["title"]) 18 # videos_id.append(saerch_result["id"]["videoId"]) 19 videos.append( 20 {"video_id": saerch_result["id"]["videoId"], 21 "video_name": saerch_result["snippet"]["title"]}) 22 23 # return videos_name, videos_id 24 return videos

view.py

def index(request): keyword = request.GET.get("keyword") return render(request, "youtube/search_list.html", {'videos': search(keyword)})

search_list.html

{% extends "youtube/base.html" %} {% block content %} <header> <h1>検索結果</h1> </header> {% for video in videos %} <div> <a href="{% url 'youtube:detail' id=video.video_id %}">{{ video.video_name }} </a> </div> {% endfor %} {% endblock %}

投稿2018/09/05 07:54

編集2018/09/05 09:18
Meganezaru

総合スコア715

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

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

HIRO150

2018/09/05 08:26

ご回答ありがとうございます。コードを参考にさていただきましたが、Could not parse the remainder: '[forloop.counter0]' from 'videos_id[forloop.counter0]' というエラーが出てしました。Django Templateでは配列の指定が[]ではなく、「.」のようでvideos_id.forloop.counter0のように試してみましたが同じくエラーになりました。ご提案のvideo_idをキーとして、video_nameを値に持つ辞書の配列の方法を試してみたいと思います。
Meganezaru

2018/09/05 08:40

失礼しました・・・ Arrayを処理する方法で何かないか、調べてみます。
HIRO150

2018/09/05 08:45

すいません。こちらでも最大限調べてみます。ありがとうございます。
Meganezaru

2018/09/05 08:57 編集

template filterを自作するような方法しかなさそうですね・・・ http://stackoverflow.com/a/29664945/2714931 戻り値を変更するなら、templateでアクセスすることを考えて、video_id、video_nameともvalueとして持つ辞書の方が良さそうですね。 {"id":(video_idの値), "name":(video_nameの値)}
Meganezaru

2018/09/05 09:20

変更例を追記しておきました。 動作未確認ですので、悪しからず・・・
HIRO150

2018/09/05 09:28

追記していただいたコードで無事動作しました! 最後まで丁寧にありがとうございます。 大変助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問