Подтвердить что ты не робот

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

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

Я пробовал разные подходы для решения этой проблемы:

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

Django View

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 View

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>

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

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

Спасибо!

4b9b3361

Ответ 1

Хорошо, я нашел решение!

В основном это было из-за не цитирования результатов. Когда Javascript пытался проанализировать объект, это не было распознано как строка.

Итак, первый шаг:

var js_list = {{django_list}}; 

изменено на:

var js_list = "{{django_list}}";

После этого я понял, что Django избегает персонажей, поэтому мне пришлось их заменить следующим образом:

 var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
                return {
                    l   : '<',
                    g   : '>',
                    quo : '"'
                }[b];
            }));

 myData = JSON.parse( myJSONList );

Примечание. Я попытался избежать экранирования символов из Django, используя этот:

var js_list = "{{json_list|safe}}"; 

Но это не работает, потому что он запутывается с кавычками.

Наконец, я нашел способ избежать логики на бэкэнде конвертации в JSON перед отправкой его на Javascript:

var myDjangoList = (("{{django_list |safe}}").replace(/&(l|g|quo)t;/g, function(a,b){
            return {
                l   : '<',
                g   : '>',
                quo : '"'
            }[b];
        }));

myDjangoList = myDjangoList.replace(/u'/g, '\'')
myDjangoList = myDjangoList.replace(/'/g, '\"')

myData = JSON.parse( myDjangoList );

Я уверен, что это можно улучшить, я разрешаю это вам;)

Спасибо за ваши ответы

Надеюсь, что это поможет кому-то еще!

Ответ 2

Тот же вопрос, "Лучше" (более поздний) ответ: Django Queryset для 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.

Ответ 4

Вы можете использовать комбинацию safe и escapejs встроенного фильтра в Django.

var json_string = unescape({{json_list | safe | escapejs}});
var json_data = JSON.parse(json_string);

Ответ 5

Django querysets сериализуется 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 не представляет проблемы в понимании.

Ответ 6

Ваша проблема в том, что, как часто, ваши требования недоопределены. Что именно вы хотите, чтобы JSON выглядел? Вы говорите, что хотите "сериализовать запрос", но в каком формате? Вам нужны все поля из каждого экземпляра модели, выбор или просто представление юникода? Когда вы ответили на этот вопрос, вы узнаете, как решить свою проблему.

Один из подходов, например, может заключаться в использовании метода запроса values для вывода словаря полей для каждого экземпляра и сериализации (необходимо сначала преобразовать его в список):

data = SomeObject.objects.values('field1', 'field2', 'field3')
serialized_data = simplejson.dumps(list(data))

Ответ 7

Вы должны пометить строку как безопасную, чтобы убедиться, что она не сбежала.

в одном из моих проектов я использую его следующим образом:

# app/templatetag/jsonify.py
from django import template
from django.utils.safestring import mark_safe
import json

register = template.Library()

@register.filter
def jsonify(list):
    return mark_safe(json.dumps(list))

и в шаблоне

{% load jsonify %}
<script type="text/javascript" >
    var js_list = {{ python_list|jsonify|escapejs }};
</script>

но вы можете просто добавить mark_safe или использовать | safe в шаблоне, чтобы избежать всех &gt; stuff

Если проблема заключается в обработке сложного объекта python, вам может понадобиться сделать ваш обработчик следующим образом: JSON datetime между Python и JavaScript

Ответ 8

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 }}

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