كيف اعدل بيانات لل json من javascript

سلام عليكم
أنا هنا استقبلت البيانات من ملف الjson

يعني بعد ان استقبل محتوى الفورم من المستخدم من ال html أريد أن يقوم الجافا سكريبت بالتعديل على بيانات json
من اجل ان اقوم بعدها باستقبال البيانات في بايثون من ملف ال json
وما اريده الان هو ان اعدل على ملف الjson من خلال javascript ؟

ارجوا المساعدة وهل هذا الطريق الذي اسلكه صحيح؟

var app2 = new Vue({
    el: '#form',
    data: {
        ses:"sd"
      
    },
    methods:{
        
        save(event){
            
            var x = new XMLHttpRequest();
            x.open('GET',"data.json");
            x.withCredentials = true;
            var app =this;
            x.onload = function(){
                var data = JSON.parse(x.responseText);
                app.ses = data.name;
        };
        x.send();

        }
    }

   

});
3 Likes

الذي فهمته منك هو انك تحاول اخذ بيانات من ملف JSON وتريد تعديل الملف والكتابة عليه بإستخدام الجافاسكربت ومن ثم الـ Python ستقوم بأخذ البيانات من ملف الـ JSON بعد تعديلة.

في الحقيقة لا يمكنك إنشاء وتعديل الملفات بإستخدام الجافاسكربت وإنما ستحتاج إلى لغة من جانب السيرفر للقيام بذلك مثل node.js. لكن يظل قيامك بهذا الشئ بهذه الطريقة غير مقنع لي لذا إشرح لي ماهو الهدف وماهو البرنامج الذي تعمل عليه حتى نستطيع الخروج بأفضل طريقة لتحقيق الهدف منه.

هل هذا الطريق الذي اسلكه صحيح؟

الطريقة الأصح هو أن تقوم بأخذ البيانات من الفورم وإرسالها للسيرفر مباشرة

4 Likes

انا كنت اود ان ارسل واستقبل البيانات بين البايثون وال template بدون ان استخدم تعليمات بايثون داخل ملفات html
بحيث اجعل ملف json هو الوسيط بحيث يقوم بايثون باخذ البيانات من الداتا بيس يرسلها لملف ال json وبعدها يأتي دور الجافا سكربت اخص بالذكر هنا المكتبة التي اعمل عليها وهي vue js سيقوم باخذ البيانات من json وعرضها على الواجهة html
الى هنا جرت الامور بشكل جيد ولم أواجه مشكلة
لكنني عندما أردت ان ارسل بينات بالعكس من ال html الى قاعدة البيانات فانني اردت أن اقوم بأخذ البيانات من الفورم وارسالها عن طريق جافا سكربت لملف ال json من اجل ان ياخذها بايثون وينقلها لقاعدة البيانات، لكن مع الاسف م استطع لتعديل من خلال جافا سكربت على ملف ال json وهنا وقفت
أنا اعرف طريقة البعث عن طريق الفورم للبايثون مباشرة لكنني أود افصل البايثون تماما عن ال html
ما رأيك؟

4 Likes

لا داعي لعمل ملف json، قم بإرسال البيانات من الفورم في الكلاينت (المتصفح) مباشرة إلى السيرفر (وهو سيرسلها على شكل json format).

وفي السيرفر قم باستقبال هذه البيانات باحتساب انها json، مثلا في flask تستعمل data = request.get_json()، هنا شرح مفصل:

لاحظ كيف يتم ارسال الفورم كما هو من تطبيق الـ vue إلى الـ flask server

4 Likes
    if request.method == "POST":
        data = request.get_json()
        print(data)

يعطيني None
وعندم أقوم

print(data.get('name'))

يعطيني

AttributeError: 'NoneType' object has no attribute 'get'
4 Likes

ممكن تتحقق من developer tools في المتصفح، في جزء الـ network انظر للـ request بعد أن تضغط على submit

هل هو يرسل البيانات بشكل سليم من الفورم ؟

4 Likes

لقد جربت

request.form['name']

وهو يعمل بشكل نظامي
اما التعليمات في الاعلا فهي لا تعمل

4 Likes

جرب هكذا أخي @sohep :

if request.method == "POST":
    data = request.json
    print(data)

من الأحسن أن ترفع مشروعك على الـ github لنتمكن من تجربته وتحديد المشكلة دون اللجوء إلى التكهنات :grin:

4 Likes

عين الصواب :grin::grin:

4 Likes

هو ليس مشروع انما تجريبي

3 Likes

أولا قد قمت بنقل مجلد js داخل static لأنه لم يتم تحميل ملفات ال js عندي، وقمت باستدعائهم من خلال url_for('static',filename='....')
هذه محاولة مني إستطعت من خلالها أن أعدل أو بالأحرى أكتب على ملف data.json عند ارسال محتوى جديد إلى السيرفر، ستجد التعليقات في الكود تشرح ذلك


ولكن هل هي الطريقة الأنسب أو لا سيجيبك الأستاذ @YaserAlnajjar حاولت المساعدة بطريقتي الخاصة لأنني جديدة في هذا المجال

5 Likes

شكرا لك
انا فعلا كنت قد عملت بطريقتك ونجحت معي لكنني حسب نصيحة الاستاذ ياسر ان نتجاز فكرة وجود ملف json
وانا اردت ان اطبقها لكن لا ادري لاذا توجهني هذه المشكلة

4 Likes

من الأحسن أن تتبع طريقة الأستاذ ياسر مثل المثال الذي أعطاه لك، لكن بمعرفتي حاولت أن أجعل ملف data.json قابل للكتابة والتعديل باستقبال البيانات المدخلة من قبل المستخدم واضافتها إلى الملف
في انتظار خبرة الأستاذ ياسر

4 Likes
 if request.method == "POST":
        date = request.get_json([""])
        print(date)
        return date["name"]

مشي الحال
بس ما بعرف ليش لازم يكون
get_json([""])
يعني لازم يتنكتب بهالشكل وعادي شو ماحطيت داخل علامتي التنصيص ما بيرق
والنتيجة انو بيعطيك كل البيانات المرسلة

4 Likes

دالة get_json() لا تستطيع أن تمرر داخلها البيانات لأنها ستجلب لك كل البيانات على شكل json، لها ثلاث براميترات force, silent & cache ففي حالة أنها ترجع لك None تمرر داخلها force بقيمة True وفي حالة مررت فيها silent لا تطبع لك الأخطاء في حالة حدوثها أما الـcache فهي تخزن البيانات دائما على شكل json في حالة احتجتها لاحقا
http://flask.pocoo.org/docs/1.0/api/#flask.Request.get_json

4 Likes

طبعا مشي الحال على برنامج postman
بس على فورم نظامي عنم يعطين يالخطا التالي:

Bad Request
Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)
4 Likes

ماذا عن استبدالها بـ request.json
قد تكون نسخة flask لديك قديمة حاول عمل update لكي تعمل لديك get_json()

3 Likes

رائع يا لارا :star_struck:

فقط انتهي من بعض الامور واكون معكم في الأسبوع القادم باذن الله

3 Likes

إن شاء الله أستاذ :blush:

2 Likes

أسبوع بالتمام والكمال :smile:

اطلعت على المشروع وما شاء الله أنت ولارا وصلتوا لأهم الأشياء… دعني فقط أركز على بعض النقاط

الاحتفاظ بالبيانات

حسب ما فهمت أن الغرض من ملف json هو الاحتفاظ بالبيانات، في الواقع هناك طرق أقوى وأفضل:

1. استعمال الذاكرة مباشرة (سيسهل عليك التطوير)

لاحظ كيف قمت باخراج المتغير data من داخل الـ request للإحتفاظ بالقائمة كما هي طول ماهو البرنامج شغال:

data = []

@app.route('/', methods=['GET', 'POST'])
def weather():
    ...

2. استعمال قاعدة بيانات

لا شيء أكثر ضمانا للاحتفاظ بالبيانات من استعمال قاعدة بيانات اعتيادية مثل SQLite أو MySQL

3. لا تريد قاعدة بيانات، استعمل ملف csv (أكسل)

مرة قرأت مقال رائع للعبقري Scott Hanselman مختص الـ ASP و C# حول كيف أن ملفات csv سهلة الاستعمال والتحكم بها عن طريق برنامج ذو واجهة سهلة… Excel:

التعامل مع Content Type

قرأت حول الدالة get_json واتضح لي أنها تستقبل بيانات json في حال كان نوع الطلب ContentType هو json:

Content-Type: application/json

وهذا هو السبب حينما أشتغل معاك postman ولم يشتغل في المتصفح، لأن المتصفح دائماً سيرسل فقط ContentType من نوع form:

Content-Type: application/x-www-form-urlencoded

هذه صورة من الطلب في المتصفح (اضغط على الصورة لتكبيرها):

  • قمت باستعمال خاصية preserve log (كما موضح بالصورة) لكي أضمن عدم ضياع البيانات عند عمل submit :wink:

وفي هذه الحالة سنحتاج لتحويل الـ form إلى dictionary باستعمال request.form.to_dict()

  • يفترض التحقق من البيانات (validation) لكي لا يكون اليوزر قد أدخل بيانات غير مسموح بها.

النتيجة النهائية

ملف index.js ازلت منه الأسطر تبع data.json وصار:

var app = new Vue({
    el: '#form',
    data: {
        ses:"sd"
      
    }
});

أما ملف main.py صار:

#!flask/bin/python
from os import abort

from flask import Flask, jsonify, request, json, render_template

app = Flask(__name__)

data = []

@app.route('/', methods=['GET', 'POST'])
def weather():
    if request.method == "POST":
        new_data = request.form.to_dict()
        data.append(new_data)
        return render_template('add_article.html', data=data)
        
    elif request.method == "GET":
        return render_template('add_article.html', data=data)


if __name__ == '__main__':
    app.run(debug=True)

الاستعمال الأمثل للـ Vue.JS

في الواقع لو قمت بالأمور كما هي فأنت لا تستفيد بالفعل من قوة Vue :sweat_smile:

لأنه يتم تحديث الصفحة عند عمل submit وهذه هي فائدة ajax (التخلص من تحديث الصفحة) كما شرحها محمد هنا:

كيف تقوم بها؟

اقرأ في هذا الرابط:

https://stackoverflow.com/a/48029830/4565520

بحيث سترسل الطلب ajax إلى الـ endpoint وهي تأخذ البيانات وتضيفها… وبالنسبة للصفحة، فأنت ستضيف البيانات بشكل تلقائي (بإفتراض أن السيرفر أضافها) بمجرد استقبال النتيجة 200 OK من السيرفر (يجب أن تتلقى النتيجة من السيرفر في Vue داخل الـ promise).

  • بالمناسبة في هذه الحالة الأفضل تستعمل get_json() وأيضاً تجعل الـ content type هو json (حينما ترسل الطلب من Vue) لكي يتم التعامل مع الأمر بالشكل الصحيح.

لو عندك أي سؤال تفضل به، وسنكون هنا معك :rose:

3 Likes