Cách tạo mô hình Django
Trong hướng dẫn trước, “ Cách tạo ứng dụng Django và kết nối nó với database ”, ta đã trình bày cách tạo database MySQL, cách tạo và khởi động ứng dụng Django cũng như cách kết nối nó với database MySQL.Trong hướng dẫn này, ta sẽ tạo các mô hình Django xác định các trường và hành vi của dữ liệu ứng dụng Blog mà ta sẽ lưu trữ. Các mô hình này ánh xạ dữ liệu từ ứng dụng Django của bạn với database . Đó là những gì Django sử dụng để tạo các bảng database thông qua API ánh xạ quan hệ đối tượng (ORM) của họ, được gọi là “mô hình”.
Yêu cầu
Hướng dẫn này là một phần của loạt bài Phát triển Django và là phần tiếp theo của loạt bài đó.
Nếu bạn chưa theo dõi loạt bài này, ta sẽ đưa ra các giả định sau:
- Bạn đã cài đặt Django version 3 trở lên.
- Bạn đã kết nối ứng dụng Django của bạn với database . Ta đang sử dụng MySQL và bạn có thể đạt được kết nối này theo phần hai của loạt bài về Django, “ Cách tạo ứng dụng Django và kết nối nó với database ”.
- Bạn đang làm việc với hệ điều hành dựa trên Unix, tốt nhất là server cloud Ubuntu 20.04 vì đây là hệ thống ta đã thử nghiệm. Nếu bạn muốn cài đặt Django trên một môi trường tương tự, vui lòng tham khảo hướng dẫn của ta , “ Cách cài đặt Django và cài đặt môi trường phát triển trên Ubuntu 20.04 .”
Vì hướng dẫn này chủ yếu liên quan đến các mô hình Django, bạn có thể làm theo ngay cả khi bạn có cài đặt hơi khác.
Bước 1 - Tạo ứng dụng Django
Để phù hợp với triết lý của Django về tính module , ta sẽ tạo một ứng dụng Django trong dự án của ta chứa tất cả các file cần thiết để tạo trang web blog.
Khi nào ta bắt đầu làm việc bằng Python và Django, ta nên kích hoạt môi trường ảo Python của bạn và chuyển vào folder root của ứng dụng. Nếu bạn đã theo dõi loạt bài này, bạn có thể đạt được điều này bằng lệnh nội dung sau.
- cd ~/my_blog_app
- . env/bin/activate
- cd blog
Từ đó, hãy chạy lệnh này:
- python manage.py startapp blogsite
Điều này sẽ tạo ứng dụng của ta cùng với một folder blogsite
.
Tại thời điểm này trong loạt bài hướng dẫn, bạn sẽ có cấu trúc folder sau cho dự án của bạn :
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
Tệp mà ta sẽ tập trung vào cho hướng dẫn này, sẽ là file models.py
, nằm trong folder blogsite
.
Bước 2 - Thêm mô hình bài đăng
Trước tiên, ta cần mở và chỉnh sửa file models.py
để file chứa mã tạo mô hình Post
. Mô hình Post
chứa các trường database sau:
-
title
- Tiêu đề của bài đăng trên blog. -
slug
- Nơi các URL hợp lệ được lưu trữ và tạo cho các trang web. -
content
-content
văn bản của bài đăng trên blog. -
created_on
- Ngày tạo bài đăng. -
author
- Người đã viết bài đăng.
Bây giờ, hãy chuyển vào folder chứa file models.py
.
- cd ~/my_blog_app/blog/blogsite
Sử dụng lệnh cat
để hiển thị nội dung của file trong terminal của bạn.
- cat models.py
Tệp phải có mã sau, mã này nhập các mô hình, cùng với chú thích mô tả những gì sẽ được đặt vào file models.py
.
from django.db import models # Create your models here.
Sử dụng editor yêu thích của bạn, thêm mã sau vào file models.py
. Ta sẽ sử dụng nano
làm editor của bạn , nhưng bạn có thể sử dụng bất cứ thứ gì bạn thích.
- nano models.py
Trong file này, mã để nhập API mô hình đã được thêm vào, ta có thể tiếp tục và xóa comment sau đó. Sau đó, ta sẽ nhập slugify
để tạo slugs từ các chuỗi, User
của Django để xác thực và reverse
từ django.urls
để giúp ta linh hoạt hơn với việc tạo URL.
from django.db import models from django.template.defaultfilters import slugify from django.contrib.auth.models import User from django.urls import reverse
Sau đó, thêm phương thức lớp vào lớp mô hình mà ta sẽ gọi là Post
, với các trường database sau, title
, slug
, content
, created_on
và author
. Thêm những điều này bên dưới báo cáo nhập khẩu của bạn.
... 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()
Tiếp theo, ta sẽ thêm chức năng tạo URL và chức năng lưu bài đăng. Điều này rất quan trọng, bởi vì điều này tạo ra một liên kết duy nhất để phù hợp với bài đăng duy nhất của ta .
... 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)
Bây giờ, ta cần cho người mẫu biết cách sắp xếp các bài viết và hiển thị trên trang web. Logic cho điều này sẽ được thêm vào một lớp Meta
lồng nhau bên trong. Lớp Meta
thường chứa logic mô hình quan trọng khác không liên quan đến định nghĩa trường database .
... class Meta: ordering = ['created_on'] def __unicode__(self): return self.title
Cuối cùng, ta sẽ thêm mô hình Comment
vào file này. Điều này liên quan đến việc thêm một lớp khác có tên Comment
với các models.Models
trong chữ ký của nó và các trường database sau được xác định:
-
name
- Tên của người đăng comment . -
email
- Địa chỉ email của người đăng comment . -
text
- Văn bản của chính comment . -
post
- Bài đăng mà comment đã được thực hiện. -
created_on
- Thời gian comment được tạo.
... 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)
Đến đây, models.py
sẽ hoàn tất. Đảm bảo rằng file models.py
của bạn trùng với các thông tin sau:
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)
Đảm bảo lưu file . Nếu bạn đang sử dụng nano, bạn có thể thực hiện bằng cách gõ CTRL
và X
, sau đó Y
, sau đó ENTER
.
Với file models.py
được cài đặt , ta có thể tiếp tục cập nhật file settings.py
.
Bước 3 - Cập nhật cài đặt
Bây giờ ta đã thêm các mô hình vào ứng dụng của bạn , ta phải thông báo cho dự án của bạn về sự tồn tại của ứng dụng blogsite
mà ta vừa thêm vào. Ta thực hiện việc này bằng cách thêm nó vào phần INSTALLED_APPS
trong settings.py
.
Điều hướng đến folder nơi settings.py
của bạn.
- cd ~/my_blog_app/blog/blog
Từ đây, hãy mở file settings.py
của bạn, chẳng hạn với nano.
- nano settings.py
Khi file được mở, hãy thêm ứng dụng blogsite
của bạn vào phần INSTALLED_APPS
của file , như được chỉ ra bên dưới.
# Application definition INSTALLED_APPS = [ 'blogsite', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
Với ứng dụng blogsite
được thêm vào, bạn có thể lưu và thoát file .
Đến đây, ta đã sẵn sàng để áp dụng những thay đổi này.
Bước 4 - Thực hiện di chuyển
Với các mô hình Post
và Comment
của ta được thêm vào, bước tiếp theo là áp dụng những thay đổi này để giản đồ database MySQL
của ta nhận ra chúng và tạo các bảng cần thiết.
Đầu tiên, ta phải đóng gói các thay đổi mô hình của bạn thành các file di chuyển riêng lẻ bằng cách sử dụng lệnh makemigrations
. Các file này tương tự như file commits
trong hệ thống kiểm soát version như Git.
Bây giờ, nếu bạn chuyển đến ~/my_blog_app/blog/blogsite/migrations
và chạy ls
, bạn sẽ nhận thấy rằng chỉ có một file __init__.py
. Điều này sẽ thay đổi khi ta thêm các di chuyển.
Thay đổi folder blog bằng cd
, như sau:
- cd ~/my_blog_app/blog
Sau đó chạy makemigrations
lệnh trên manage.py
.
- python manage.py makemigrations
Sau đó, bạn sẽ nhận được kết quả sau trong cửa sổ terminal của bạn :
OutputMigrations for 'blogsite': blogsite/migrations/0001_initial.py - Create model Post - Create model Comment
Lưu ý , khi ta chuyển đến /~/my_blog_app/blog/blogsite/migrations
và nó chỉ có file __init__.py
? Nếu bây giờ ta cd
trở lại folder đó, ta sẽ nhận thấy rằng hai mục đã được thêm vào: __pycache__
và 0001_initial.py
. Tệp 0001_initial.py
được tạo tự động khi bạn chạy makemigrations
. Một file tương tự sẽ được tạo mỗi khi bạn chạy makemigrations
.
Chạy less 0001_initial.py
từ folder chứa nó nếu bạn muốn đọc qua những gì file chứa.
Bây giờ chuyển đến ~/my_blog_app/blog
:
- cd ~/my_blog_app/blog
Vì ta đã tạo một file di chuyển, ta phải áp dụng các thay đổi mà các file này mô tả cho database bằng cách sử dụng lệnh migrate
. Nhưng trước tiên, hãy kiểm tra di chuyển nào hiện đang tồn tại, sử dụng lệnh 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
Bạn sẽ nhận thấy rằng tất cả các di chuyển đều được kiểm tra ngoại trừ di chuyển cho 0001_initial
mà ta vừa tạo với các mô hình Post
và Comment
.
Bây giờ, hãy kiểm tra SQL
sẽ được thực thi khi ta thực hiện di chuyển, bằng cách sử dụng lệnh sau. Nó lấy trong quá trình di chuyển và tiêu đề của di chuyển làm đối số:
- python manage.py sqlmigrate blogsite 0001_initial
Tiết lộ bên dưới là truy vấn SQL thực tế đang được thực hiện đằng sau mức thấp .
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`);
Bây giờ ta hãy thực hiện di chuyển để chúng được áp dụng cho database MySQL của ta .
- python manage.py migrate
Ta sẽ nhận được kết quả sau:
OutputOperations to perform: Apply all migrations: admin, auth, blogsite, contenttypes, sessions Running migrations: Applying blogsite.0001_initial... OK
Đến đây bạn đã áp dụng thành công việc di chuyển của bạn .
Điều quan trọng cần lưu ý là có 3 lưu ý đối với việc di chuyển Django với MySQL làm chương trình backend của bạn, như đã nêu trong tài liệu Django.
- Thiếu hỗ trợ cho các giao dịch xung quanh các hoạt động thay đổi schemas . Nói cách khác, nếu quá trình di chuyển không áp dụng thành công, bạn sẽ phải bỏ chọn thủ công các thay đổi bạn đã thực hiện để thử một lần di chuyển khác. Không thể khôi phục, về điểm trước đó, trước khi thực hiện bất kỳ thay đổi nào trong quá trình di chuyển không thành công.
- Đối với hầu hết các hoạt động thay đổi schemas , MySQL sẽ viết lại đầy đủ các bảng. Trong trường hợp xấu nhất, độ phức tạp về thời gian sẽ tỷ lệ thuận với số hàng trong bảng để thêm hoặc bớt cột. Theo tài liệu Django, điều này có thể chậm đến một phút trên một triệu hàng.
- Trong MySQL, có những giới hạn nhỏ về độ dài tên cho các cột, bảng và chỉ số. Cũng có một giới hạn về kích thước kết hợp của tất cả các cột và bìa index . Trong khi một số phần mềm backend khác có thể hỗ trợ các giới hạn cao hơn được tạo trong Django, các chỉ số tương tự sẽ không được tạo với phần backend MySQL tại chỗ.
Đối với mỗi database mà bạn xem xét để sử dụng với Django, hãy đảm bảo cân nhắc những ưu và nhược điểm của từng database đó.
Bước 5 - Xác minh schemas database
Khi quá trình di chuyển hoàn tất, ta nên xác minh việc tạo thành công các bảng MySQL mà ta đã tạo thông qua các mô hình Django của ta .
Để thực hiện việc này, hãy chạy lệnh sau trong terminal để đăng nhập vào MySQL. Ta sẽ sử dụng djangouser
mà ta đã tạo trong hướng dẫn trước .
- mysql blog_data -u djangouser
Bây giờ, chọn blog_data
database của ta . Nếu bạn không biết database mình đang sử dụng, bạn có thể hiển thị tất cả các database với SHOW DATABASES;
trong SQL.
- USE blog_data;
Sau đó gõ lệnh sau để xem các bảng.
- SHOW TABLES;
Truy vấn SQL này sẽ tiết lộ những điều sau:
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)
Trong số các bảng có blogsite_comment
và blogsite_post
. Đây là những mô hình mà ta vừa tự làm. Hãy xác thực rằng chúng chứa các trường mà ta đã xác định.
- 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)
Ta đã xác minh các bảng database đã được tạo thành công từ việc di chuyển mô hình Django của ta .
Bạn có thể đóng MySQL bằng CTRL
+ D
và khi đã sẵn sàng rời khỏi môi trường Python của bạn , bạn có thể chạy lệnh deactivate
:
- deactivate
Việc hủy kích hoạt môi trường lập trình của bạn sẽ đưa bạn trở lại dấu nhắc lệnh terminal .
Kết luận
Trong hướng dẫn này, ta đã thêm thành công các mô hình cho chức năng cơ bản trong ứng dụng web blog. Bạn đã học cách viết mã models
, cách migrations
hoạt động và quá trình dịch models
Django sang các bảng database MySQL
thực tế.
Các tin liên quan