javascript - template - title css
Pasar objetos de Django a Javascript DOM (9)
Estoy intentando pasar un conjunto de consultas de Django a una plantilla con javascript.
He intentado diferentes enfoques para resolver esto:
1. Enfoque normal: Javascript se confunde al intentar analizar el objeto debido a la nomenclatura [& gt Objeto: ID & lt, & gt Objeto: ID & lt, ...]
Vista Django
django_list = list(Some_Object.objects.all())
Plantilla HTML + JS
<script type="text/javascript" >
var js_list = {{django_list}};
</script>
2. Enfoque JSON: Django falla al convertir la lista de objetos en una cadena json que no es serializable por JSON.
Vista Django
django_list = list(Some_Object.objects.all())
json_list = simplejson.dumps(django_list)
Plantilla HTML + JS
<script type="text/javascript" >
var js_list = {{json_list}};
</script>
Entonces, necesito ayuda aquí :)
¿Alguien tiene alguna sugerencia / solución?
¡Gracias!
La misma pregunta, "Mejor" ( más reciente ) respuesta: Django Queryset a dict para uso en json
Respuesta de vashishtha-jogi :
Un mejor enfoque es usar DjangoJSONEncoder. Tiene soporte para 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)
Muy fácil de usar Sin saltar por los aros para convertir campos individuales para flotar.
Actualización: Cambió la respuesta para usar el json incorporado en lugar de simplejson.
Esta es la respuesta que aparece con tanta frecuencia en mis búsquedas de Google y tiene tantas vistas, que parece una buena idea actualizarla y evitar que alguien más explore a través de SO. Asume que Django 1.5
.
Debe marcar la cadena como segura para asegurarse de que no se haya escapado.
en uno de mis proyectos lo uso así:
# 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))
y en la plantilla
{% load jsonify %}
<script type="text/javascript" >
var js_list = {{ python_list|jsonify|escapejs }};
</script>
pero puede preferir simplemente agregar mark_safe o usar | safe en la plantilla para evitar todo >
cosas
Si el problema es para manejar objetos Python complejos, puede que tenga que hacer su manejador de esta manera: JSON datetime entre Python y JavaScript
Django ofrece ayuda integrada para el mismo escenario que estás tratando de hacer aquí. Es algo parecido a esto:
Tienes una secuencia, lista, diccionario, etc. de Python en tu vista, llamémoslo py_object
. Un enfoque es jsonificarlo antes de pasarlo al motor de renderizado.
from django.shortcuts import render_to_response
import json
Luego, más tarde, usa así ...
render_to_response(''mypage.html'',{''js_object'':json.dumps(py_object)})
En tu plantilla, utiliza el filtro de safe
para importar el objeto ya jsonizado de python a javascript, así ...
data = {{ js_object|safe }}
Eso debería resolver tu problema, espero.
EDITAR: no use este método, vea la respuesta de @ agconti.
Utilice el filtro escapejs: https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#escapejs
Ejemplo de dumping de una lista:
var foo = [{% for x in y %}''{{ x|escapejs }}'',{% endfor %}]
Los conjuntos de consulta de Django son serializables por JSON . Algunos tipos de campo (como, por ejemplo, la fecha) no se pueden serializar en is. Una solución para objetos de fecha se publica en otra pregunta en JSON y Python .
Recomendaría crear diccionarios directamente en el propio JavaScript. Dados modelos como este:
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)
Haría algo así en la plantilla:
<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>
Si tal vez redactó la pregunta un poco mal y no está planeando insertar código en una etiqueta <script>
y realmente necesita JSON por algún motivo, simplemente haré un bucle en la vista y crearé una lista de dict
, que JSON no tiene problemas para serializar, y JavaScript no tiene problemas para entenderlo.
Ok, encontré la solución!
Mayormente fue por no citar los resultados. Cuando Javascript intentaba analizar el objeto, no se reconocía como cadena.
Entonces, el primer paso es:
var js_list = {{django_list}};
cambiado a:
var js_list = "{{django_list}}";
Después de esto, me di cuenta de que Django estaba escapando de los personajes, así que tuve que reemplazarlos así:
var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : ''<'',
g : ''>'',
quo : ''"''
}[b];
}));
myData = JSON.parse( myJSONList );
Nota: Intenté evitar el escape de personajes de Django usando esto :
var js_list = "{{json_list|safe}}";
Pero esto no funciona porque se confunde con las comillas.
Finalmente encontré una forma de evitar la lógica en el back-end de convertir a JSON antes de enviarlo 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 );
Estoy seguro de que esto se puede mejorar, se lo dejo a usted;)
Gracias por tus respuestas
Espero que ayude a alguien más!
Respuesta consolidada (mi env: Django 2.0)
En views.py
import json
data= []
// fil the list
context[''mydata''] = json.dumps({''data'':data})
En plantilla
<script type="text/javascript">
var mydataString = "{{mydata|escapejs}}";
console.log(JSON.parse(mydataString));
</script>
Su problema es que, como suele suceder, sus requisitos no están suficientemente especificados. ¿A qué exactamente quieres que se vea el JSON? Usted dice que quiere "serializar el conjunto de preguntas", pero ¿en qué formato? ¿Desea todos los campos de cada instancia de modelo, una selección o simplemente la representación unicode? Cuando hayas respondido esa pregunta, sabrás cómo resolver tu problema.
Un enfoque, por ejemplo, podría ser utilizar el método de values
consulta para generar un diccionario de campos para cada instancia y serializar eso (primero debe convertirlo a una lista):
data = SomeObject.objects.values(''field1'', ''field2'', ''field3'')
serialized_data = simplejson.dumps(list(data))