मैं टेम्पलेट में फ्लास्क से जावास्क्रिप्ट तक डेटा कैसे पारित कर सकता हूं?


123

मेरा ऐप एक एपीआई के लिए एक कॉल करता है जो एक शब्दकोश देता है। मैं इस दृश्य से जावास्क्रिप्ट को देखने के लिए जानकारी देना चाहता हूं। मैं जेएस में Google मैप्स एपीआई का उपयोग कर रहा हूं, विशेष रूप से, इसलिए मैं इसे लंबी / अव्यक्त जानकारी के साथ ट्यूपल्स की एक सूची देना चाहता हूं। मुझे पता है कि render_templateइन चरों को देखने के लिए पास किया जाएगा ताकि वे HTML में उपयोग किए जा सकें, लेकिन मैं उन्हें टेम्पलेट में जावास्क्रिप्ट में कैसे पारित कर सकता हूं?

from flask import Flask
from flask import render_template

app = Flask(__name__)

import foo_api

api = foo_api.API('API KEY')

@app.route('/')
def get_data():
    events = api.call(get_event, arg0, arg1)
    geocode = event['latitude'], event['longitude']
    return render_template('get_data.html', geocode=geocode)

जवाबों:


140

आप {{ variable }}अपने टेम्पलेट में कहीं भी उपयोग कर सकते हैं , न कि केवल HTML भाग में। तो यह काम करना चाहिए:

<html>
<head>
  <script>
    var someJavaScriptVar = '{{ geocode[1] }}';
  </script>
</head>
<body>
  <p>Hello World</p>
  <button onclick="alert('Geocode: {{ geocode[0] }} ' + someJavaScriptVar)" />
</body>
</html>

इसे दो-चरणीय प्रक्रिया के रूप में सोचें: पहला, जिन्जा (टेम्प्लेट इंजन फ्लास्क का उपयोग करता है) आपके टेक्स्ट आउटपुट को उत्पन्न करता है। यह उस उपयोगकर्ता को भेजा जाता है जो जावास्क्रिप्ट को निष्पादित करता है जिसे वह देखता है। यदि आप चाहते हैं कि आपका फ्लास्क चर जावास्क्रिप्ट में एक सरणी के रूप में उपलब्ध हो, तो आपको अपने आउटपुट में एक सरणी परिभाषा उत्पन्न करनी होगी:

<html>
  <head>
    <script>
      var myGeocode = ['{{ geocode[0] }}', '{{ geocode[1] }}'];
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

जिन्जा भी पायथन से अधिक उन्नत निर्माण प्रदान करता है, इसलिए आप इसे छोटा कर सकते हैं:

<html>
<head>
  <script>
    var myGeocode = [{{ ', '.join(geocode) }}];
  </script>
</head>
<body>
  <p>Hello World</p>
  <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
</body>
</html>

आप forलूप्स, ifस्टेटमेंट्स और कई अन्य का भी उपयोग कर सकते हैं , अधिक के लिए जिनजा 2 प्रलेखन देखें ।

इसके अलावा, फोर्ड के जवाब पर एक नज़र डालें जो tojsonफ़िल्टर को इंगित करता है जो कि जिनजा 2 के फ़िल्टर के मानक सेट के अतिरिक्त है ।

संपादित करें Nov 2018: tojsonअब जिन्जा 2 के फिल्टर के मानक सेट में शामिल है।


2
बहुत मजबूर, मेस्सी! यह मेरा प्रारंभिक विचार था लेकिन फ्लास्क के लिए प्रलेखन यह स्पष्ट रूप से स्पष्ट नहीं करता है कि आप JS में भी {{var}} फॉर्म का उपयोग कर सकते हैं। इसे साफ करने के लिए धन्यवाद।
विदेश मंत्रालय

2
@mea: आप मनमाने ढंग से टेक्स्ट-आधारित फ़ाइलों को उत्पन्न करने के लिए टेम्प्लेट इंजन का उपयोग भी कर सकते हैं, मैंने इसका उपयोग डायनेमिक रूप से TeX फाइलें (-> पीडीएफ) और ईमेल बनाने के लिए भी किया है, यह काफी बहुमुखी है;)
मेंसी

क्विक फॉलो अप सवाल: यदि मैं जेएस में लूप के लिए करता हूं, तो क्या मैं अजगर वेरिएबल जैसे {{जियोकोड [i]}} में इंडेक्स वेरिएबल का उपयोग कर सकता हूं?
विदेश मंत्रालय

1
यह समझ में आता है, लेकिन आपके द्वारा पोस्ट किया गया समाधान मुझे जेएस सरणी की सामग्री में हाथ से कोड करने की आवश्यकता है। मैं उम्मीद कर रहा था कि मैं इसे और अधिक प्रोग्रामिक रूप से कर सकता हूं जैसे कि मैं चर लंबाई की एक पायथन सूची को पास कर सकता हूं और लूप के लिए एक जेएस लंबाई पर पुनरावृति कर सकता है और फिर उन्हें जेएस सरणी में जोड़ सकता है। क्षमा करें यदि मैं खुद को पर्याप्त स्पष्ट नहीं कर रहा हूं, लेकिन मैं जेएस और वेब देव के लिए हरा हूं।
विदेश मंत्रालय

1
यदि आप किसी अलग फ़ाइल में डेटा पास करना चाहते हैं तो @RocketPingu, आमतौर पर jsonमॉड्यूल का उपयोग करना आसान होता है ताकि आप अपने डेटा को एक
जोंस

113

जावास्क्रिप्ट ऑब्जेक्ट में किसी भी पायथन ऑब्जेक्ट को प्राप्त करने के बारे में जाने का आदर्श तरीका JSON का उपयोग करना है। JSON प्रणालियों के बीच स्थानांतरण के लिए एक प्रारूप के रूप में महान है, लेकिन कभी-कभी हम यह भूल जाते हैं कि यह जावास्क्रिप्ट ऑब्जेक्ट नोटेशन के लिए है। इसका मतलब है कि JSON को टेम्पलेट में इंजेक्ट करना जावास्क्रिप्ट कोड को इंजेक्ट करने के समान है जो ऑब्जेक्ट का वर्णन करता है।

फ्लास्क इसके लिए एक जिन्जा फिल्टर प्रदान करता है: tojsonसंरचना को जेएसएन स्ट्रिंग में डंप करता है और इसे सुरक्षित करता है ताकि जिन्जा इसे ऑटोप्टस्केप न करे।

<html>
  <head>
    <script>
      var myGeocode = {{ geocode|tojson }};
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

यह किसी भी पायथन संरचना के लिए काम करता है जो कि JSON अनुक्रमिक है:

python_data = {
    'some_list': [4, 5, 6],
    'nested_dict': {'foo': 7, 'bar': 'a string'}
}
var data = {{ python_data|tojson }};
alert('Data: ' + data.some_list[1] + ' ' + data.nested_dict.foo + 
      ' ' + data.nested_dict.bar);

4
अगली बार जब आप Uncaught SyntaxError: Unexpected token &जावास्क्रिप्ट कंसोल में मिलते हैं , तो यह कोशिश करें ।
scharfmn

8
मुझे यह उत्तर स्वीकृत उत्तर की तुलना में अधिक ठोस और तार्किक लगता है।
कोनराड

मुझे कोड चलाने में त्रुटि हुई:TypeError: Object of type Undefined is not JSON serializable
jbuddy_13

27

एक का उपयोग करना डेटा विशेषता किसी HTML तत्व पर इनलाइन पटकथा है, जो बारी में अर्थ है आप उपयोग कर सकते हैं का उपयोग किए टाल सख्त सीएसपी नियम अधिक सुरक्षा के लिए।

जैसे कोई डेटा विशेषता निर्दिष्ट करें:

<div id="mydiv" data-geocode='{{ geocode|tojson }}'>...</div>

फिर इसे स्थिर जावास्क्रिप्ट फ़ाइल में एक्सेस करें जैसे:

// Raw JavaScript
var geocode = JSON.parse(document.getElementById("mydiv").dataset.geocode);

// jQuery
var geocode = JSON.parse($("#mydiv").data("geocode"));

11

वैकल्पिक रूप से आप अपने चर को वापस करने के लिए एक समापन बिंदु जोड़ सकते हैं:

@app.route("/api/geocode")
def geo_code():
    return jsonify(geocode)

फिर इसे प्राप्त करने के लिए एक XHR करें:

fetch('/api/geocode')
  .then((res)=>{ console.log(res) })

हाँ, आप कर सकते हैं और कुछ आर्किटेक्चर (esp। एसपीए) में यह चीजों को करने का उचित तरीका है, लेकिन ध्यान रखें कि ऐसा करने के कई नुकसान हैं जब आप इसे सर्व करते हैं तो पेज में डेटा को बेक करना पड़ता है: 1. यह धीमे, 2. इसे थोड़ा और कोड करने की आवश्यकता है यहां तक ​​कि धीरे-धीरे करने के लिए, और 3. यह कम से कम दो अतिरिक्त फ्रंट-एंड स्टेट्स का परिचय देता है जो आपको संभवतः अपने यूआई में सफाई से निपटने की आवश्यकता होगी (अर्थात राज्य जहां एक्सएचआर अनुरोध अभी भी उड़ान में है , और वह स्थान जहां यह पूरी तरह से विफल हो गया है), जिसे अतिरिक्त जावास्क्रिप्ट कोड की एक गुच्छा की आवश्यकता होती है और संभावित बग का एक अतिरिक्त स्रोत पेश करता है।
मार्क अमेरी

3

उन लोगों के लिए बस एक और वैकल्पिक समाधान, जो वैरिएबल को स्क्रिप्ट में पास करना चाहते हैं, जो फ्लास्क का उपयोग करके खट्टा हो जाता है, मैं केवल बाहर के चरों को परिभाषित करके और फिर स्क्रिप्ट को निम्न रूप से कॉल करके इस काम को प्राप्त करने में कामयाब रहा:

    <script>
    var myfileuri = "/static/my_csv.csv"
    var mytableid = 'mytable';
    </script>
    <script type="text/javascript" src="/static/test123.js"></script>

यदि मैं इनपुट jinja चर test123.jsइसमें काम नहीं करता है और आप एक त्रुटि मिल जाएगा।


ठीक वही जो मेरे द्वारा खोजा जा रहा था।
श्रिष्टि

1
-1; इस जवाब का कोई मतलब नहीं है। मुझे लगता है कि "एक स्क्रिप्ट के आधार पर " एक स्क्रिप्ट जो फ्लास्क का उपयोग करके तैयार की जाती है " और आपकी स्पष्ट अपेक्षा है कि आप टेम्पलेट चर का उपयोग करने में सक्षम होंगे /static/test123.js) कि आप गलतफहमी कर रहे हैं कि एस काम के <script>साथ कैसे है src। वे एक फ्लास्क विशेषता नहीं हैं। ब्राउज़र , जब यह इस तरह के एक स्क्रिप्ट को पार्स करता है, स्क्रिप्ट प्राप्त करने के लिए एक अलग HTTP अनुरोध बनाता है। स्क्रिप्ट सामग्री फ्लास्क द्वारा टेम्पलेट में बेक नहीं होती है; वास्तव में, फ्लास्क ने संभवतया ब्राउज़र द्वारा टेम्प्लेट किए गए HTML को उस समय तक भेज दिया है जब ब्राउज़र स्क्रिप्ट का अनुरोध करता है।
मार्क ऐमी

3

कामकाजी उत्तर पहले से ही दिए गए हैं, लेकिन मैं एक चेक जोड़ना चाहता हूं जो फ्लास्क चर उपलब्ध नहीं होने की स्थिति में एक विफल-सुरक्षित के रूप में कार्य करता है। जब आप उपयोग करते हैं:

var myVariable = {{ flaskvar | tojson }};

यदि कोई त्रुटि है जिसके कारण चर गैर-मौजूद है, तो परिणामस्वरूप त्रुटियां अप्रत्याशित परिणाम उत्पन्न कर सकती हैं। इससे बचने के लिए:

{% if flaskvar is defined and flaskvar %}
var myVariable = {{ flaskvar | tojson }};
{% endif %}

2
<script>
    const geocodeArr = JSON.parse('{{ geocode | tojson }}');
    console.log(geocodeArr);
</script>

यह jinja2 का उपयोग जियोडोड ट्यूपल को एक जस स्ट्रिंग में बदलने के लिए करता है, और फिर जावास्क्रिप्ट JSON.parseको एक जावास्क्रिप्ट सरणी में बदल देता है।


1
तुम सिर्फ अजगर में क्यों नहीं धारावाहिक करते हो
Mojimi

0

वैसे, मेरे पास इस काम के लिए एक मुश्किल तरीका है। विचार इस प्रकार है-

<label>, <p>, <input>HTML बॉडी में कुछ अदृश्य HTML टैग्स आदि बनाएं और टैग आईडी में एक पैटर्न बनाएं, उदाहरण के लिए, टैग आईडी में सूची सूचकांक का उपयोग करें और टैग वर्ग के नाम पर सूची मूल्य।

यहां मेरे पास दो सूचियाँ हैं रखरखाव_नेक्स्ट [] और मेंटेनेंस_ब्लॉक_टाइम [] एक ही लंबाई की। मैं फ्लास्क का उपयोग करके इन दो सूची के डेटा को जावास्क्रिप्ट में पास करना चाहता हूं। इसलिए मैं कुछ अदृश्य लेबल टैग लेता हूं और इसका टैग नाम सूची सूचकांक का एक पैटर्न है और इसके वर्ग नाम को सूचकांक में मान के रूप में सेट करता है।

{% for i in range(maintenance_next|length): %}
<label id="maintenance_next_{{i}}" name="{{maintenance_next[i]}}" style="display: none;"></label>
<label id="maintenance_block_time_{{i}}" name="{{maintenance_block_time[i]}}" style="display: none;"></label>
{% endfor%}

इसके बाद, मैं कुछ सरल जावास्क्रिप्ट ऑपरेशन का उपयोग करके जावास्क्रिप्ट में डेटा पुनर्प्राप्त करता हूं।

<script>
var total_len = {{ total_len }};

for (var i = 0; i < total_len; i++) {
    var tm1 = document.getElementById("maintenance_next_" + i).getAttribute("name");
    var tm2 = document.getElementById("maintenance_block_time_" + i).getAttribute("name");
    
    //Do what you need to do with tm1 and tm2.
    
    console.log(tm1);
    console.log(tm2);
}
</script>


-1

कुछ js फाइलें वेब या लाइब्रेरी से आती हैं, वे स्वयं नहीं लिखी जाती हैं। कोड उन्हें इस तरह परिवर्तनशील मिलता है:

var queryString = document.location.search.substring(1);
var params = PDFViewerApplication.parseQueryString(queryString);
var file = 'file' in params ? params.file : DEFAULT_URL;

यह विधि js फ़ाइलों को अपरिवर्तित रखती है (स्वतंत्रता रखें), और चर को सही ढंग से पास करें!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.