DjangoでJavaScriptのオブジェクトを動的に作成

Twitterでシェア FaceBookでシェア はてなブックマークでシェア

Python - Django
2018年11月23日1:54に更新(約20日前)
2018年11月23日1:47に作成(約20日前)

旧ブログ移行記事です。

概要

JavaScriptのオブジェクト(連想配列)を動的に作成しておくことで楽なケースがあります。

例えばちょっとしたサンプルということで、以下のようなものを作ってみます。

プルダウンを選択すると,,,

ページの色がすぐに変更されます。ページ遷移はしません。

更に、色データの登録はadmin管理サイト等から自由に登録できるとしましょう。

今回のはチープな例ですが、もう少し実用的なものだと親カテゴリを選択すると子カテゴリの一覧も変わるといったものも作れます。

ソースコード

models.pyです。

from django.db import models


class Color(models.Model):
    name = models.CharField('テーマ名', max_length=255)
    background_color = models.CharField('背景色', max_length=255)
    h1_color = models.CharField('h1の色', max_length=255)
    p_color = models.CharField('pの色', max_length=255)

    def __str__(self):
        return self.name

次にforms.py。通常のフォームですが、forms.ModelChoiceFieldを使っています。色の一覧をモデル(Color)から取得します。

from django import forms
from .models import Color


class ColorForm(forms.Form):
    color = forms.ModelChoiceField(
        queryset=Color.objects.all(),
        empty_label=None,
        required=False, 
    )

views.pyです。

from django.views import generic
from .forms import ColorForm


class Top(generic.FormView):
    template_name = 'app/top.html'
    form_class = ColorForm

top.htmlです。今回はbase.htmlは作らず、直接全て書きました。

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
</head>
<body>
{{ form.as_p }}

<h1>h1文字</h1>
<p>p文字</p>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script>
    var colors = {
        {% for color in form.color.field.queryset %}
            "{{ color.id }}": {
                "background-color": "{{ color.background_color }}",
                "h1": "{{ color.h1_color }}",
                "p": "{{ color.p_color }}",
            },
        {% endfor %}
    };


    function change_color() {
        var color_id = $("#id_color").val();
        var color_object = colors[color_id];
        $("body").css("background-color", color_object["background-color"]);
        $("h1").css("color", color_object["h1"]);
        $("p").css("color", color_object["p"]);
    }

    $('#id_color').change(function () {
        change_color();
    });
    change_color();
</script>
</body>
</html>

JavaScriptのオブジェクトを動的に作成しているのは以下の部分です。

    var colors = {
        {% for color in form.color.field.queryset %}
            "{{ color.id }}": {
                "background-color": "{{ color.background_color }}",
                "h1": "{{ color.h1_color }}",
                "p": "{{ color.p_color }}",
            },
        {% endfor %}
    };

これは以下のようなオブジェクトになります。pk: 各色の情報という感じですね。

    var colors = {

            "1": {
                "background-color": "#FFFFFF",
                "h1": "#000000",
                "p": "#000000",
            },

    };

<option>要素の値もpkなので、色を選択すると、このオブジェクトから各色の情報を取得できますね。

{% for color in form.color.field.queryset %}ですが、これはちょっと横着している書き方です。一般的に見かけるのは、{% for color in color_list %}のような書き方でしょう。フォームのModelChoiceField内でqueryset=Color.objects.all(),としていたのを思い出してください。そのQuerysetの一覧を借りました。

Twitterでシェア FaceBookでシェア はてなブックマークでシェア

記事にコメントする