Передача объектов из Django в Javascript DOM


Answers

Тот же вопрос, «Лучше» ( более поздний ) ответ: Django Queryset to dict для использования в json

Ответа на этот вопрос vashishtha-jogi :

Лучший подход - использовать DjangoJSONEncoder. Он поддерживает десятичное значение.

import json
from django.core.serializers.json import DjangoJSONEncoder

prices = Price.objects.filter(product=product).values_list('price','valid_from')

prices_json = json.dumps(list(prices), cls=DjangoJSONEncoder)

Очень проста в использовании. Никаких прыжков через обручи для преобразования отдельных полей в плавать.

Обновление: Изменен ответ на использование встроенного json вместо simplejson.

Это ответ так часто встречается в моих поисковых запросах Google и имеет так много просмотров, что кажется хорошей идеей обновить его и спасти кого-либо еще от рытья через SO. Предполагает Django 1.5 .

Question

Я пытаюсь передать набор запросов из Django в шаблон с javascript.

Я пробовал разные подходы к решению этого:

1. Обычный подход. Javascript все испортил, пытаясь разобрать объект из-за номенклатуры [& gt; Object: ID & lt; & gt; Object: ID & lt; ...]

Просмотр Django

django_list = list(Some_Object.objects.all())

Шаблон HTML + JS

<script type="text/javascript" >
    var js_list = {{django_list}};
</script>

2. JSON Approach - Django не удается преобразовать список объектов в строку json, не является сериализуемым JSON

Просмотр Django

django_list = list(Some_Object.objects.all())
json_list = simplejson.dumps(django_list)

Шаблон HTML + JS

<script type="text/javascript" >
    var js_list = {{json_list}};
</script>

Итак, мне нужна помощь здесь :)

У кого-нибудь есть предложение / решение?

Благодаря!




Запросы Django могут быть сериализованы JSON . Некоторые типы полей (например, дата, по-видимому) не могут быть сериализованы в состоянии is. Обходной путь для объектов даты размещен в другом вопросе о JSON и Python .

Я бы рекомендовал создавать словари непосредственно в самом JavaScript. Для таких моделей:

class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField()
    content = models.TextField()

class Author(models.Model):
    article = models.ForeignKey("Article", related_name="authors")
    first_name=models.CharField(max_length=100)
    last_name=models.CharField(max_length=100)

Я бы сделал что-то подобное в шаблоне:

<script type="text/javascript">
    var articles = [
    {% for article in article_list %}
        {% if not forloop.first %},{% endif %}
        {
            title: "{{ article.title }}",
            slug: "{{ article.slug }}",
            content: "{{ article.content }}",
            authors: [
            {% for author in article.authors.all %}
                {% if not forloop.first %},{% endif %}
                {
                    first_name: "{{ author.first_name }}",
                    last_name: "{{ author.last_name }}",
                }
            {% endfor %}
            ]
        }
    {% endfor %}
    ]
</script>

Если вы, возможно, немного сформулировали вопрос и не планируете вставлять код в <script> и на самом деле нуждаетесь в JSON по какой-то причине, я бы просто сделал цикл в представлении и создал список dict s, который JSON не имеет проблем с сериализацией, и JavaScript не представляет проблемы в понимании.




Django предлагает встроенную помощь для самого сценария, который вы пытаетесь сделать здесь. Это выглядит примерно так:

В вашем представлении есть последовательность python, список, словарь и т. Д., Назовем его py_object . Один из подходов состоит в том, чтобы jsonify его перед передачей его в механизм рендеринга.

from django.shortcuts import render_to_response
import json  

Затем, позже, используйте это ...

render_to_response('mypage.html',{'js_object':json.dumps(py_object)})

В вашем шаблоне используйте safe фильтр для импорта уже jsonized-объекта из python в javascript, например ...

data = {{ js_object|safe }}

Это должно решить вашу проблему, я надеюсь.