-
المساهمات
646 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
1
إجابات الأسئلة
-
إجابة مسعود زاهي سؤال في كيفية توليد رسالة خطأ مخصصة في فلاسك Flask بإستخدام flask-restful؟ كانت الإجابة المقبولة
استخدم الدالة abort من المكتبة flask_restful ليس من مكتبة flask ﻷن الأولى تقبل إضافة قِيم أخرى في كود ال JSON، والثانية لا تقبل:
from flask import Flask from flask_restful import Resource, Api, abort #قم باستدعاء الدالة #abort # من المكتبة # flask_restful app = Flask(__name__) api = Api(app) class HelloWorld(Resource): def get(self): # قم باستخدام الدالة # وأضف القيم الجديدة إليها # على سبيل المثال قمنا هنا بإضافة # route= api.url_for(self) abort(500, message="Error: Can't find the file you looking for.", route=api.url_for(self)) return {'hello': 'world'} api.add_resource(HelloWorld, '/api/v1/get-log') if __name__ == "__main__": app.run(debug=True)
-
إجابة مسعود زاهي سؤال في كيفية الوصول إلى الملفات المرفوعة إلى فلاسك Flask؟ كانت الإجابة المقبولة
لقراءة ملف الCSV قبل حِفظه قُم بتحويله إلى دفق نص (Text stream) باستخدام io.TextIOWrapper:
import io from flask import Flask, jsonify, request @app.route('/upload/', methods=['POST']) def csv_upload(): filebuf = request.files.get('csvfile')#جلب الملف من الطلب if filebuf is None:# التأكد من أن الملف موجود وإلا نقوم بارجاع خطأ للعميل return jsonify(message='Please specify the file'), 400 elif 'text/csv' != filebuf.mimetype: #التأكد من أن نوع الملف المُحَمّل هو CSV return jsonify(message='Only CSV files will be accepted'), 415 text_stream = io.TextIOWrapper(filebuf.stream, encoding='utf8')# نقوم بتحويل الملف الى دفق نص for row in csv.reader(text_stream):#نقرأ محتوى الملف #ضع شيفرة القراءة هنا return jsonify(message=f'{filebuf.filename!r}Loaded'), 200#إرجاع جواب للعميل بأن الملف حُمّل بنجاح
-
إجابة مسعود زاهي سؤال في كيفية الحصول على معرف حقل field id في القالب template في جانغو Django؟ كانت الإجابة المقبولة
للحصول على مُعرف الحقل إستخدم
{{ field.auto_id }} أو:
{{ field.id_for_label }}
-
إجابة مسعود زاهي سؤال في هل من الممكن تضمين عدة نماذج في نموذج واحد في جانغو Django؟ كانت الإجابة المقبولة
إذا أردت عرض النموذجين كنموذج واحد في القالب لا يجب عليك دمجُهُما بس استعملهما داخل عنصر <form> واحد. مثال ذلك:
<form action="/your-url/" method="post"> {% csrf_token %} {{ profileForm }} {{ userEditForm }} <input type="submit" value="Submit"> </form> ثم فقط قُم بمعالجة النماذج بشكل منفصل في العرض (View):
def your_view(request): # في حالة # GET # نقوم بإنشاء كائن جديد من كل نموذج وإرساله إلى القالب للعرض if request.method == "GET": profileForm = ProfileForm() userEditForm = UserEditForm() # أما في حالة # POST # elif request.method == 'POST': # نقوم بإنشاء النموذجين وملئهما بالبيانات المُرسلة من القالب profileForm = ProfileForm(request.POST) userEditForm = UserEditForm(request.POST) # بعدها نتحقق في ماإذا كانت البيانات صالحة في النموذجين وليس بها أخطاء if profileForm.is_valid() and userEditForm.is_valid(): # إذا كانت البيانات صالحة نقوم بحفظها وإرسال العميل إلى صفحة أخرى profileForm.save() userEditForm.save() return HttpResponseRedirect('/thanks/') return render(request, 'template.html', {'profileForm': profileForm, 'userEditForm':userEditForm})
-
إجابة مسعود زاهي سؤال في تنفيذ دالة بعد إرجاع رد Response إلى العميل في فلاسك Flask؟ كانت الإجابة المقبولة
نعم هناك طريقة:
قُم بالفصل بين المهام التي يتعين على الخادم القيام بها وبين إرسال الرد للعميل. إستخدم مكتبة بايثون threading لإنشاء Thread ليقوم بتنفيذ الدالة بعد إرسال الرد للعميل على الشكل الآتي: from flask import Flask, request import time import threading#قم باستدعاء مكتبة بايثون app = Flask(__name__) @app.route('/your-route', methods=['POST']) def start_task(): def long_running_task(**kwargs): # أنشئ الدالة """ مهمة طويلة المدى """ ... # قم بتنفيذ الدالة داخل # Thread thread = threading.Thread(target=long_running_task) thread.start() return {"message": "Accepted"}, 202 # هنا تقوم بإرجاع الرد للعميل if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)
-
إجابة مسعود زاهي سؤال في كيفية الحصول على رسائل الخطأ في WTForms في فلاسك Flask؟ كانت الإجابة المقبولة
استعمل form.errors التي ستعطيك مُلخصاً لجميع الأخطاء:
for field, err in form.errors.items(): print(err )
-
إجابة مسعود زاهي سؤال في كيفية إستبدال النصوص في قوالب jinja2 في فلاسك Flask؟ كانت الإجابة المقبولة
يُمكنك تعطيل خاصية الautoescape للحصول على النتيجة التي ترغب بها:
{% autoescape false %} {{ 'username|name|email' | replace("|", ":<br/>") }} {% endautoescape %} لكن هذه الطريقة لا يُنصح بها لأنك تقوم بعطيل الحماية ضد حَقْن ال HTML أو ما يُعرف بالإنجليزية HTML Injection.
في طريقة أخرى وهي إنشاء مُرشح خاص يقوم بهذا العمل:
# myapp/util/filters.py from .. import app from markupsafe import Markup @app.template_filter() def custom_split(text): """ الفصل بين العناصر بأسطر""" return Markup("<br>".join(text.split("|"))) القالب يُصبحْ:
{{ 'username|name|email'|custom_split }}
-
إجابة مسعود زاهي سؤال في كيفية إستخدام عمل logging في مشروع جانغو Django؟ كانت الإجابة المقبولة
لإضافة خاصية تسجيل المعلومات لكل الزيارات التي يقوم بها المستخدمون قم بإضافة الشفرة الآتية إلى ملف الإعدادات settings.py:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'file': { 'level': 'DEBUG', 'class': 'logging.FileHandler', 'filename': 'path to the forlder temp/app.log',# ضع هنا المسار الكامل لملف التسجيل }, }, 'loggers': { 'django': { 'handlers': ['file'], 'level': 'DEBUG', 'propagate': True, }, }, }
بعدها في ملف ال views.py الخاص بك أضف الشفرة التالية:
import logging# قم بإستيراد المكتبة الخاص بالتسجيل logger = logging.getLogger(__name__) # قم بجلب المٌسجل def profile(request): ... # بعدها سجل ما تريد من المعلومات # التسجيلات سوف تٌحفظ في الملف الذي عينته في الإعدادات logger.debug('User visited /profile/me') logger.debug('User is %s' % (request.user.get_full_name())) logger.debug('User age is %s' % (request.user.profile.age)) 14:22:10 Jan 31 2022 Username is Mohssen 14:22:10 Jan 31 2022 User age is 23
-
إجابة مسعود زاهي سؤال في كيفية إضافة خصائص HTML Attributes إلى أحد الحقول TextInput في جانغو Django؟ كانت الإجابة المقبولة
لنفرض مثلا أن الحقل الذي تستعمله query نوعه هو Charfield
class YourModelForm(forms.Form): query = forms.CharField(required=True) فلإضافة الخاصية autocomplete إليه نقوم بالآتي:
class YourModelForm(forms.Form): query = forms.CharField(required=True, widget=forms.TextInput(attrs={'autocomplete':'off'})) كما يمكننا تغيير خصائص الحقل داخل الدالة __init__ الخاصة بالنموذج.
class YourModelForm(forms.Form): query = forms.CharField(required=True) def __init__(self, *args, **kwargs): super(YourModelForm, self).__init__(*args, **kwargs) self.fields['query'].widget.attrs.update({ 'autocomplete': 'off' })
-
إجابة مسعود زاهي سؤال في كيفية عرض محتوى HTML في قالب jinja بإستخدام فلاسك flask؟ كانت الإجابة المقبولة
إستعمل مرشح القوالب filter لوضع علامة آمن على أكواد ال Html التي أضفتها حتى يقوم jinja بعرضها كعناصر وليس كنص.
<body> {% block body %} {{ data|safe }} {% endblock %} <body> كما يمكنك الإستغناء عن unescape:
return render_template("index.html", data= Markup(html)) هذا سيؤدي إلى عمل نفس الشيء و سيُحافظ على القالب الخاص بك نظيفًا.
كما يُمكنك أيضا إستخدام:
{٪ autoescape٪} التي تعمل على تعطيل نظام autoescape في القوالب:
{% autoescape false %} <body> {% block body %} {{ data }} {% endblock %} </body> {% endautoescape %} ملاحظة: يُرجى توخي الحذر الشديد بشأن المتغيرات التي تستخدمها في هذه الكتلة.
-
إجابة مسعود زاهي سؤال في ما الفرق بين الدالة len والتابع QuerySet.count في جانغو Django؟ كانت الإجابة المقبولة
عادة يُفضل استعمال count أحسن من len لأنها أسرع وتستهلك ذاكرة أقل:
qs.count() : ستترجم إلى:
SELECT COUNT(*) FROM some_table وهي عبارة عن طلب واحد من جانغو و كل الحسابات الأخرى تتم داخل نظام إدارة قاعدة البيانات (RDBMS).
أما
len(qs) فهي تترجم إلى:
SELECT * FROM some_table هذا يعني جلب كل العناصر الموجودة داخل الجدول وبعدها جانغو يقوم بِعَدِهَا وإرجاع النتيجة، وهذا يتطلب ذاكرة إضافية للتخزين قبل العَد.
-
إجابة مسعود زاهي سؤال في خطأ too many values to unpack في جانغو Django؟ كانت الإجابة المقبولة
عادة يحدث هذا الاستثناء لما نُحاول فك حزمة (a tuple) ، لكن الحزمة تحتوي على عدد كبير من القيم أكبر من المتغيرات التي نريد فك الحزمة فيها. مثال على ذلك:
def mehtod(): return ("a","b","c") #الدالة تقوم بارجاع حُزمة فيها ثلاث قيم a,b,c = mehtod()#نقوم بفك الحزمة في ثلاث متغيرات # هنا لا يحصل خطأ print a >> "a" print b >> "b" print c >> "c" # أما هنا يحصل خطأ a,b = mehtod() # لأننا قمنا بفك الحزممة في عدد متغيرات أقل من حجم الحزمة الآن ، لا أعرف سبب حدوث ذلك في حالتك ، ولكن ربما ستوجهك هذه الإجابة في الاتجاه الصحيح ان شاء الله.
-
إجابة مسعود زاهي سؤال في خطأ DisallowedHost عند نشر موقع جانغو Django على الإنترنت كانت الإجابة المقبولة
سبب المشكلة: هو أن جانغو يقوم بفحص قيمة Host في رأس طلب الHTTP المُرسلة ويُقارنها بالقيم الموجودة داخل ALLOWED_HOSTS المُتواجدة في ملف الإعدادات settings.py. إذا كانت قيمة HOST - سواءًا عُنوان أيْبي أو إسم نطاق- مُتواجدة في ALLOWED_HOSTS يقوم جانغو بسماح الطلب. أما في حالة عدم تواجدها فيقوم برفضها مثل ما حصل معك. ملاحظة: هذه هي عبارة عن حماية يوفرها جانغو ليمنع هجمات "HTTP HOST Header"، والتي تكون ممكنة حتى في ظل العديد من تكوينات خادم الويب التي تبدو آمنة.
حل المشكلة: يكون بإضافة xxx.xxx.xx.xx الى ALLOWED_HOSTS الموجودة في ملف settings.py. ALLOWED_HOSTS = ['xxx.xxx.xx.xx']
-
إجابة مسعود زاهي سؤال في كيف يمكنني حذف علاقة Many-to-Many دون التأثير على الكائنات في جانغو Django؟ كانت الإجابة المقبولة
الأمر بسيط أولا قم بجلب الكائن my_interest باستعمال الدالة get مثلاً:
my_interest = Interest.objects.get(id=my_interest_id) #قمت بجلب الكائن باستعمال معرفه #يمكنك جلبه بأي خاصية من خصائصه بعدها احذف الرابطة بينه وبين my_user:
my_user.interests.remove(my_interest) # ملاحظة: #remove #تقوم بالفصل بين الكائنين ولا تقوم بحذف أي منهما
-
إجابة مسعود زاهي سؤال في كيفية إعادة تسمية العناصر في التابع values في جانغو Django؟ كانت الإجابة المقبولة
توجد عدة طرق للقيام بهذا الأمر.
الطريقة الأولى: >>> from django.db.models import F >>> MyModel.objects.annotate(new_name= F('original_name')).values('new_name') [{'new_name': 1}, {'new_name': 2}] # أنشأنا عمود جديد في الكائن وسميناه بالاسم الجديد # بعدها أعطيناه قيمة العمود القديم باستخدام الكائن # F الطريقة الثانية: # مثل الطريقة الأولى لكن باستعمال # extra >>> MyModel.objects.extra(select={'new_name': 'original_name'}).values('new_name') [{'new_name': 1}, {'new_name': 2}] الطريقة الثالثة: # كما يمكننا تغيير الاسم مباشرة في # values >>> from django.db.models import F >>> MyModel.objects.values(new_name=F('original_name')) [{'new_name': 1}, {'new_name': 2}]
-
إجابة مسعود زاهي سؤال في كيفية إستخدام معامل باقي القسمة % في قوالب جانغو Django؟ كانت الإجابة المقبولة
يمكنك استخدام علامة القالب (tamplatetag) divisibleby المدمجة في Django.
divisibleby: تقوم بارجاع True عندما تكون القيمة تقبل القسمة على العنصر المُدخل. مثلا: {{ value|divisibleby:"3" }} # إذا كانت القيمة = 21 فسيكون الإخراج # True # أما اذا كانت القيمة لا تقبل القسمة على 3 فسيكون الإخراج # False إذا مثالك يُصبح:
{% for p in posts %} <!-- ملاحظة: forloop.counter0 => تقوم بالعد من 0 --> <!-- forloop.counter0|divisibleby:'4' يكون الاخراج صحيحا عند العنصر الخامس لا الرابع --> <!-- لهذا عليك استعمال --> <!-- forloop.counter --> <div class="post flex flex-row justify-start {% if forloop.counter|divisibleby:'4' %}bg-black{% endif %}}"> <h2>p.title</h2> <div class="preview"> <!-- ... --> </div> <div class="overlay"> <!-- ... --> </div> </div> {% endfor %}
-
إجابة مسعود زاهي سؤال في ما هي الطريقة للإشارة إلى عنصر واحد في قائمة list من قالب جانغو Django؟ كانت الإجابة المقبولة
يوجد عدة طرق لطباعة أول عنصر في مجموعة.
الطريقة الأولى {{products.0}} الطريقة الثانية باستخدام علامة القالب first: {{products|first}} #أما اذا كنت تريد طباعة خاصية داخل الكائن فيمكنك استعمال # with {% with products|first=firstPoduct %} #هنا اطبع الخاصية التي تريد مثلا خاصية الاسم {{firstPoduct.name}} {% endwith %} الطريقة الثالثة باستخدام الحلقة for: {% for product in products %} {% if forloop.first %} {{product}} {% endif %} {% endfor %}
-
إجابة مسعود زاهي سؤال في كيفية الوصول إلى forloop.counter الخاص بالحلقات for المتداخلة في قوالب جانغو Django؟ كانت الإجابة المقبولة
للحصول على عداد الحلقة الخارجية أو الحلقة الأب يمكن استعمال forloop.parentloop.counter كما يلي:
{% for parent in ParentItems %} {% for item in parent %} <!-- {{forloop.parentloop.counter}} هو عداد الحلقة الخارجية --> <!-- {{ forloop.counter }} هو عداد الحلقة الداخلية --> <li>{{ forloop.parentloop.counter }} - {{ item }}</li> {% endfor %} {% endfor %} يمكنك أيضا استعمال with لتخزين عداد الحلقة الخارجية واستعماله لاحقاً:
{% for parent in ParentItems %} {% with pcounter=forloop.counter %} {% for item in parent %} <!-- {{pcounter}} هو عداد الحلقة الخارجية --> <!-- {{ forloop.counter }} هو عداد الحلقة الداخلية --> <li>{{ pcounter }} - {{ item }}</li> {% endfor %} {% endwith %} {% endfor %}
-
إجابة مسعود زاهي سؤال في كيفية عمل إستعلام GROUP BY مع ORDER BY في جانغو Django؟ كانت الإجابة المقبولة
للحصول على أعلى 5 كُتاب من خلال نموذج Transaction ما عليك إلا استعمال:
from django.db.models import Count#نقوم باستيراد النموذج Count Transaction.objects.values('author') .annotate(total=Count('author')) .order_by('-total')[:5] الشرح:
نستخدم عادة values لحصر الأعمدة التي يتم إرجاعها في مجموعة النتائج، في مثالنا قمنا فقط باسترجاع العمود author. لإضافة عمود آخر للكائن الموجود في الQuerySet نقوم باستعمال annotate. في مثالنا قمنا بإضافة Count('author') وسميناه total. بعدها قمنا بترتيب ال QuerySet من الأكبر إلى الأصغر باستخدام order_by('-total'). للحصول على أعلى 5 كتاب فقط ماعلينا الا استخدام [:5]. -
إجابة مسعود زاهي سؤال في كيفية إستخدام إستثناء DoesNotExist في جانغو Django؟ كانت الإجابة المقبولة
المشكلة هو أنك تقوم باستدعاء الدالة get - التي بدورها تُظهِر الخطأ - قبل أن تصل إلى assertRaises.
الحل هو أن تقوم بالفصل بين الدالة get وبين قيمها (arguments) كما هو مبين في المرجع الخاص بال unitests.
from django.utils import unittest def test_user_can_delete_question_response(self): # ... self._driver.get("http://localhost:5000/questions/3") # هنا تقوم بالفصل بين الدالة وبين قيمها self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to question\'s answers.</p>') أو يوجد حل آخر هو استعمال with:
from django.utils import unittest def test_user_can_delete_question_response(self): # ... self._driver.get("http://localhost:5000/questions/3") with self.assertRaises(Answer.DoesNotExist): Answer.objects.get(body__exact = '<p>User can reply to question\'s answers.</p>') لمزيد من المعلومات يرجى زيارة المرجع على الرابط التالي TestCase.assertRaises
-
إجابة مسعود زاهي سؤال في كيفية استخدام الدالة stream_with_context لعمل عداد counter في فلاسك Flask؟ كانت الإجابة المقبولة
للوصول إلى مبتغاك يمكنك إستعمال كود جافاسكربت لتغيير قيمة <p> في كل مرة.
غير الكود في ملف index.html إلى ما يلي:
<p id=counter></p><!-- هنا تضع أي دي للوسم--> <!-- بعدها تغير محتواه باستعمال كود جافاسكربت--> <script> document.getElementById("counter").textContent="{{ i }}"; </script>