הקדמה
בשיעור הקודם, " איך ליצור אפליקציה ב-Django ולחבר אותה למסד נתונים," כיסינו איך ליצור מסד נתונים ב-MySQL, כיצד ליצור ולהתחיל אפליקציה ב-Django, וכיצד לחבר אותה למסד נתונים ב-MySQL.
בשיעור זה, ניצור את המודלים של Django שמגדירים את השדות וההתנהגויות של נתוני האפליקציה "בלוג" שנאחסן. מודלים אלו ממפים את הנתונים מאפליקציה Django שלך למסד הנתונים. זהו מה ש-Django משתמשת בו כדי ליצור את טבלאות המסד נתונים דרך API של התמרת עצמים אובייקטים (ORM), הידוע גם בשם "מודלים".
דרישות מוקדמות
השיעור הזה הוא חלק מסדרת פיתוח Django והוא המשך של סדרה זו.
אם לא עקבת אחרי הסדרה, אנו עושים את ההנחות הבאות:
- יש לך Django בגרסה 4 ומעלה מותקנת.
- אתה חיברת את האפליקציה שלך ב-Django למסד נתונים. אנו משתמשים ב-MySQL, ואתה יכול להשיג את החיבור הזה על ידי מעקב אחרי חלק שני של סדרת ה-Django, "איך ליצור אפליקציה ב-Django ולחבר אותה למסד נתונים".
- אתה עובד עם מערכת הפעלה מבוססת Unix, רצוי שתהיה זו שרת ענן Ubuntu 22.04 כפי שבדקנו. אם ברצונך להגדיר את Django בסביבה דומה, אנא הפנה להדרכתנו, "איך להתקין את Django ולהגדיר סביבת פיתוח על Ubuntu 22.04".
מכיוון שההדרכה הזו עוסקת בעיקר בדגמים של Django, ייתכן שתוכל לעקוב גם אם יש לך הגדרה מעט שונה.
שלב 1 — צור אפליקציה ב-Django
כדי להיות עקביים עם פילוסופיית ה-Django לגבי המודולריות, ניצור אפליקציה ב-Django בתוך הפרויקט שלנו שתכיל את כל הקבצים הדרושים ליצירת האתר בלוג.
כל פעם שאנו מתחילים לעבוד ב-Python וב-Django, עלינו להפעיל את סביבת הפיתוח שלנו ולהתקדם לתיקייה הראשית של האפליקציה. אם עקבת אחרי הסדרה, תוכל להשיג זאת על ידי הקלדת הפקודה הבאה.
- cd ~/my_blog_app
- . env/bin/activate
- cd blog
משם נריץ את הפקודה הבאה:
- python manage.py startapp blogsite
הדרך ליצירת האפליקציה שלנו כוללת יצירת תיקייה בשם 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
, הנמצא בתיקייה blogsite
.
שלב 2 — הוסף את מודל הפוסט
יש צורך ראשית לפתוח ולערוך את קובץ models.py
כך שיכיל את הקוד ליצירת מודל Post
. מודל Post
יכיל את השדות הבאים בבסיס הנתונים:
title
— כותרת הפוסט בבלוג.slug
— מקום שבו יישמרו ויפורטו כתובות URL תקפות לעמודי האינטרנט.content
— התוכן הטקסטואלי של הפוסט בבלוג.created_on
— התאריך בו נוצר הפוסט.author
— הכותב של הפוסט.
עכשיו, נכנס לתיקייה בה נמצא קובץ models.py
.
- cd ~/my_blog_app/blog/blogsite
נשתמש בפקודת cat
כדי להציג את תוכן הקובץ בטרמינל.
- cat models.py
הקובץ צריך להכיל את הקוד הבא, המייבא מודלים, יחד עם הערה שמתארת מה יש למקם בקובץ models.py
זה.
from django.db import models
# יצירת המודלים שלך כאן.
השתמשו בעורך הטקסט המועדף עליכם כדי להוסיף את הקוד הבא לקובץ models.py
. אנו נשתמש ב־nano
כעורך הטקסט שלנו, אך אתם מוזמנים להשתמש במה שתעדיפו.
- nano models.py
בתוך קובץ זה, קוד לייבוא של API המודלים כבר נוסף, ואפשר למחוק את ההערה שבמשך. לאחר מכן נייבא את slugify
כדי ליצור slugs ממחרוזות, את User
של Django למערכת האימות, ואת reverse
מ־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
, עם שדות מסד נתונים הבאים: title
, slug
, content
, created_on
ו־author
. נוסיף אותם מתחת להצהרות הייבוא.
...
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)
עכשיו, עלינו לספר למודל כיצד הפוסטים ייסדרו ויתצגו בדף האינטרנט. הלוגיקה לכך תתווסף למחלקת Meta
פנימית מקוננת. מחלקת ה־Meta
בדרך כלל מכילה לוגיקה רבה של מודל שאינה קשורה להגדרת שדות מסד הנתונים.
...
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
לבסוף, נוסיף את מודל התגובות (Comment
) לקובץ זה. זה כולל הוספת מחלקה נוספת בשם Comment
עם models.Models
בחתימתו והשדות מסד נתונים הבאים מוגדרים:
name
— שם האדם שמפרסם את התגובה.דואר אלקטרוני
– כתובת הדואר האלקטרוני של האדם שמפרסם את התגובה.טקסט
– הטקסט של התגובה עצמה.פוסט
– הפוסט שבו נעשתה התגובה.נוצר ב
– הזמן בו נוצרה התגובה.
...
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)
ודא ששמרת וסגרת את הקובץ. אם אתה משתמש בננו, תוכל לעשות זאת על ידי הקלדת CTRL
ואז X
, אז Y
, אז ENTER
.
עם קובץ ה-models.py
מוגדר, אנו יכולים להמשיך ולעדכן את קובץ ה-settings.py
שלנו.
שלב 3 — עדכון ההגדרות
כעת שהוספנו מודלים לאפליקציה שלנו, עלינו ליידע את הפרויקט שלנו על קיום האפליקציה blogsite
שהוספנו לאחרונה. אנו עושים זאת על ידי הוספתה לסעיף INSTALLED_APPS
בתוך settings.py
.
נווט לתיקייה בה קובץ ה-settings.py
שלך ממוקם.
- cd ~/my_blog_app/blog/blog
מכאן, פתח את קובץ ה-settings.py
שלך, לדוגמה באמצעות ננו.
- nano settings.py
עם הקובץ פתוח, הוסף את האפליקציה שלך blogsite
לסעיף INSTALLED_APPS
שבקובץ, כפי שמצויין למטה.
# הגדרת האפליקציות
INSTALLED_APPS = [
'blogsite',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
עם האפליקציה blogsite
שנוספה, אתה יכול לשמור ולצאת מהקובץ.
בנקודה זו, אנחנו מוכנים להמשיך וליישם את השינויים הללו.
שלב 4 – לבצע העברות
עם המודלים שלנו Post
ו־Comment
נוספו, השלב הבא הוא ליישם את השינויים כך שסכימת מסד הנתונים שלנו MySQL
תזהה אותם ותיצור את הטבלאות הנדרשות.
ראשית, עלינו לארוז את השינויים במודל שלנו לקבצי העברה יחידים באמצעות הפקודה makemigrations
. קבצים אלו דומים לאלו של commits
במערכת בקרת גרסאות כמו Git.
כעת, אם תנוודו אל ~/my_blog_app/blog/blogsite/migrations
ותפעילו את ls
, תשימו לב שיש רק קובץ __init__.py
. זה ישתנה כאשר נוסיף את ההעברות.
שנה את התיקייה לתיקיית הבלוג באמצעות cd
, כך:
- cd ~/my_blog_app/blog
ואז הפעילו את הפקודה makemigrations
על manage.py
.
- python manage.py makemigrations
תקבל את הפלט הבא בחלון הטרמינל שלך:
OutputMigrations 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
.
הרץ less 0001_initial.py
מהתיקייה בה הוא נמצא אם ברצונך לקרוא מה יש בקובץ.
כעת נווט אל ~/my_blog_app/blog
:
- cd ~/my_blog_app/blog
מכיוון שיש לנו קובץ המיגרציה, עלינו להחיל את השינויים שהם מתארים לבסיס הנתונים באמצעות הפקודה migrate
. אך קודם נבדוק אילו מיגרציות קיימות כרגע, באמצעות הפקודה showmigrations
.
- python manage.py showmigrations
Outputadmin
[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
שיצרנו עם המודלים Post
ו־Comment
.
כעת נבדוק אילו פקודות SQL
יושגו בעת ביצוע המיגרציות, באמצעות הפקודה הבאה. היא מקבלת את המיגרציה ואת כותרת המיגרציה כארגומנט:
- python manage.py sqlmigrate blogsite 0001_initial
מטה מוצגת השאילתת SQL
האמיתית שנעשית מאחורי הקלעים.
Output--
-- יצירת מודל 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);
--
-- יצירת מודל 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
נקבל את הפלט הבא:
OutputOperations to perform:
Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
Applying blogsite.0001_initial... OK
כעת הגעת להפעיל את המעברים שלך בהצלחה.
חשוב לזכור כי יש שלוש נקודות לשימור בדקת המעברים של Django עם MySQL כבסיס הנתונים שלך, כפי שמצוין במסמך הטכני של Django.
- חוסר תמיכה בעסקאות שמסביב לפעולות שינוי בסכימה. במילים אחרות, אם המעבר נכשל בהצלחה, יהיה עליך לבטל ידנית את השינויים שביצעת כדי לנסות מעבר נוסף. אין אפשרות לגלול לנקודה קודמת, לפני שנעשו שינויים במעבר הנכשל.
- לרוב הפעולות של שינוי בסכימה, MySQL יכתוב מחדש תצורת טבלאות. במקרה הגרוע, יחס הזמן יהיה פרופורציונלי למספר השורות בטבלה להוספת או הסרת עמודות. על פי תיעוד Django, זה יכול להיות כה איטי כדקה למיליון שורות.
- ב-MySQL יש הגבלות קטנות על אורכי שמות לעמודות, טבלאות ואינדקסים. יש גם הגבלה על גודל המשולב של כל העמודות והכיסוי של האינדקסים. בעוד שמספר מסדי נתונים אחרים יכולים לתמוך בהגבלות גבוהות שנוצרו ב-Django, אינדקסים אלו יכשלו להיות נוצרים עם MySQL כבסיס נתונים במקום.
לכל מסד נתונים שתשקול לשימוש עם Django, חשוב לשקול את היתרונות והחסרונות של כל אחד.
שלב 5 — אמת את סכימת המסד נתונים
עם המעברים השלמים, עלינו לוודא את הייצוב המוצלח של הטבלאות של MySQL שיצרנו דרך מודלי Django שלנו.
כדי לעשות זאת, הריצו את הפקודה הבאה בטרמינל כדי להתחבר ל-MySQL. נשתמש ב־djangouser
שיצרנו ב־מדריך הקודם.
- 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
וכאשר תרצו לצאת מהסביבה של פייתון, תוכלו להריץ את הפקודה deactivate
:
- deactivate
השבתת הסביבת התכנות שלכם תחזיר אתכם לציוד הפקודה בטרמינל.
מסקנה
במדריך זה, הוספנו בהצלחה מודלים עבור פונקציונליות בסיסית ביישום אינטרנטי של בלוג. למדת כיצד לכתוב מודלים, כיצד עובדות המיגרציות, והתהליך של תרגום מודלי Django לטבלאות בסיס נתונים ב MySQL.
Source:
https://www.digitalocean.com/community/tutorials/how-to-create-django-models