اذهب إلى المحتوى

Bassam Ahmed3

الأعضاء
  • المساهمات

    52
  • تاريخ الانضمام

  • تاريخ آخر زيارة

كل منشورات العضو Bassam Ahmed3

  1. يمكنك إتباع الخطوات التالية لتثبيت لغة بايثون على نظام ابونتو في حاسوبك : قم فتح موجة الأوامر Terminal و اكتب الأمر التالي للتأكد من تواجد نسخة بايثون مثبته افتراضياً مع النظام أم لا python --version إذا ظهر لك رد مثل الآتي مع إختلاف رقم النسخة فإن لغة بايثون مثبتة على النظام بالفعل Python 3.10.0 حيثُ يُمكنك التحديث بشكل عام من خلال الأمر التالي : sudo apt-get update إذا تم التأكد من عدم تواجد لغة بايثون فيمكنك التثبيت المباشر من خلال الأمر التالي إذا أردت تثبيت الإصدار الثاني من اللغة : sudo apt-get install python أو الأمر التالي لتثبيت الإصدار الثالث من اللغة : sudo apt-get install python3 أو يمكنك تثبيت إصدار محدد بالرقم على سبيل المثال : sudo apt install python3.9 ملحوظة هامة : أحياناً يحدث خطأ خلال التثبيت لذلك يمكن تثبيت بعض الإحتياجات الضرورية لتشغيل اللغة على جهازك من خلال الأمر التالي ثم المحاولة مُجدداً : sudo apt install software-properties-common sudo add-apt-repository ppa:deadsnakes/ppa
  2. يمكنك إستخدام ذلك الكود لحذف الملفات بعد إزالة الكائن من جداول البيانات : class DeleteImage(models.Model): name = models.CharField(blank=True, max_length=100) image = models.ImageField(upload_to='/pictures/', blank=True) def delete(self, using=None, keep_parents=False): self.image.storage.delete(self.image.name) super().delete() حيثُ تم إنشاء class بشكل إفتراضي يحتوي على حقلين name / image و لكننا قمنا بإنشاء دالة إفتراضية أسفله تحتوي على كود يهدف إلى ( حذف الملف بمجرد حذف الكائن المرتبط به )
  3. يمكنك إنشاء ملف context processor داخل django و يقوم النظام تلقائياً بإستدعاء ذلك الملف و تنفيذه في كل request يتم على السيرفر حيثُ يمكن إتباع الخطوات الآتيه : قم بإنشاء ملف يحمل الإسم الذي تفضله على سبيل المثال private_context_processor.py داخل التطبيق قم بفتح الملف و استدعي النموذج المراد التطبيق عليه من ملف models.py كالتالي : from .models import Category def categories_everywhere(request): my_categories = Category.objects.all() return {'my_categories': my_categories} 3 . نقوم بتسجيل السطر 'home.private_context_processor.categories_everywhere' داخل اعدادات المشروع settings.py في قسم TEMPLATES كالتالي : TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.i18n', 'django.contrib.messages.context_processors.messages', 'home.private_context_processor.categories_everywhere', ], }, }, ] التفاصيل للسطر الذي تم تسجيلة : home هو إسم التطبيق الذي تم إنشاء ملف private_context_processor.py به private_context_processor هو اسم الملف الذي قمنا بإنشائه categories_everywhere هي الدالة التي كتبناها داخل الملف 4. ثم نذهب لأي ملف html داخل اي تطبيق في المشروع بشكل عام و نستدعي الـ context الذي يقوم بالتعويض عن الداله و يرجع بها في تلك الحاله my_categories حيثُ يُمكنك عمل for loop أو اي أمر من أوامر بايثون المتوافقة مع ال templates داخل التطبيق
  4. هناك مكتبة كاملة في django تقوم بذلك الأمر و هي django import export يمكن تثبيتها عن طريق الأمر التالي في موجة الأوامر بعد تفعيل البيئة الإفتراضية virtualenv pip install django-import-export ثم قم بإضافة المكتبه كتطبيق ضمن التطبيقات المثبته في المشروع بملف settings.py داخل خانة INSTALLED_APPS 'import_export' قم بالتوجه لملف admin.py داخل التطبيق الذي يوجد به النموذج المراد تصدير أو إستيراد البيانات له ثم قم بإستيراد السطر التالي لإستدعاء مكتبة import export from import_export.admin import ImportExportModelAdmin و لكن في تلك الحاله لا يمكن تسجيل النموذج بالشكل الإفتراضي الخاص به حيثُ يجب تغيير طريقة تسجيلة على سبيل المثال أريد تسجيل النموذج Volunteering في ملف admin.py حيثُ نقوم بتسجيله بالشكل التالي بالطريقة الإفتراضية from django.contrib import admin from .models import Volunteering from import_export.admin import ImportExportModelAdmin admin.site.register(Volunteering) لكن في حال أردت إستخدام مكتبة import export يجب تعديل طريقة التسجيل لتكن بالشكل التالي : from django.contrib import admin from .models import Volunteering from import_export.admin import ImportExportModelAdmin @admin.register(Volunteering) class VolImportExport(ImportExportModelAdmin): pass ملحوظه : يمكن تعديل إسم الـ class بالإسم الذي تريد فهو متغير أما ما بين الأقواس فهو ثابت كذلك ال decorator فوق ال class ثابت أيضاً ثم تقوم بفتح لوحة تحكم الموقع الخاص بك بشكل إفتراضي ثم تتجه للنموذج الذي تريد فيه استدعاء به مكتبة import export فستجد بجانب " إضافة " انه ظهر أزرار جديده " تصدير , إستيراد " مثل الصورة المرفقة حيثُ يمكنك تصدير او استيراد البيانات للنموذج مباشرة عن طريق العديد من الصيغ مثل csv , xls , xlsx , json , yaml و غيرها الكثير
  5. الخطوه التي اتخذتها صحيحة بالفعل يتبقى فقط : إضافة الآي بي 192.168.8.186 إلى ALLOWED_HOSTS أو ما يعادلها في إعدادات المشروع الخاص بك فتح الآي بي 192.168.8.186:8000 في المتصفح على أي جهاز متصل بالشبكة
  6. فكرة فتح الـ local host على الهاتف او الأجهزه الأخرى المتصلة بنفس الشبكة سهل تطبيقها مع بعض التعديلات البسيطة حيثُ في البداية تأكد من فتح ال cmd أو موجه الأوامر الخاص بك ثم كتابة الأمر ' ipconfig ' ليظهر الآي بي الخاص بشبكتك IPv4 Address فهو آي بي متغير و ليس ثابت و لكن في ذلك الشرح سأشرح على الآي بي الذي ظهر لي في موجه الأوامر لتصفح الموقع على شبكتك يختلف الأمر التالي من بيئه تطوير لاخرى لكنها بالنهاية نفس فكرة فتح السيرفر المحلي و سأستخدم python / django على سبيل المثال يمكن تشغيل السيرفر المحلي بالطريقة المعتاده python manage.py runserver و لكن الإختلاف هنا هو كتابة الآي بي الخاص بالشبكة بشكل عام بدل من الإكتفاء بتشغيل السيرفر على الجهاز المحلي ثم يليه المنفذ الذي تريد التشغيل عليه بحيث يكون كالتالي python manage.py runserver 192.168.1.105:8000 ثم اضغط Enter قبل كتابة 192.168.1.105:8000 لتصفح الموقع الخاص بك في الحاسوب أو اي جهاز اخر متصل بالشبكه يجب إضافة عنوان الآي بي المتغير في تلك الحاله 192.168.1.105 إلى إعدادات الموقع في django على سبيل المثال يتم كتابة الآي بي داخل ALLOWED_HOSTS = ["192.168.1.105"] في ملف settings.py و من ثم يمكنك فتح الآي بي يليه رقم المنفذ 192.168.1.105:8000 على اي جهاز متصل بالشبكه لتصفح الموقع الخاص بك بسهوله ملاحظه عامة : نفس الطريقه هي ذاتها مع اختلاف الأوامر مع بيئة تطوير أو تقنيه لآخرى لكنها نفس الفكره العامه مع اختلاف الأسطر التي تكتب لتأتي بنفس النتيجه * لا تنسى مراجعة الصور بالمرفقات
  7. من حيث طريقة كتابة الكود فليس به خطأ و من المفترض به أن يعمل حيثُ أن القيمة صحيحة بالفعل created_at = models.DateField(_("Date"), default=datetime.now) و لكن للتأكيد يجب التأكد من إستدعاء كافة الأسطر لتشغيل الكود السابق بالطريقة الصحيحه حيثُ: تأكد من إستدعاء الأسطر التاليه : import datetime from datetime import datetime كما يجب التأكد من استدعاء _ حيثُ قد تسبب بعض المشكلات البسيطة في حال إستدعاؤها بشكل غير صحيح عن طريق السطر التالي : from django.utils.translation import gettext as _ كما يرجى التأكد من ضبط التاريخ في جهاز الحاسوب الخاص بك لأنه يأخذ القيمة الإفتراضية منه لذلك يجب التأكد من صحة التاريخ و انه على الوضع " ظبط تلقائي "
  8. يمكنك إستخدام SUM لحساب مجموع المنتجات عن طريق الكود التالي : def total_sale(self): total = Sale.objects.aggregate(TOTAL = Sum('amount'))['TOTAL'] return total بالعلم أن " amount " يتم إستبداله بإسم النموذج التي تريد حسابه و يتم إستبدال " Sale " بالنموذج العام الخاص بالمنتجات هناك طريقه اخرى إضافيه في Django لحساب مجموع المنتجات حيثُ يُمكنك إستخدام F و annotate على سبيل المثال : from django.db.models import F tickets = Ticket.objects.all().annotate(total_price=F('total_quantity') * F('price')) for t in tickets: print(t.total_price) كما يمكنك دمج إستخدام F , SUM إذا كنت تريد حساب مجموع المنتجات المتواجده فعلياً في الـ Cart عن طريق التالي : from django.db.models import F, Sum def cart(request): cart = Cart.objects.annotate( price=Sum(F('orderitem__item__price') * F('orderitem__quantity')) ).get( order_user=request.user ) cart.total = cart.price cart.save() فهناك العديد من الطرق
  9. يمكنك تجربة ذلك الكود لجلب العناصر بترتيب تصاعدي Reserved.objects.filter(client=client_id).order_by('check_in') بالعلم أن client = client هي متغيره يمكن إستبدالها على سبيل المثال حسب المستخدم في مشروعك سواء id او slug و أ، check_in هو الحقل الذي ترغب من الإرجاع منه مثلاً حقل يحتوي على تاريخ و تريد الترتيب من الأحدث للأقدم أو العكس و ذلك الكود إضافي للترتيب التنازلي Reserved.objects.filter(client=client_id).order_by('-check_in')
  10. OneToManyField أو ما يطلق عليه ForeignKey هو نوع من الحقول في models.py هدفه الربط ما بين شيء واحد فقط و شيء آخر مرتبط به على سبيل المثال ( المستخدم الواحد يمتلك العديد من المنشورات و لكن لا يمكن أن يكون للمنشور الواحد أن يمتلكه أكثر من مستخدم ) ManyToManyField هو نوع من الحقول يربط بين العديد من الأشياء و بين العديد من الأشياء ( كثير إلى كثير ) على سبيل المثال ( المستخدم الواحد لديه في حسابه العديد من الجروبات / المجموعات و يمكن للمجموعه أن تحتوي على العديد من المستخدمين ) OneToOneField هو نوع المن الحقول يربط شيء واحد بالعديد من الأشياء على سبيل المثال ( المستخدم يمتلك صفحه شخصيه واحده فقط و الصفحه الشخصيه الواحده لا يمكن أن يمتلكها أكثر من مستخدم )
  11. الطريقة الأولى : يمكنك إستخدام abstract = True اسفل نموذج تقوم بإنشاؤه يحتوي على كافة الحقول المتكرر إستخدامها في عدة نماذج بدل من كتابتها مره اخرى في models.py مما يسهل من عملية الوصول لتلك الحقول و عدم زيادة حجم الملف على سبيل المثال هنا نلاحظ أن الحقل name متكرر في النموذجين School / Student : class School(models.Model): name = models.CharField(max_length=100) number = models.IntergerField() class Student(models.Model): name = models.CharField(max_length=100) Phone = models.IntergerField() حيثُ يُمكنك إنشاء نموذج موحد يحتوي على كافة الحقول التي يُعاد إستخدامها على سبيل المثال : class CommonInfo(models.Model): name = models.CharField(max_length=100) class Meta: abstract = True ثم بعد ذلك لا تعيد كتابة الحقل name مره اخرى في حال الرغبه في إعادة إستخدامه حيثُ يمكنك استدعاء النموذج CommonInfo بشكل مباشر في النموذج الجديد الذي ترغب أن يحتوي على الحقل name لتُصبح هكذا : class School(CommonInfo): number = models.IntegerField() class Student(CommonInfo): phone = models.IntegerField() تلك الطريقه ستقلل من عدد الأسطر المستخدمه و بالتالي إنخفاض حجم الملف models.py الطريقه الثانيه : يمكنك تقسيم التطبيقات في المشروع الواحد عن طريق الأمر python manage.py startapp newapp #بالعلم أن #newapp #هو متغير بإسم التطبيق الذي ترغب في انشاؤه و ذلك حتى يحتوي المشروع الواحد على عدة تطبيقات على سبيل المثال : تطبيق للحسابات تطبيق للمنشورات تطبيق للتعليقات تطبيق لصفحات حول الموقع و يكون لكل تطبيق ملف models.py الخاص به مما سيكون الأمر أكثر ترتيباً
  12. الفرق بين السطرين هو الآتي : السطر الأول : request.POST.get('KEY') سيقوم بإرجاع القيمة None إذا لم يكن المفتاح أو الكلمة المطلوب إستدعاؤها غير متوفره فهو سطر يقصد به أجلب تلك القيمه فإذا لم تكن متواجده فسيرجع بالرد None فهو مثل تماماً try , except try: x = request.POST['key'] except KeyError: x = None أما السطر الثاني : request.POST['KEY'] سيعطي خطأ Error بمجرد عدم تواجد المفتاح أو القيمة المطلوب إيجادها
  13. هناك 3 أنواع من طرق التعامل مع Forms في Django الطريقة الأولى : هي ال class الذي يُكتب في ملف forms.py و الذي يرث من forms.ModelForm بالإضافة لكتابة اسم النموذج Model الذي تريد تحويلة إلى Forms وذلك بعد إستدعاؤه و هذا النوع هدفه الأول هو تحويل النماذج models إلى forms بدلاً من كتابتها من جديد مثال : from django import forms from .models import Volunteering class VolunteeringForm(forms.ModelForm): class Meta : model = Volunteering fields = ['name' , 'phone' , 'email' , 'national_id' , 'address'] labels = { 'name' : ('Name | الأسم'), 'phone' : ('Phone | الهاتف'), 'email' : ('Email | البريد الإلكتروني'), 'national_id' : ('National ID | الرقم القومي'), 'address' : ('Address | العنوان'), } الطريقة الثانية : هي إنشاء Forms خاصة عن طريق class يرث من forms.Form بشكل مباشر على سبيل المثال : from django import forms class VolunteerForm(forms.Form): name = forms.CharField(max_length=100) phone = forms.IntegerField() email = forms.EmailField() national_id = forms.CharField(max_length = 14) address = forms.CharField(max_length=200) الطريقة الثالثه و هي لا ترتبط بملف forms.py او models.py و إنما إنشاء نماذج خاصة في ملف الـ HTML Template و إستقبال البيانات من تلك النماذج على ملف views.py عن طريق كتابة الأمر ذلك على سبيل المثال تريد استقبال بيانات ذلك النموذج من ملف HTML <form action="/your-name/" method="post"> <label for="your_name">Your name: </label> <input id="your_name" type="text" name="your_name" value="{{ current_name }}"> <input type="submit" value="OK"> </form> في تلك الحاله يجب إستخدام الأمر التالي في ملف views.py من أجل إستقبال البيانات من نموذج HTML عن طريق الأمر cleaned_data.get name = form.cleaned_data['name']
  14. يمكنك تثبيت قيمة الحقل عن طريق : from django.core.exceptions import ValidationError def validate_length(value,length=6): if len(str(value))!=length: raise ValidationError(u'%s is not the correct length' % value) from django.db import models class MyModel(models.Model): constraint_length_charField = models.CharField(validators=[validate_length] , max_length = 6) حيثُ أن تم تثبيت القيمه في داله و من ثم استدعاؤها في النموذج model الخاص بك من أجل التحقق منها و قد تلاحظ انه قد تم كتابة الأمر max_length مجدداً و ذلك حتى لا تحدث مشكله عن كتابة الأمرين python manage.py makemigrations / python manage.py migrate أي يجب تحديد قيمة الحقل في كلاً من : length في الداله المطلوب التحقق منها و max_length في الحقل
  15. يمكنك استخدام Django Signals و هي يوجد بها العديد من الخصائص التي تسمح بإستقبال الإشارات على سبيل المثال : عند إستقبال إشارة إنشاء مستخدم جديد في قاعدة البيانات قم بإنشاء صفحة شخصية خاصة بذلك المستخدم و ذلك يتم عن طريق استخدام أوامر الإستدعاء from django.db.models.signals import post_save from django.dispatch import receiver ثم نقوم بكتابة class الصفحة الشخصية للمستخدم تتضمن بعض البيانات الاختياريه مثل الاسم , العنوان , رقم الهاتف و غيرها ثم نضع django signals بعد ال class كالآتي بالعلم أن ال class الذي وضعنا بعده نموذج الإشارات هو Profile : @receiver(post_save , sender = User) def create_user_profile(sender , instance , created , **kwargs ): if created : Profile.objects.create(user = instance) فهناك العديد من الأوامر المستخدمه في نظام الإشارات في django لتتناسب مع كل فكرة يتم تطبيقها على سبيل المثال : pre_save : تستخدم في حال الرغبة في تنفيذ شيء قبل حفظ النموذج post_save : تستخدم في حال الرغبة في تنفيذ شيء بعد حفظ النموذج pre_delete : تستخدم في حال الرغبة في تنفيذ شيء قبل مسحة ( قبل حذف المستخدم قم بحذف المنشورات المتعلقه به ) m2m_changed : تستخدم في تتبع التغييرات في العلاقات المتعدده مثل ManyToManyField و يوجد بها العديد من الأدوات ( pre_add , post_add , pre_remove , post_remove , pre_clear , post_clear ) و غيرها من الأدوات لتسهيل تنفيذ الإشارات في حال حدوث أي تغيير في العلاقة
  16. هناك العديد من الأنواع المناسبة تحت فئة الـ 500 دولار على سبيل المثال : HP Notebook 15-dw3028ne الذي يحتوي على معالج core i3 ‎4.1 GHz و سعة تخزين 1 TB HDD و و ذاكرة تخزين عشوائية ( رام ) بسعة 4 جيجا بايت من نوع DDR4 بسعر يتراوح ما بين 470 - 500 دولار Lenovo IdeaPad 3 الجيل العاشر منه يحتوي على معالج core i3 1.2 GHz مع هارد 1 TB HDD و ذاكرة تخزين عشوائية ( رام ) بسرعة 4 جيجا بايت من نوع DDR4 بسعر يتراوح ما بين 450 - 500 دولار Asus E410MA-EK948T مع معالج Intel Celeron N4020 و سعة تخزين 256 جيجا بايت SSD و ذاكرة عشوائية ( رام ) 4 جيجا بايت من نوع DDR4 بسعر يتراوح ما بين 350 - 400 دولار Lenovo Chromebook Duet 3 بمعالج MediaTek® Helio P60T Processor 2.00 GHz, 8 Cores, 8 Threads مع ذاكرة تخزين عشوائية ( رام ) 4 جيجا بايت من نوع LPDDR4x و سعة تخزين 64 GB من نوع eMMC بسعر يتراوح ما بين 270 - 320 دولار بشكل عام يوجد العديد من الأنواع من شركات عديده و لكن تلك الأنواع التي انصحك بها إذا كنت ترغب في نوعية لاب توب تناسب استخدامك في مجال البرمجه و يكون سهل التعامل معها
  17. إنضمامك لفريق أمر رائع و ذلك الفريق يمكن أن يختلف فعلى سبيل المثال : فريق تطوعي فريق تحفيز فريق عمل الفريق التطوعي : يمكن الإنضمام له عن طريق البحث على الشركات التي تريد إنشاء مواقع و تعتبر ذلك نوع من تجربة المهارات البرمجية لديك عن طريق الدخول في بيئة تشبه فريق العمل الحقيقي الذي يؤهلك للعمل الخاص فيما بعد فالمشاريع أغلبها ستكون بدون مقابل لكنها ستكسبك خبرات كبيرة في المجال فريق التحفيز : عن طريق البحث على مواقع التواصل الإجتماعي على سبيل المثال لمجموعة من المهتمين بذات المجال " تعلم البرمجة , تعلم مهارة أو أكثر من مهاراتك " حيث ستكونون حافز لبعض من أجل إستمرار التعلم فريق العمل : أنصحك في البداية بتطوير مهاراتك فمثلاً إذا كنت تريد العمل كـ " Back End Developer " فيجب تحديد التقنية المستخدمة تحديداً على سبيل المثال PHP / Laravel - Python / Django و غيرها كذلك أنصحك في مجال Front End Developement أن تقوم بدراسة FrameWork مثل VueJs - Angular - React من أجل تعزيز مهاراتك و تحديدها بدقة لأن أغلب فرق العمل خاصة إذا كانوا داخل شركة خاصة يبحثون فقط على من يستطيع العمل و تطوير الشركة لذلك يجب عليك تحديد مهاراتك بدقة و تطويرها قبل البحث عن مستقلين أو الدخول إلى عمل خاص ... كل التوفيق
  18. البيئة الإفتراضية الهدف من تثبيتها و تثبيت المكتبات بها هي سهولة الوصول لإصدارات المكتبات المُثبته بها عن طريق الملف requirements.txt من الأمر pip freeze > requirements.txt إذا تستخدم Django القائم على لغة Python فبدون البيئة الإفتراضي ستكون كافة المشروعات على جهازك تستخدم نفس إصدارات المكتبات و يصعب التحكم بها مثل تعديلها على كافة المشروعات فالبيئة الإفتراضية تهدف لفصل كل مشروع بالمكتبات الخاصه به داخل بيئة إفتراضيه على سبيل المثال لديك 3 مشروعات عن طريق django المشروع الأول يعمل بإصدار django2 و الثاني django3 و الثالث django4 كذلك تفاصيل المكتبات مثل التالي : asgiref==3.4.1 beautifulsoup4==4.10.0 defusedxml==0.7.1 diff-match-patch==20200713 Django==3.2.8 django-bootstrap-form==3.4 django-bootstrap4==3.0.1 django-ckeditor==6.2.0 django-filter==21.1 django-import-export==2.7.1 django-js-asset==1.2.2 djangorestframework==3.13.1 et-xmlfile==1.1.0 fontawesome-free==5.15.4 importlib-metadata==4.10.0 Markdown==3.3.6 MarkupPy==1.14 odfpy==1.4.1 openpyxl==3.0.9 Pillow==8.4.0 pytz==2021.3 PyYAML==6.0 six==1.16.0 soupsieve==2.2.1 sqlparse==0.4.2 tablib==3.1.0 xlrd==2.0.1 xlwt==1.3.0 zipp==3.6.0 هذه مكتبات تم كتابتها من الأمر pip freeze > requirements.txt و هي متواجدة داخل الملف requirements.txt تلاحظ أن كل مكتبه بجانبها رقم الإصدار الخاص بها لإعادة تثبيت كافة السطور على الإستضافة بمجرد رفع الموقع الخاص بك لسهولة الوصول لنفس إصدارات المكتبات المستخدمه
  19. الصورة الأولى تعني أن التطبيق تم رفعة بالفعل و حالياً قيد المراجعة من قبل شركة جوجل لمراجعة ما إذا كان التطبيق يتبع معايير المجتمع و انه آمن بنسبة ١٠٠٪ السؤال الثاني بخصوص مراجعة التطبيق فعادة تتراوح مدة المراجعة إذا كانت تلك المرة الأولى يتم رفع بها تطبيق على حسابك ما بين ١ - ٧ أيام عمل و ما بين ١ - ٤ أيام عمل إذا لم تكن المرة الأولى لرفع تطبيقات و ما بين ٢٤ - ٣٦ ساعة عمل للموافقة على رفع تحديث لتطبيق على المنصة بالفعل
  20. لا يمكن إستخدام الأسطر البرمجية بشكل مباشر حيثُ يجب إستخدامها هكذا : class Post(models.Model): title = models.CharField(...) def get_content(self): return self.content class Meta: abstract = True و ذلك لأن في Django يتم وراثة و تعريف كل متغير من مكتبات تم تثبيتها مُسبقاً في بيئة django مثال إذا حذفت models.Model فلن يعمل السطر البرمجي لأنه يجب تعريف لـ django كيف يجب عليه أن يتعامل مع ال models حتى يسهل التعامل معها و تطبيقها في قاعدة البيانات المستخدمه في settings.py أما عن abstract = True فهي تهدف لعدم تكرار جدول البيانات مره اخرى في قاعدة بيانات django أي على سبيل المثال : class School(models.Model): name = models.CharField(max_length=100) number = models.IntergerField() class Student(models.Model): name = models.CharField(max_length=100) Phone = models.IntergerField() # نلاحظ هنا أن الحقل name مكرر نلاحظ أن الحقل name مُكرر في النموذجين و لمنع كتابة الحقول بشكل متكرر دائماً يتم إنشاء نموذج منفرد مثل : class CommonInfo(models.Model): name = models.CharField(max_length=100) class Meta: abstract = True لاحظت إضافة abstract = True حيث يتم وراثة ذلك النموذج عند انشاء النماذج بعد ذلك كالتالي : class School(CommonInfo): number = models.IntegerField() class Student(CommonInfo): phone = models.IntegerField() و عند تطبيق الأمرين python manage.py makemigrations و الأمر python manage.py migrate سيتم إنشاء الحقل name كأن تم كتابته في النموذجين و لكن بالأصل قمنا بوراثته من class كما لاحظت أن ال class ورث من CommonInfo لتوريث كافة الحقول به لأي نموذج يتم إستدعاؤه به
  21. الأمر بسيط حيث في البدايه 1 - يجب استدعاء تلك السطور في ملف models.py from django.core.files import File from urllib import request import os بالعلم أن السطر " import os " يمكن عدم استدعاؤه ( اختياري ) 2 - يتم إنشاء class في ملف models.py كالمثال التالي : class Item(models.Model): image_file = models.ImageField(upload_to='images') image_url = models.URLField() - حيثُ أن image_file من نوع ImageField وهو الحقل الذي يتم رفع به الصوره بشكل تقليدي و أن image_url من نوع URLField وهو يقبل إدخال الروابط فقط 3 - يتم تطبيق الفكره المُراد تطبيقها عن طريق كتابة الداله التاليه أسفل ال class الذي تم انشاؤه def get_remote_image(self): if self.image_url and not self.image_file: result = request.urlretrieve(self.image_url) self.image_file.save( os.path.basename(self.image_url), File(open(result[0], 'rb')) ) self.save() حيثُ أن تلك الداله تهدف إلى جعل الأمر منطقياً من خلال معادله بسيطه تٌفيد بأنها في حال وجود ملف للصوره تم رفعه في خانة " image_file " يتم تنزيل الملف من الرابط المتواجد داخل خانة " image_url " و حفظها و اعتبارها هي الصوره الأساسيه
×
×
  • أضف...