كيفية إنشاء نماذج Django

0 الأسهم
0
0
0
0

مقدمة

في هذا البرنامج التعليمي، سننشئ نماذج Django التي تُعرّف حقول وسلوكيات بيانات تطبيق المدونة التي سنخزّنها. تربط هذه النماذج بيانات تطبيق Django بقاعدة البيانات. هذا ما يستخدمه Django لإنشاء جداول قاعدة البيانات من خلال واجهة برمجة تطبيقات التعيين العلائقي للكائنات (ORM)، والتي تُسمى "النماذج".

المتطلبات الأساسية

يعد هذا البرنامج التعليمي جزءًا من سلسلة تطوير Django ويعد استمرارًا لهذه السلسلة.

إذا لم تكن تتابع هذه السلسلة، فإننا نفترض ما يلي:

  • لقد قمت بتثبيت Django الإصدار 4 أو أعلى.
  • لقد قمت بتوصيل تطبيق Django الخاص بك بقاعدة البيانات.
  • أنت تعمل مع نظام تشغيل قائم على Unix، ويفضل أن يكون خادم سحابي Ubuntu 22.04 لأن هذا هو النظام الذي قمنا باختباره.

نظرًا لأن هذا البرنامج التعليمي يتعامل بشكل أساسي مع نماذج Django، فقد تتمكن من المتابعة حتى إذا كان لديك إعداد مختلف.

الخطوة 1 - إنشاء تطبيق Django

لمتابعة فلسفة Django المعيارية، سنقوم بإنشاء تطبيق Django في مشروعنا يحتوي على جميع الملفات اللازمة لإنشاء موقع الويب للمدونة.

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

cd ~/my_blog_app
. env/bin/activate
cd blogr code... */

من هناك، دعنا ننفذ هذا الأمر:

python manage.py startapp blogsite

يقوم هذا البرنامج بإنشاء موقع مدونتنا بالإضافة إلى الدليل.

في هذه المرحلة من سلسلة البرامج التعليمية، سيكون لديك هيكل الدليل التالي لمشروعك:

my_blog_app/
└── blog
├── blog
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-38.pyc
│ │ ├── settings.cpython-38.pyc
│ │ ├── urls.cpython-38.pyc
│ │ └── wsgi.cpython-38.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── blogsite
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py

الملف الذي سنركز عليه في هذا البرنامج التعليمي سيكون ملف models.py، والذي يقع في دليل المدونة الخاص بالموقع.

الخطوة 2 – إضافة قوالب المنشورات

أولاً، علينا فتح ملف models.py وتعديله ليحتوي على الكود اللازم لإنشاء نموذج Post. يحتوي نموذج Post على حقول قاعدة البيانات التالية:

  • العنوان – عنوان تدوينة المدونة.
  • Slug – المكان الذي يتم فيه تخزين عناوين URL الصالحة لصفحات الويب وإنشاؤها.
  • المحتوى - المحتوى النصي للمدونة.
  • create_on – تاريخ إنشاء المنشور.
  • المؤلف - الشخص الذي كتب المنشور.

انتقل الآن إلى الدليل الذي يوجد به ملف models.py.

cd ~/my_blog_app/blog/blogsite

استخدم الأمر cat لعرض محتويات الملف في محطتك الطرفية.

cat models.py

يجب أن يحتوي الملف على الكود التالي الذي يقوم باستيراد النماذج، بالإضافة إلى تعليق يشرح ما يتم وضعه في ملف models.py هذا.

from django.db import models
# Create your models here.

باستخدام محرر النصوص المفضل لديك، أضف الكود التالي إلى ملف models.py. سنستخدم nano كمحرر نصوص، ولكن يمكنك استخدام أي محرر تفضله.

nano models.py

في هذا الملف، تمت إضافة الكود اللازم لاستيراد نماذج واجهة برمجة التطبيقات (API)، ويمكننا حذف التعليق أدناه. بعد ذلك، نستورد slugify لإنشاء عناوين slug من السلاسل النصية، ومستخدم Django للمصادقة، والعكس من django.urls لمزيد من المرونة في إنشاء عناوين URL.

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse

بعد ذلك، أضف دالة فئة تحتوي على حقول قاعدة البيانات التالية: العنوان، والعنوان الفرعي، والمحتوى، وتاريخ الإنشاء، والمؤلف، إلى فئة النموذج التي سنسميها Post. أضف هذه الحقول أسفل بيانات الاستيراد.

...
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()

بعد ذلك، نضيف دالةً لإنشاء رابط URL ودالةً لحفظ المنشور. هذا مهمٌّ جدًا، إذ يُنشئ رابطًا فريدًا يتوافق مع منشورنا الفريد.

...
def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])

def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)

الآن، علينا إخبار النموذج بكيفية فرز المنشورات وعرضها على صفحة الويب. سيُضاف منطق هذه العملية إلى فئة ميتا متداخلة. عادةً ما تحتوي فئة الميتا على منطق نموذجي مهم آخر غير مرتبط بتعريف حقل قاعدة البيانات.

...
class Meta:
ordering = ['created_on']

def __unicode__(self):
return self.title

أخيرًا، نضيف نموذج التعليق إلى هذا الملف. يتضمن ذلك إضافة فئة أخرى تُسمى التعليق، تحمل علامة models.Models في توقيعها، وتحديد حقول قاعدة البيانات التالية:

  • الاسم - اسم الشخص الذي يرسل التعليق.
  • البريد الإلكتروني – عنوان البريد الإلكتروني للشخص الذي يرسل التعليق.
  • النص - نص التعليق نفسه.
  • المنشور – المنشور الذي تم من خلاله تقديم التعليق.
  • create_on – عندما تم إنشاء التعليق.
...
class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)

في هذه المرحلة، سيكون ملف models.py مكتملًا. تأكد من أن ملف models.py يطابق ما يلي:

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse


class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()

def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])

def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)

class Meta:
ordering = ['created_on']

def __unicode__(self):
return self.title


class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)

تأكد من حفظ الملف وإغلاقه. إذا كنت تستخدم برنامج nano، يمكنك القيام بذلك بالضغط على CTRL وX، ثم Y، ثم ENTER.

مع تشغيل ملف models.py، يمكننا تحديث ملف settings.py الخاص بنا.

الخطوة 3 – تحديث الإعدادات

بعد إضافة النماذج إلى تطبيقنا، نحتاج إلى إعلام مشروعنا بوجود تطبيق موقع المدونة الذي أضفناه للتو. نقوم بذلك بإضافته إلى قسم INSTALLED_APPS في ملف settings.py.

انتقل إلى الدليل الذي يوجد به ملف settings.py الخاص بك.

cd ~/my_blog_app/blog/blog

من هنا، افتح ملف settings.py الخاص بك باستخدام nano، على سبيل المثال.

nano settings.py

من خلال فتح الملف، قم بإضافة تطبيق مدونة موقعك إلى قسم INSTALLED_APPS في الملف، كما هو موضح أدناه.

# Application definition
INSTALLED_APPS = [
'blogsite',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

مع إضافة تطبيق مدونة الموقع، يمكنك حفظ الملف والخروج.

وفي هذه المرحلة، أصبحنا مستعدين للمضي قدمًا في تنفيذ هذه التغييرات.

الخطوة 4 – تنفيذ الترحيل

بعد إضافة نماذج النشر والتعليق، فإن الخطوة التالية هي تطبيق هذه التغييرات حتى يتعرف عليها مخطط قاعدة بيانات MySQL ويقوم بإنشاء الجداول اللازمة.

أولاً، علينا تجميع تغييرات نموذجنا في ملفات ترحيل منفصلة باستخدام أمر makemigrations. هذه الملفات تشبه الالتزامات في نظام تحكم الإصدارات مثل Git.

الآن، إذا ذهبت إلى ~/my_blog_app/blog/blogsite/migrations وشغّلت الأمر ls، ستلاحظ وجود ملف __init__.py واحد فقط. سيتغير هذا عند إضافة عمليات الترحيل.

انتقل إلى دليل المدونة باستخدام cd، كما هو موضح أدناه:

cd ~/my_blog_app/blog

ثم قم بتشغيل الأمر makemigrations في manager.py.

python manage.py makemigrations

يجب أن تحصل بعد ذلك على الإخراج التالي في نافذة المحطة الطرفية الخاصة بك:

Output
Migrations for 'blogsite':
blogsite/migrations/0001_initial.py
- Create model Post
- Create model Comment

هل تذكر عندما ذهبنا إلى /~/my_blog_app/blog/blogsite/migrations ووجدنا ملف __init__.py فقط؟ إذا عدنا إلى هذا المجلد الآن، فسنلاحظ إضافة عنصرين آخرين: __pycache__ و0001_initial.py. تم إنشاء ملف 0001_initial.py تلقائيًا عند تشغيل makemigrations. سيتم إنشاء ملف مشابه في كل مرة تُشغّل فيها makemigrations.

إذا كنت تريد قراءة محتويات الملف، فما عليك سوى تشغيل 0001_initial.py من الدليل الذي يوجد فيه.

الآن انتقل إلى ~/my_blog_app/blog:

cd ~/my_blog_app/blog

بعد إنشاء ملف ترحيل، نحتاج إلى تطبيق التغييرات التي تصفها هذه الملفات على قاعدة البيانات باستخدام أمر migrate. لكن أولاً، لنتحقق من عمليات الترحيل الحالية باستخدام أمر showmigrations.

python manage.py showmigrations
Output
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
blogsite
[ ] 0001_initial
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial

ستلاحظ أن جميع عمليات الترحيل تم فحصها، باستثناء عملية الترحيل الخاصة بـ 0001_initial التي أنشأناها باستخدام نماذج النشر والتعليق.

لنتحقق الآن من عبارات SQL التي تُنفَّذ بعد انتهاء عمليات الترحيل باستخدام الأمر التالي. يأخذ الأمر الترحيل وعنوانه كمعامل:

python manage.py sqlmigrate blogsite 0001_initial

يظهر أدناه استعلام SQL الفعلي الذي يتم تنفيذه خلف الكواليس.

Output
--
-- Create model Post
--
CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL);
--
-- Create model Comment
--
CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `post_id` integer NOT NULL);
ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);

لنبدأ الآن بتشغيل عمليات الترحيل لتطبيقها على قاعدة بيانات MySQL الخاصة بنا.

python manage.py migrate

سوف نحصل على الناتج التالي:

Output
Operations to perform:
Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
Applying blogsite.0001_initial... OK

لقد قمت الآن بتطبيق عمليات الهجرة الخاصة بك بنجاح.

من المهم أن تتذكر أنه، كما هو مذكور في وثائق Django، هناك ثلاثة تحذيرات بشأن ترحيل Django مع MySQL كبرنامج خلفي.

  • لا يوجد دعم للمعاملات المتعلقة بعمليات تغيير المخطط. بمعنى آخر، في حال فشل عملية الترحيل، يجب عليك تحديد التغييرات التي أجريتها يدويًا لإجراء عملية ترحيل أخرى. لا توجد طريقة للرجوع إلى نقطة سابقة قبل إجراء أي تغييرات على عملية الترحيل الفاشلة.
  • في معظم عمليات تغيير المخططات، يُعيد MySQL كتابة الجداول بالكامل. في أسوأ الأحوال، يتناسب تعقيد الوقت مع عدد الصفوف في الجدول المطلوب إضافة أو إزالة أعمدة. وفقًا لوثائق Django، قد يستغرق هذا الأمر دقيقة واحدة لكل مليون صف.
  • في MySQL، توجد حدود صغيرة لطول أسماء الأعمدة والجداول والفهارس. كما يوجد حد أقصى لحجم جميع الأعمدة ومجلدات الفهارس. بينما تدعم بعض الواجهات الخلفية الأخرى الحدود الأعلى المُنشأة في Django، لا يُمكن إنشاء الفهارس نفسها باستخدام واجهة MySQL الخلفية.

بالنسبة لأي قاعدة بيانات تفكر في استخدامها مع Django، تأكد من موازنة إيجابيات وسلبيات كل منها.

الخطوة 5 - التحقق من مخطط قاعدة البيانات

بمجرد اكتمال عملية الترحيل، نحتاج إلى التحقق من نجاح إنشاء جداول MySQL التي أنشأناها من خلال نماذج Django.

للقيام بذلك، قم بتشغيل الأمر التالي في المحطة الطرفية لتسجيل الدخول إلى MySQL.

mysql blog_data -u djangouser

الآن، حدد قاعدة بيانات blog_data. إذا كنت لا تعرف أي قاعدة بيانات تستخدمها، يمكنك عرض جميع قواعد البيانات باستخدام SHOW DATABASES. في SQL

USE blog_data;

ثم اكتب الأمر التالي لعرض الجداول.

SHOW TABLES;

يجب أن يكشف استعلام SQL هذا عن التالي:

Output
+----------------------------+
| Tables_in_blog_data |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| blogsite_comment |
| blogsite_post |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
12 rows in set (0.01 sec)

تتضمن الجداول blogsite_comment وblogsite_post. هذه نماذج أنشأناها بأنفسنا. لنتأكد من احتوائها على الحقول التي حددناها.

DESCRIBE blogsite_comment;
Output
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(42) | NO | | NULL | |
| email | varchar(75) | NO | | NULL | |
| website | varchar(200) | YES | | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| post_id | int | NO | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
DESCRIBE blogsite_post;
Output
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| slug | varchar(255) | NO | UNI | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| author | longtext | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

لقد تأكدنا من أن جداول قاعدة البيانات تم إنشاؤها بنجاح من عمليات نقل نموذج Django الخاصة بنا.

يمكنك إغلاق MySQL باستخدام CTRL + D وعندما تكون مستعدًا للخروج من بيئة Python الخاصة بك، يمكنك تشغيل أمر التعطيل:

deactivate

يؤدي تعطيل بيئة التطوير إلى إرجاعك إلى سطر أوامر المحطة الطرفية.

نتيجة

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

قد يعجبك أيضاً