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

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

ただいまの
回答率

90.50%

  • Python

    7999questions

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

  • Python 3.x

    6412questions

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

  • Django

    1054questions

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

DjangoでViewからテンプレートへデータを渡すには

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 306

anvinon

score 30

 前提・実現したいこと

Djangoで音楽に関するWEBアプリを作っております。
viewで動的に作ったデータをテンプレートのプルダウンで表示させたいです。

 WEBアプリの処理の手順

1.まず、音楽のアーティスト名を下記の画像の赤枠内に入力して、アーティスト名でデータベース内を検索する。
※画像下部のインクリメンタルサーチはまだ補助的な使い方にとどめていますので、今回の質問とは無関係です。
添付画像1

コードでの説明
formsのSearchFormで生成したフォームをviewsのindexアクションに渡し、index.htmlテンプレートで表示させてます。
そちらにアーティスト名を入力します。

2.1.で入力したアーティスト名でデータベースを検索し、そのアーティストの所属する音楽ジャンルが添付画像2のように表示される。
添付画像2

コードでの説明
入力したアーティスト名はaddアクションに飛び、アーティスト名からそのアーティストが所属する音楽ジャンル(9つまで)をデータベースから引き出す。
アーティスト名と音楽ジャンルを今度はresult.htmlに表示させます。

 該当のソースコード

<!-- 下記は index.html です。 -->
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'search/css/style.css' %}" />
<h1>Gusic</h1>
<h2>アーティスト名を入力してください。</h2>
<h3>※ご参考までに以下のインクリメンタルサーチもご利用ください。</h3>
    <form action="add" method="get">
        {{ form.errors.name }}
        <label>{{ form.name.label }}{{ form.name }}</label><br/>
        <input type="submit" value="検索">
    </form>

<h2>アーティスト名の頭文字から選択してから、下記に表示されるインクリメンタルサーチをご利用ください。</h2>
    <form action="index" method="get" name="initial" id"=initial">
        {{ initialForm.errors.initial }}
        <label>{{ initialForm.initial }}</label><br/>
        <input type="button" value="選択" id="submit()" onclick="submit()" />
    </form>
<h2>インクリメンタルサーチ</h2>
    <input id="keyword" type="text" />
    <ol id="list">
    {% url 'search:genre' as genre_url %}
    {% for a in artists %}
<li><a href="{% url 'search:genre' %}">{{ a.name }}</a></li>    
    {% endfor %}
    </ol>


<script type="text/javascript">
    var artists = {{ artists_list|safe }};
</script>    

<script src="{% static 'search/js/index.js' %}"></script>
# 下記はviews.pyです。
from django.shortcuts import render, redirect
from .forms import *
from .models import Artist

def index(request):
    form = SearchForm(request.GET or None)
    initialForm = InitialForm(request.GET or None)
    if initialForm.is_valid():
        initial =  initialForm.cleaned_data["initial"]
        initial = int(initial)
        q = initialForm.choices[initial][1]
        artists = Artist.objects.filter(name__istartswith=q)
        artists_list = artists.values_list('name', flat = True)
        artists_list = list(artists_list)
        f = {
            'form': form,
            'initialForm': initialForm,
            'artists_list': artists_list
        }
        return render(request, 'search/index.html', f)
    else :
        f = {
            'form': form,
            'initialForm': initialForm,
        }
        return render(request, 'search/index.html', f)

def add(request) :
    genre = GenreForm(request.GET or None)
    form = request.GET['name']
    genres = []
    name = Artist.objects.filter(name__iexact=form).values_list('name', flat = True)[0]
    genre1= Artist.objects.filter(name__iexact=form).values_list('genre1', flat = True)[0]
    genres.append(genre1)
    genre2= Artist.objects.filter(name__iexact=form).values_list('genre2', flat = True)[0]
    genres.append(genre2)
    genre3= Artist.objects.filter(name__iexact=form).values_list('genre3', flat = True)[0]
    genres.append(genre3)
    genre4= Artist.objects.filter(name__iexact=form).values_list('genre4', flat = True)[0]
    genres.append(genre4)
    genre5= Artist.objects.filter(name__iexact=form).values_list('genre5', flat = True)[0]
    genres.append(genre5)
    genre6= Artist.objects.filter(name__iexact=form).values_list('genre6', flat = True)[0]
    genres.append(genre6)
    genre7= Artist.objects.filter(name__iexact=form).values_list('genre7', flat = True)[0]
    genres.append(genre7)
    genre8= Artist.objects.filter(name__iexact=form).values_list('genre8', flat = True)[0]
    genres.append(genre8)
    genre9= Artist.objects.filter(name__iexact=form).values_list('genre9', flat = True)[0]
    genres.append(genre9)
    genres = list(filter(lambda a: a != '', genres))
    j = { 
        'name': name,
        'genres' : genres,
    }
    return render(request, 'search/result.html', j)

def result(request):
    return(request, 'search/result.html')

def genre(request):
    return(request, 'search/genre.html')
# 下記はforms.pyです。
from django import forms
from .views import *

class SearchForm(forms.Form):
    name = forms.CharField(
        label='アーティスト名',
        max_length=255,
        required=True,
        widget=forms.TextInput()
    )

class GenreForm(forms.Form):
    genre = forms.ChoiceField(choices = [
        ]
    )     


class InitialForm(forms.Form):
    initial = forms.ChoiceField(choices = [
        (0, "A"), 
        (1, "B"),
        (2,"C"),
        (3,"D"), 
        (4,"E"), 
        (5,"F"),
        (6,"G"), 
        (7,"H"), 
        (8,"I"), 
        (9,"J"), 
        (10,"K"), 
        (11,"L"), 
        (12,"M"), 
        (13,"N"), 
        (14,"O"), 
        (15,"P"), 
        (16,"Q"), 
        (17,"R"), 
        (18,"S"), 
        (19,"T"), 
        (20,"U"), 
        (21,"V"), 
        (22,"W"), 
        (23,"X"),
        (24,"X"), 
        (25,"Y"), 
        (26,"Z")
    ])
    choices=[
        (0,"A"),
        (1,"B"), 
        (2,"C"),
        (3,"D"), 
        (4,"E"), 
        (5,"F"),
        (6,"G"), 
        (7,"H"), 
        (8,"I"), 
        (9,"J"), 
        (10,"K"), 
        (11,"L"), 
        (12,"M"), 
        (13,"N"), 
        (14,"O"), 
        (15,"P"), 
        (16,"Q"), 
        (17,"R"), 
        (18,"S"), 
        (19,"T"), 
        (20,"U"), 
        (21,"V"), 
        (22,"W"), 
        (23,"X"),
        (24,"X"), 
        (25,"Y"), 
        (26,"Z")
    ]
# 下記は models.py です。
from django.db import models
from psycopg2.sql import NULL
from django.template.defaultfilters import default


class Artist(models.Model):
    name = models.CharField(max_length=255)
    genre1 = models.CharField(max_length=255, blank=True, null=True)
    genre2 = models.CharField(max_length=255, blank=True, null=True)
    genre3 = models.CharField(max_length=255, blank=True, null=True)
    genre4 = models.CharField(max_length=255, blank=True, null=True)
    genre5 = models.CharField(max_length=255, blank=True, null=True)
    genre6 = models.CharField(max_length=255, blank=True, null=True)
    genre7 = models.CharField(max_length=255, blank=True, null=True)
    genre8 = models.CharField(max_length=255, blank=True, null=True)
    genre9 = models.CharField(max_length=255, blank=True, null=True)

class Genre(models.Model):
    name = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

class Songs(models.Model):
    id = models.IntegerField
    artist = models.CharField(max_length=255)
    title = models.CharField(max_length=255)
    free_download = models.BooleanField(default=False)
    url = models.URLField(blank = True)

class ArtistAndSongs(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    song = models.ForeignKey(Songs, on_delete=models.CASCADE)

class ArtistAndGenre(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    genre = models.ForeignKey(Genre, on_delete=models.CASCADE)
<!-- 以下は result.html です。 -->
<h2>入力したアーティスト({{ name }})の属するジャンル一覧</h2>
<h2>聴きたいジャンルをクリックしてください。</h2>
{% for g in genres %}
    {{ g }}<br>
{% endfor %}

 発生している問題

result.html で表示させているジャンル一覧をプルダウンで表示させたいです。(今度はジャンル一覧からさらに一つのジャンルを選択させたいので)
しかし、プルダウンメニューにaddアクションで生成した音楽ジャンルを表示させるにはどうすればいいのかわからないので、止まっています。

 試したこと

ググった結果、関数(今回はaddアクション)内で生成した変数(今回はgenres)は、他のファイル(今回はforms.py)から参照できないことがわかりました。よって、formsでviewsの関数内の変数が参照できないと、formsでプルダウンに表示させるデータが設定できないのでは、というのが現在の認識です。

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

  • Python 3.6.5
  • Django 2.0.3

 最後に

できるだけ情報と説明を詳しくしたつもりですが、足りない情報がありましたら、おっしゃってください。
追記いたします。

 追記(2018/06/01 19:06)

以下のような画面表示になりました。

イメージ説明

出来ましたら、以下のようにしたいのですが、どうすればよろしいでしょうか。

イメージ説明

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

こんな感じでしょうかー?

result.html

<select id="id_list" name="name_list">
    {% for g in genres %}
    <option value="{{ g }}"> {{ g }}</option>
    {% endfor %}
</select>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/01 19:06

    コメントありがとうございます!あともう一歩なのですが、ご存じないでしょうか?
    画面表示がどのようになったかは、今から質問内容に追記して、画像をアップロードいたします。

    キャンセル

  • 2018/06/01 22:23

    画像拝見しました。HTMLが下記のようになっていますね。

    <option value="progressive technical metalcore" class> progressive technical metalcore </option>

    この部分で期待するのは、下記と思います。

    <option value="progressive">progressive</option>
    <option value="technical">technical</option>
    <option value="metalcore">metalcore</option>

    そのためには、views.py で genre の中身がこれらの要素が入ったlistになってればよいです。

    デバッグのため、views.pyの genreに代入されている部分で
    for item in genre:
    print(item)
    などして、中身を確認するとよいかもしれません。

    キャンセル

  • 2018/06/02 06:30

    kakimochi様

    返信有難うございます。結論から申しますと、私が少し勘違いしていまして、先程の最初のご回答
    で合っていました。

    いずれにせよ、kakimochi様のご回答がなければ、ずっと開発が止まっていたままでした。
    本当にありがとうございました。ベストアンサーに選ばせていただきます。

    キャンセル

  • 2018/06/04 10:52

    ありがとうございます。

    解決して、よかった~~。

    キャンセル

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

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    7999questions

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

  • Python 3.x

    6412questions

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

  • Django

    1054questions

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