riotjs Passare oggetti da Django a DOM Javascript




riotjs (8)

Puoi utilizzare la combinazione di escapejs integrato safe e escapejs in Django.

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

Sto provando a passare un set di query da Django a un modello con javascript.

Ho provato diversi approcci per risolvere questo problema:

1. Approccio normale - Javascript si incasina cercando di analizzare l'oggetto a causa della nomenclatura [& gt Object: ID & lt, & gt Object: ID & lt, ...]

Django View

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

Modello HTML + JS

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

2. Approccio JSON - Django non riesce a convertire la lista degli oggetti in una stringa json non è serializzabile in JSON

Django View

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

Modello HTML + JS

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

Quindi, ho bisogno di aiuto qui :)

Qualcuno ha qualche suggerimento / soluzione?

Grazie!


Stessa domanda, "Migliore" ( più recente ) risposta: Django Queryset da usare per l'uso in json

Risposta da vashishtha-jogi :

Un approccio migliore è l'uso di DjangoJSONEncoder. Ha il supporto per Decimal.

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)

Molto facile da usare. Nessun salto attraverso i cerchi per convertire i singoli campi in float.

Aggiornamento: Modificata la risposta per usare json incorporato invece di simplejson.

Questa è la risposta che è venuta fuori così spesso nelle mie ricerche su google e ha così tanti punti di vista, che mi sembra una buona idea aggiornarla e salvare chiunque altro a scavare attraverso SO. Presume Django 1.5 .


Django offre un aiuto integrato per lo stesso scenario che stai cercando di fare qui. Va qualcosa del genere:

Hai una sequenza python, un elenco, un dizionario, ecc. Nella tua vista, chiamiamolo py_object . Un approccio è quello di jsonify prima di passarlo al motore di rendering.

from django.shortcuts import render_to_response
import json  

Poi più tardi uso come questo ...

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

Nel tuo modello, usa il filtro safe per importare l'oggetto già jsonized da python in javascript, come questo ...

data = {{ js_object|safe }}

Questo dovrebbe risolvere il tuo problema, spero.


Ok, ho trovato la soluzione!

Principalmente era a causa di non citando i risultati. Quando Javascript stava cercando di analizzare l'oggetto questo non è stato riconosciuto come stringa.

Quindi, il primo passo è:

var js_list = {{django_list}}; 

cambiato in:

var js_list = "{{django_list}}";

Dopo questo mi sono reso conto che Django stava scappando dai personaggi quindi ho dovuto sostituirli in questo modo:

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

 myData = JSON.parse( myJSONList );

Nota: ho cercato di evitare la fuga di caratteri da Django usando questo :

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

Ma questo non funziona perché viene confuso con le virgolette.

Finalmente ho trovato un modo per evitare la logica sul backend della conversione in JSON prima di inviarlo a 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 );

Sono sicuro che questo può essere migliorato, ti lascio questo;)

Grazie per le tue risposte

Spero che aiuti qualcun altro!


È necessario contrassegnare la stringa come sicura per assicurarsi che non sia sfuggita.

in uno dei miei progetti lo uso in questo modo:

# 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))

e nel modello

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

ma potresti preferire semplicemente aggiungere mark_safe o usare | safe nel modello per evitare tutto &gt; cose

Se il problema riguarda la gestione di un oggetto Python complesso, potrebbe essere necessario eseguire il gestore in questo modo: JSON datetime tra Python e JavaScript


I queryset di Django sono serializzabili da JSON . Alcuni tipi di campo (come data, apparentemente), non possono essere serializzati a. Una soluzione alternativa per gli oggetti data viene pubblicata in un'altra domanda su JSON e Python .

Consiglierei di creare dizionari direttamente nello stesso JavaScript. Dati i modelli come questo:

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)

Farei qualcosa di simile nel modello:

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

Se forse hai formulato la domanda un po 'male e non hai intenzione di inserire il codice in un tag <script> e in realtà hai bisogno di JSON per qualche ragione, farei semplicemente un ciclo nella vista e creerò un elenco di dict s, che JSON non ha problemi di serializzazione e JavaScript non ha problemi di comprensione.


Il tuo problema è che, come così spesso, i tuoi requisiti sono sottostimati. Che aspetto vuoi che assuma il JSON? Dici che vuoi "serializzare il queryset", ma in quale formato? Vuoi tutti i campi da ogni istanza di modello, una selezione o solo la rappresentazione unicode? Quando avrai risposto a questa domanda, saprai come risolvere il tuo problema.

Un approccio, ad esempio, potrebbe essere quello di utilizzare il metodo values queryset per generare un dizionario di campi per ogni istanza e serializzarlo (è necessario prima convertirlo in un elenco):

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

Risposta consolidata (my env: Django 2.0)

In views.py

import json
data= []
// fil the list
context['mydata'] = json.dumps({'data':data})

Nel modello

  <script type="text/javascript">
      var mydataString = "{{mydata|escapejs}}";
      console.log(JSON.parse(mydataString));
  </script>




dom