আমি কীভাবে কোনও টেম্পলেটে ফ্ল্যাস্ক থেকে জাভাস্ক্রিপ্টে ডেটা পাস করতে পারি?


123

আমার অ্যাপ্লিকেশনটি এমন কোনও এপিআইতে কল করে যা একটি অভিধান প্রদান করে। আমি ভিউটিতে এই ডিক থেকে জাভাস্ক্রিপ্টে তথ্য প্রেরণ করতে চাই। আমি জেএস-এ গুগল ম্যাপস এপিআই ব্যবহার করছি, বিশেষত, তাই আমি এটিকে দীর্ঘ / দীর্ঘ তথ্যের সাথে টিপলগুলির একটি তালিকা পাস করতে চাই। আমি জানি যে render_templateএই ভেরিয়েবলগুলি ভিউতে পাস করবে যাতে এগুলি এইচটিএমএল-এ ব্যবহৃত হতে পারে তবে আমি কীভাবে এগুলি টেমপ্লেটে জাভাস্ক্রিপ্টে পাস করতে পারি?

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>

এটিকে দ্বি-পর্যায়ের প্রক্রিয়া হিসাবে ভাবেন: প্রথমে জিনজা (টেম্পলেট ইঞ্জিন ফ্লাস্ক ব্যবহার করে) আপনার পাঠ্য আউটপুট উত্পন্ন করে। এটি যে জাভাস্ক্রিপ্টটি দেখেছে তার সম্পাদন করে to আপনি যদি চান যে আপনার ফ্লাস্ক ভেরিয়েবলটি অ্যারে হিসাবে জাভাস্ক্রিপ্টে উপলভ্য হয় তবে আপনাকে আপনার আউটপুটে একটি অ্যারে সংজ্ঞা তৈরি করতে হবে:

<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 এর মানক ফিল্টারগুলির সংযোজন ।

নভেম্বর 2018 সম্পাদনা করুন: tojsonএখন জিনজা 2 এর স্ট্যান্ডার্ড ফিল্টারের অন্তর্ভুক্ত।


2
অনেক বাধ্য, মেনসি! এটি আমার প্রাথমিক চিন্তা ছিল তবে ফ্লাস্কের জন্য নথিপত্রগুলি সহজেই পরিষ্কার করে দেয় না যে আপনি জেএসেও {{var}}} ফর্মটি ব্যবহার করতে পারেন। যে পরিষ্কার করার জন্য ধন্যবাদ।
মায়া

2
@ মিয়া: আপনি স্বেচ্ছাসেবী পাঠ্য-ভিত্তিক ফাইলগুলি তৈরি করতে টেম্পলেট ইঞ্জিনটিও ব্যবহার করতে পারেন, আমি এটিকে টেক্সট ফাইলগুলি (-> পিডিএফ) এবং ইমেলটি
কার্যকরভাবে

দ্রুত ফলোআপ প্রশ্ন: আমি যদি জেএসে লুপের জন্য করি, আমি কি পাইথন ভেরিয়েবলের মধ্যে সূচক পরিবর্তনশীল যেমন eg {জিওকোড [i]}} ব্যবহার করতে পারি?
খনি

1
এটি বোধগম্য হয় তবে আপনি পোস্ট করেছেন এমন সমাধানের জন্য আমার কাছে জেএস অ্যারের সামগ্রীতে হ্যান্ড-কোডের প্রয়োজন বলে মনে হচ্ছে। আমি আশা করছিলাম যে আমি এটি আরও প্রোগ্রামগতভাবে করতে পারব যাতে আমি ভেরিয়েবল দৈর্ঘ্যের পাইথন তালিকাটি পাস করতে পারি এবং লুপের জন্য একটি জেএস দৈর্ঘ্যের উপর পুনরাবৃত্তি করতে পারে এবং তারপরে এটিকে জেএস অ্যারে সংযুক্ত করতে পারে। দুঃখিত যদি আমি নিজেকে যথেষ্ট পরিষ্কার করে নিচ্ছি না তবে আমি জেএস এবং ওয়েব দেবের চেয়ে সবুজ am
খনি

1
@ রকেটপিংগুংগু যদি আপনি একটি পৃথক ফাইলে ডেটা পাস করতে চান তবে সাধারণত json
জাসন

113

জাভাস্ক্রিপ্ট অবজেক্টে যেকোন পাইথন অবজেক্টকে প্রায় বেশিরভাগ ক্ষেত্রে পাওয়ার আদর্শ উপায় হ'ল জেএসএন ব্যবহার করা। JSON সিস্টেমগুলির মধ্যে স্থানান্তর করার জন্য একটি ফর্ম্যাট হিসাবে দুর্দান্ত, তবে কখনও কখনও আমরা ভুলে যাই যে এটি জাভাস্ক্রিপ্ট অবজেক্ট নোটেশনটির জন্য দাঁড়িয়েছে। এর অর্থ এই যে টেমপ্লেটে জেএসএন ইনজেকশন করা জাভাস্ক্রিপ্ট কোডটি ইনজেকশনের মতোই যা অবজেক্টটি বর্ণনা করে।

ফ্লাস্ক tojsonএটির জন্য একটি জিনজা ফিল্টার সরবরাহ করে: কাঠামোটিকে একটি JSON স্ট্রিংয়ে ফেলে দেয় এবং এটি নিরাপদ হিসাবে চিহ্নিত করে যাতে জিনজা এটিকে স্বয়ংক্রিয়ভাবে ক্যাপচার না করে।

<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
আমি এই উত্তরটি গ্রহণযোগ্য উত্তরের চেয়ে আরও শক্ত এবং যৌক্তিক মনে করি find
কনরাড

কোডটি চালাতে আমি একটি ত্রুটি পেয়েছি: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)

তারপরে এটি পুনরুদ্ধার করতে একটি এক্সএইচআর করুন:

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

হ্যাঁ, আপনি করতে পারেন এবং কিছু আর্কিটেকচারে (উদাহরণস্বরূপ এসপিএ) এটি করার উপযুক্ত উপায়, তবে মনে রাখবেন যে আপনি যখন এটি পরিবেশন করবেন তখন পৃষ্ঠাতে ডেটা বেকিংয়ের বিরুদ্ধে এইগুলি করার বিভিন্ন অসুবিধা রয়েছে: ১. এটি ধীরে ধীরে, ২. এটিকে opালুভাবে করতে আরও কিছুটা কোড প্রয়োজন, এবং ৩. এটি কমপক্ষে দু'টি অতিরিক্ত ফ্রন্ট-এন্ডের রাজ্যের সাথে পরিচয় করে যে আপনাকে সম্ভবত আপনার ইউআইতে পরিষ্কারভাবে পরিচালনা করতে হবে (নাম্বারটি যেখানে এক্সএইচআর অনুরোধটি এখনও ফ্লাইটে রয়েছে) , এবং এটি যেখানে এটি সম্পূর্ণরূপে ব্যর্থ হয়েছে), যার জন্য অতিরিক্ত একাধিক জাভাস্ক্রিপ্ট কোড প্রয়োজন এবং সম্ভাব্য বাগগুলির অতিরিক্ত উত্স প্রবর্তন করে।
মার্ক অ্যামেরি

3

যারা ফ্ল্যাশ ব্যবহার করে সর্বাগ্রে লিখিত স্ক্রিপ্টে ভেরিয়েবলগুলি পাস করতে চান তাদের জন্য কেবলমাত্র অন্য একটি বিকল্প সমাধান, আমি কেবল বাইরে ভেরিয়েবলগুলি সংজ্ঞায়িত করে এবং পরে স্ক্রিপ্টটি কল করে এই কাজটি পরিচালনা করতে সক্ষম হয়েছি:

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

যদি আমি এতে জিনজা ভেরিয়েবলগুলি ইনপুট test123.jsকরি তবে এটি কাজ করে না এবং আপনি একটি ত্রুটি পাবেন।


ঠিক আমি খুঁজছেন ছিল কি.
শ্রীশিন্দে

1
-1; এই উত্তরটির কোনও অর্থ নেই। আমি মনে করি ( "স্ক্রিপ্ট যা ফ্লাস্ক ব্যবহার করে উত্সাহিত করা হয়েছে" এবং আপনার স্পষ্ট প্রত্যাশার উপর ভিত্তি করে যে আপনি এতে টেমপ্লেট ভেরিয়েবলগুলি ব্যবহার করতে সক্ষম হবেন /static/test123.js) যে আপনি কীভাবে কাজটি <script>নিয়ে ভুল বুঝছেন src। এগুলি কোনও ফ্লাস্ক বৈশিষ্ট্য নয়। ব্রাউজারটি যখন এই জাতীয় স্ক্রিপ্টটিকে বিশ্লেষণ করে তখন স্ক্রিপ্টটি পাওয়ার জন্য পৃথক এইচটিটিপি অনুরোধ করে। স্ক্রিপ্ট সামগ্রী ফ্লেস্ক দ্বারা টেমপ্লেট এ বেক করা হয় না; প্রকৃতপক্ষে, ফ্লাস্ক সম্ভবত ব্রাউজারটিতে এমনকি স্ক্রিপ্টটির জন্য অনুরোধ করার সময় দ্বারা প্রেরিত এইচটিএমএল প্রেরণ শেষ করেছে।
মার্ক অ্যামেরি

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>

এটি জিঞ্জো 2 ব্যবহার করে জিওকোড টিপলটিকে জসন স্ট্রিংয়ে পরিণত করতে এবং তারপরে জাভাস্ক্রিপ্ট এটিকে JSON.parseজাভাস্ক্রিপ্ট অ্যারে রূপান্তরিত করে।


1
আপনি কেন
অজগরে জসনকে

0

ঠিক আছে, এই কাজের জন্য আমার কাছে একটি জটিল পদ্ধতি আছে। ধারণাটি অনুসরণ করা হয়-

<label>, <p>, <input>এইচটিএমএল বডিতে কিছু অদৃশ্য এইচটিএমএল ট্যাগ তৈরি করুন এবং ট্যাগ আইডিতে একটি প্যাটার্ন তৈরি করুন, উদাহরণস্বরূপ, ট্যাগ আইডিতে তালিকা সূচক এবং ট্যাগ শ্রেণীর নামে তালিকা মান ব্যবহার করুন।

এখানে আমার একই দৈর্ঘ্যের দুটি তালিকা রক্ষণাবেক্ষণ_পদ্ধতি [] এবং রক্ষণাবেক্ষণ_ব্লক_টাইম [] রয়েছে। আমি ফ্ল্যাশ ব্যবহার করে জাভাস্ক্রিপ্টে এই দুটি তালিকার ডেটা পাস করতে চাই। সুতরাং আমি কিছু অদৃশ্য লেবেল ট্যাগ নিয়েছি এবং এর ট্যাগের নামটি তালিকা সূচকের একটি প্যাটার্ন হিসাবে সেট করে এটির শ্রেণীর নামটিকে সূচকের মান হিসাবে সেট করে।

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

কিছু জেএস ফাইল ওয়েব বা লাইব্রেরি থেকে আসে, সেগুলি নিজের লেখা হয় না। কোডগুলি তারা এইভাবে পরিবর্তনশীল পায়:

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

এই পদ্ধতিটি জেএস ফাইলগুলিকে অপরিবর্তিত করে (স্বাধীনতা বজায় রাখে), এবং সঠিকভাবে ভেরিয়েবল পাস করে!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.