Quando renderizo uma página usando o renderizador de modelos do Django, posso passar uma variável de dicionário contendo vários valores para manipulá-los na página usando {{ myVar }}
.
Existe uma maneira de acessar a mesma variável em Javascript (talvez usando o DOM, não sei como o Django torna as variáveis acessíveis)? Quero poder pesquisar detalhes usando uma pesquisa AJAX com base nos valores contidos nas variáveis passadas.
escapejs
existe um filtro:escapejs('<>') -> u'\\u003C\\u003E'
CUIDADO Verifique o ticket nº 17419 para obter uma discussão sobre a adição de uma marca similar no núcleo do Django e possíveis vulnerabilidades XSS introduzidas usando essa marca de modelo com dados gerados pelo usuário. O comentário do amacneil discute a maioria das preocupações levantadas no ticket.
Eu acho que a maneira mais flexível e útil de fazer isso é definir um filtro de modelo para variáveis que você deseja usar no código JS. Isso permite garantir que seus dados sejam escapados corretamente e que você possa usá-los com estruturas de dados complexas, como
dict
elist
. É por isso que escrevo esta resposta, apesar de haver uma resposta aceita com muitos votos positivos.Aqui está um exemplo de filtro de modelo:
Esse modelo de filtros converte variável em string JSON. Você pode usá-lo assim:
fonte
safe
apenas marca o valor como seguro, sem conversão e escape adequados.function myWidget(config) { /* implementation */ }
no arquivo JS e depois o use em algumas páginasmyWidget({{ pythonConfig | js }})
. Mas você não pode usá-lo em arquivos JS (como você notou), por isso tem suas limitações.Uma solução que funcionou para mim está usando o campo de entrada oculto no modelo
Em seguida, obtendo o valor em javascript dessa maneira,
fonte
A partir do Django 2.1, uma nova tag de modelo incorporada foi introduzida especificamente para este caso de uso:
json_script
.https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#json-script
A nova tag serializa com segurança os valores do modelo e protege contra o XSS.
Trecho dos documentos do Django:
fonte
Aqui está o que estou fazendo com muita facilidade: modifiquei meu arquivo base.html para o meu modelo e coloquei na parte inferior:
então, quando quero usar uma variável nos arquivos javascript, crio um dicionário DJdata e o adiciono ao contexto por um json:
context['DJdata'] = json.dumps(DJdata)
Espero que ajude!
fonte
Para um dicionário, é melhor codificar para JSON primeiro. Você pode usar simplejson.dumps () ou, se desejar converter de um modelo de dados no App Engine, poderá usar encode () da biblioteca GQLEncoder.
fonte
Eu estava enfrentando um problema semelhante e a resposta sugerida por S.Lott funcionou para mim.
No entanto, gostaria de destacar aqui as principais limitações de implementação . Se você planeja colocar seu código javascript em um arquivo diferente e incluir esse arquivo no seu modelo. Isso não vai funcionar.
Isso funciona apenas quando o modelo principal e o código javascript estão no mesmo arquivo. Provavelmente a equipe do django pode resolver essa limitação.
fonte
Eu também tenho lutado com isso. Na superfície, parece que as soluções acima devem funcionar. No entanto, a arquitetura django exige que cada arquivo html tenha suas próprias variáveis renderizadas (ou seja,
{{contact}}
é renderizado paracontact.html
, enquanto{{posts}}
vai para egindex.html
e assim por diante). Por outro lado,<script>
tags aparecem após a na partir do qual e herdar. Isso basicamente significa que qualquer solução, incluindo{%endblock%}
base.html
contact.html
index.html
está fadado a falhar, porque a variável e o script não podem coexistir no mesmo arquivo.
A solução simples que acabei encontrando e funcionou para mim foi simplesmente envolver a variável com uma tag com id e depois se referir a ela no arquivo js, da seguinte forma:
e depois:
e apenas incluem
<script src="static/js/somecode.js"></script>
embase.html
como de costume. Claro que isso é apenas sobre como obter o conteúdo. Em relação à segurança, basta seguir as outras respostas.fonte
.textContent
vez de.innerHTML
, porque, caso contrário, as entidades que forem codificadas em HTML também farão parte da variável JS. Mas, mesmo assim, pode não ser reproduzido 1: 1 (não tenho certeza).Para um objeto JavaScript armazenado em um campo Django como texto, que precisa novamente se tornar um objeto JavaScript inserido dinamicamente no script na página, você precisa usar ambos
escapejs
eJSON.parse()
:O Django
escapejs
lida com a citação corretamente eJSON.parse()
converte a string novamente em um objeto JS.fonte
Observe que, se você quiser passar uma variável para um script .js externo, precisará preceder sua marca de script por outra marca de script que declare uma variável global.
data
é definido na visualização como de costume noget_context_data
fonte
Eu uso dessa maneira no Django 2.1 e trabalho para mim e dessa maneira é segura (referência) :
Lado do Django:
Lado do HTML:
fonte
você pode montar o script inteiro em que sua variável de matriz é declarada em uma sequência, da seguinte maneira:
que irá gerar uma string da seguinte maneira
depois de ter essa sequência, você deve enviá-la para o modelo
no modelo, você o recebe e o interpreta literariamente como código htm, logo antes do código javascript onde você precisa, por exemplo
e abaixo desse restante do código, lembre-se de que a variável a ser usada no exemplo é data2
Dessa forma, você manterá o tipo de dados, que neste caso é um arranjo
fonte
aaa
conterá apenas números, caso contrário, XSS (injeção de script) é possível.Há duas coisas que funcionaram para mim dentro do Javascript:
e outro: no views.py
e no html:
fonte