Học Django | Model và Migration

Bài tập 2.01

Trong bài tập này, bạn sẽ tạo cơ sở dữ liệu sách cho ứng dụng bookr của chúng ta. Chúng ta sẽ sử dụng DB Browser for SQLite (tải về tại địa chỉ https://sqlitebrowser.org)

1. Mở ứng dụng, tạo cơ sở dữ liệu mới bằng cách nhấn vào New Database ở góc trên bên trái của ứng dụng. Tạo cơ sở dữ liệu có tên là bookr.

2. Tiếp theo, tạo bảng mới bằng cách nhấn vào Create Table ở góc trên bên trái và nhập book làm tên của bảng.

3. Tạo trường cho bảng bằng cách nhấn Add field và nhập tên trường là title, và chọn kiểu của trường là TEXT từ thực đơn đổ xuống:

4. Tương tự, thêm hai trường có tên là publisherauthor và chọn TEXT làm kiểu dữ liệu cho cả hai trường này. Sau đó nhấn nút OK:

5. Kết quả cuối cùng là một bảng cơ sở dữ liệu có tên book được tạo ra trong cơ sở dữ liệu bookr trong đó chứa các trường title, publisherauthor.

CRUD (Create-Read-Update-Delete)

Chuyển đến thẻ Execute SQL trong DB Browser. Bạn có thể gõ hoặc sao chép rồi dán mã truy vấn SQL vào cửa sổ SQL 1. Sau đó để thực hiện truy vấn, nhấn vào biểu tượng giống nút Play hoặc bấm phím F5 để chạy lệnh. Kết quả của truy vấn được hiển thị trong cửa sổ ngay bên dưới cửa sổ SQL 1.

Create

Hành động Create (tạo bản ghi) trong ngôn ngữ SQL được thực hiện bằng lệnh insert. Trở lại ví dụ bookr ở trên. Vì chúng ta đã thực sự tạo cơ sở dữ liệu và bảng book, chúng ta sẵn sàng để chèn một bản ghi vào cơ sở dữ liệu bằng lệnh sau:

insert into book values ( 'The Sparrow Warrior', 'Super Hero Publications', 'Patric Javagal' );
Code language: SQL (Structured Query Language) (sql)

Nó chèn một bản ghi vào bảng book với titleThe Sparrow Warrior, publisherSuper Hero PublicationsauthorPatric Javagal.

Tương tự, thêm hai bản ghi nữa:

insert into book values ( 'Ninja Warrior', 'East Hill Publications', 'Edward Smith' ); insert into book values ( 'The European History', 'Northside Publications', 'Eric Robbins' );
Code language: SQL (Structured Query Language) (sql)

Read

Bạn có thể đọc dữ liệu từ cơ sở dữ liệu qua SQL. Ví dụ, lệnh select sau đây lấy ra các bản ghi đã tạo trong bảng book:

select title, publisher, author from book;
Code language: SQL (Structured Query Language) (sql)

Ở đây lệnh select đọc dữ liệu từ cơ sở dữ liệu, và các trường title, publisherauthor là các cột mà ta muốn lấy dữ liệu từ bàng book. Vì chúng là tất cả các cột trong bảng cơ sở dữ liệu, lệnh này trả về tất cả dữ liệu hiện có trong bảng. Một cách viết ngắn gọn hơn (và tốt hơn) để chọn tất cả các cột là sử dụng ký tự đại diện *:

select * from book;
Code language: SQL (Structured Query Language) (sql)

Giả sử bạn muốn lấy tên tác giả của cuốn sách có tiêu đề là The Sparrow Warrior; trong trường hợp này lệnh SQL sẽ trông như sau:

select author from book where title="The Sparrow Warrior";
Code language: SQL (Structured Query Language) (sql)

Update

Trong SQL, cách để cập nhật một bản ghi trong bảng là sử dụng update:

update book set publisher='Northside Publications' where title='The Sparrow Warrior';
Code language: SQL (Structured Query Language) (sql)

Ở đây, chúng ta cài đặt giá trị trường publisher thành Northside Publications nếu giá trị trường titleThe Sparrow Warrior. Chúng ta sau đó có thể sử dụng lệnh select để nhìn kết quả sau khi cập nhật:

Delete

Đây là một ví dụ về cách để xóa một bản ghi từ cơ sở dữ liệu bằng lệnh delete:

delete from book where title='The Sparrow Warrior';
Code language: SQL (Structured Query Language) (sql)

Kết quả sau khi xóa bản ghi này:

Cấu hình cơ sở dữ liệu và tạo các ứng dụng Django

Khi chúng ta tạo một dự án Django và chạy Django Server, cơ sở dữ liệu mặc định được sử dụng là SQLite3 và được khai báo trong mục DATABASES trong tệp settings.py:

DATABASES = { 'default': { 'ENGINE': django.db.backends.sqlite3, 'NAME': BASE_DIR / 'db.sqlite3', } }
Code language: Python (python)

Biến DATABASES được gán cho một từ điển chứa thông tin chi tiết về các cơ sở dữ liệu được sử dụng trong dự án. Bên trong từ điển này, có một từ điển con với khóa là default. Nó giữ cấu hình của cơ sở dữ liệu mặc định được sử dụng trong dự án Django. Một dự án Django có thể tương tác với nhiều cơ sở dữ liệu cùng lúc và khi bạn không chỉ rõ cơ sở dữ liệu nào được sử dụng, Django sử dụng cơ sở dữ liệu mặc định này.

Khóa ENGINE biểu diễn kiểu hệ quản trị cơ sở dữ liệu được dùng; trong trường hợp trên là sqlite3.

Khóa NAME định nghĩa tên của cơ sở dữ liệu, có thể là tên bất kỳ. Đối với SQLite3, vì cơ sở dữ liệu là một tệp trên hệ thống, NAME sẽ là đường dẫn tuyệt đối tới tệp này.

Nếu bạn sử dụng các hệ quản trị cơ sở dữ liệu khác như PostgreSQL, MySQL, … ta cần các khai báo các khóa như sau:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'bookr', 'USER': <username>, 'PASSWORD': <password>, 'HOST': <host-IP-address>, 'PORT': '5432', } }
Code language: Python (python)

Ứng dụng trong Django

Một dự án có thể có nhiều ứng dụng. Mặc định Django có sẵn một số ứng dụng được bật sẵn. Chúng được khai báo trong mục INSTALLED_APPS trong tệp settings.py:

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
Code language: Python (python)

Migration

Django ORM giúp các thao tác đối với cơ sở dữ liệu đơn giản hơn. Nhiệm vụ chính của nó là chuyển đổi mã Python thành các cấu trúc cơ sở dữ liệu như các trường, bảng và dữ liệu. Sự chuyển đổi mã Python thành các cấu trúc cơ sở dữ liệu được gọi là migration. Thay vì tạo hàng tá bảng cơ sở dữ liệu bằng mã SQL, bạn sẽ viết các model cho chúng thông qua Python. Những model này sẽ có các thuộc tính, tương ứng với các trường trong bảng cơ sở dữ liệu.

Mặc dù ta chưa tạo ra model nào cho dự án, các dự án có sẵn của Django đã có sẵn nhiều model và migration. Chúng ta có thể thực hiện hành động migrate để áp dụng các migration của các model của các ứng dụng này thông qua lệnh sau đây:

python manage.py migrate
Code language: Bash (bash)

Sau khi thực hiện việc này, các bảng cơ sở dữ liệu của các model của các ứng dụng có sẵn được tạo ra.

Mở DB Browser for SQLite để duyệt dữ liệu (chú ý là duyệt đến tệp db.sqlite3), chúng ta sẽ thấy được các bảng cơ sở dữ liệu đã tạo:

Duyệt tiếp tới từng bảng, chúng ta sẽ thấy được các trường:

Tạo model và migration

Một model trong Django là một lớp Python định nghĩa một bảng cơ sở dữ liệu. Tệp models.py có thể chứa nhiều model, và mỗi model được chuyển đổi thành một bảng cơ sở dữ liệu.

Với ứng dụng reviews, chúng ta cần tạo các model tương ứng với các bảng dữ liệu sau:

  • Book: lưu thông tin về các cuốn sách.
  • Contributor: lưu thông tin về những người đóng góp để viết nên một cuốn sách, như tác giả, đồng tác giả hoặc người biên tập.
  • Publisher: nhà xuất bản của cuốn sách.
  • Review: lưu các đánh giá về cuốn sách được viết bởi người dùng.

Mỗi cuốn sách có một nhà xuất bản, cùng tạo model đầu tiên là Publisher. Nhập đoạn mã sau trong reviews/models.py:

from django.db import models class Publisher(models.Model): """A company that publishes books.""" name = models.CharField(max_length=50, help_text="The name of Publisher.") website = models.URLField(help_text="The Publisher's website.") email = models.EmailField(help_text="The Publisher's email address.")
Code language: Python (python)

Các kiểu trường

Như ta có thể thấy, các trường trên được định nghĩa với các kiểu sau:

  • CharField: kiểu này được dùng để lưu trữ các chuỗi ngắn. Với các chuỗi dài, chúng ta dùng kiểu TextField.
  • EmailField: nó tương tự như CharField, nhưng yêu cầu chuỗi phải có dạng một địa chỉ email hợp lệ.
  • URLField: nó tương tự như CharField, nhưng yêu cầu chuỗi phải có dạng một địa chỉ URL hợp lệ.

Các tùy chọn trường

Đây là hai tùy chọn mà ta đã sử dụng khi định nghĩa model Publisher ở trên:

  • help_text: là tùy chọn giúp ta thêm các mô tả cho trường được dùng bởi Django Form.
  • max_length: là tùy chọn áp dụng cho kiểu CharField, nó định nghĩa chiều dài cực đại của chuỗi (số ký tự tối đa của chuối).

Việc tiếp theo là tạo ra migration cho model này. Ta sử dụng lệnh makemigrations để tạo các migration cho tất cả các model của ứng dụng reviews thông qua lệnh sau:

python manage.py makemigrations reviews
Code language: Python (python)

Kết quả của lệnh sau trông như sau:

Migrations for 'reviews': reviews/migration/0001_initial.py - Create model Publihser
Code language: Bash (bash)

Lệnh makemigrations <appname> tạo tập lệnh migration cho ứn dụng appname; trong trường hợp này là reviews. Sau lệnh này một tệp mới được tạo trong thư mục migrations:

Đây là tập lệnh migration được tạo ra bởi Django. Khi chúng ta chạy makemigrations mà không chỉ rõ tên ứng dụng, các tập lệnh migration sẽ được tạo ra cho mọi ứng dụng trong dự án. Tiếp theo, cùng liệt kê trạng thái các migration của ứng dụng. Nhớ là trước đó, chúng ta đã áp dụng các migration của các ứng dụng có sẵn của Django và giờ chúng ta đã tạo một ứng dụng mới – ứng dụng reviews. Lệnh sau đây, khi ta chạy, sẽ hiển thị trạng thái của các migration của các model của toàn dự án:

python manage.py showmigrations
Code language: Bash (bash)

Kết quả của lệnh này trông như sau:

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 [X] 0012_alter_user_first_name_max_length contenttypes [X] 0001_initial [X] 0002_remove_content_type_name reviews [ ] 0001_initial sessions [X] 0001_initial
Code language: Bash (bash)

Ký hiệu [x] cho biết migration đã được áp dụng.

Tiếp theo, cùng hiểu về cách Django chuyển đổi một model thành bảng cơ sở dữ liệu.

Mã SQL tương ứng với một migration được hiển thị thông qua lệnh quản lý sqlmigrate:

python manage.py sqlmigrate reviews 0001_initial
Code language: Bash (bash)

Kết quả của câu lệnh này trông như sau:

BEGIN; -- -- Create model Publisher -- CREATE TABLE "reviews_publisher" ( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(50) NOT NULL, "website" varchar(200) NOT NULL, "email" varchar(254) NOT NULL ); COMMIT;
Code language: SQL (Structured Query Language) (sql)

Khi thực hiện migrate migration 0001_initial.py, lệnh SQL sẽ trên sẽ được chạy.

Các khóa chính

Giả sử có một bảng cơ sở dữ liệu gọi là users, lưu thông tin về các người dùng, nó có hơn 1000 bản ghi và có ít nhất 3 người dùng cùng tên là Joe Burns. Làm sao để chúng ta phân biệt những người dùng này trong ứng dụng?

Giải pháp là cần một cách để tạo ra định danh duy nhất cho một bản ghi. Cách thực hiện là tạo ra một trường đặc biệt đóng vai trò là khóa chính (Primary Key) lưu một định danh duy nhất với mỗi bản ghi (dòng) trong bảng cơ sở dữ liệu. Một bảng không thể có hai bản ghi có cùng khóa chính.

Trong Django, khi khóa chính không được khai báo trong model, Django tự động tạo ra trường id (có kiểu số nguyên, tự động tăng khi thêm một bản ghi mới) làm khóa chính.

CREATE TABLE "reviews_publisher" ( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, );
Code language: SQL (Structured Query Language) (sql)

Đến lúc này, ta đã tạo một migration (0001_initial.py), tiếp theo ta áp dụng nó bằng lệnh migrate:

python manage.py migrate reviews
Code language: Bash (bash)

Kết quả:

Operations to perform: Apply all migrations: reviews Running migrations: Applying reviews.0001_initial... OK
Code language: Bash (bash)

Hành động này tạo ra bảng dữ liệu có tên reviews_publisher cho ứng dụng reviews:

Việc cuối cùng là tạo các model còn lại của ứng dụng reviews của chúng ta:

  • Book
  • Publisher (đã tạo)
  • Contributor
  • Reviews

Cùng thêm các model BookContributor vào trong reviews/models.py:

from django.db import models class Publisher(models.Model): """A company that publishes books.""" name = models.CharField(max_length=50, help_text="The name of the Publisher.") website = models.URLField(help_text="The Publisher's website.") email = models.EmailField(help_text="The Publisher's email address.") class Book(models.Model): """A published book.""" title = models.CharField(max_length=70, help_text="The title of the book.") publication_date = models.DateField(verbose_name="Date the book was published.") isbn = models.CharField(max_length=20, verbose_name="ISBN number of the book.") class Contributor(models.Model): """ A contributor to a Book, e.g. author, editor, co-author """ first_names = models.CharField(max_length=50, help_text="The contributor's first name or names.") last_names = models.CharField(max_length=50, help_text="The contributor's last name or names.") email = models.EmailField(help_text="The contact email for the contributor.")
Code language: Python (python)

Ở trên xuất hiện một tùy chọn mới là verbose_name, cung cấp tên có tính mô tả hơn cho trường.

Mối quan hệ giữa các model

many-to-one

Trong quan hệ này, nhiều bản ghi (dòng) trong một bảng có thể tham chiếu tới cùng một bản ghi trong một bảng khác. Ví dụ, có thể có nhiều cuốn sách được xuất bản bởi một nhà xuất bản. Để thiết lập mối quan hệ này, chúng ta cần sử dụng các khóa ngoại (Foreign Key). Một khóa ngoại là một trường trong một bảng tham chiếu tới tới khóa chính ở một bảng khác.

Trong ứng dụng bookr của chúng ta, model Book có thêm có một khóa ngoại tham chiếu tới khóa chính của bảng Publisher:

class Boook(models.Model): """A published book.""' title = models.CharField(max_length=70, help_text="The title of the book.") publication_date = models.DateField(verbose_name="Date the book was published.") isbn = models.CharField(max_length=20, verbose_name="ISBN number of the book.") publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
Code language: Python (python)

Giờ ta đã thêm trường publisher để thực hiện mối quan hệ many-to-one giữa PublisherBook sử dụng khóa ngoại:

  • models.ForeignKey: đây là kiểu trường cần dùng để tạo một khóa ngoại.
  • Publisher: tên model mà khóa ngoại tham chiếu đến khóa chính của nó.
  • on_delete: tùy chọn này xác định hành động xảy ra khi xóa một bản ghi của Publisher. Khi được đặt là models.CASCADE thì khi xóa bản ghi của Publisher, tất cả các bản ghi tham chiếu tới nó trong Book cũng bị xóa. Ngoài ra còn có:
    • PROTECT: không cho xóa bản ghi của Publisher trử khi tất cả các bản ghi tham chiếu tới nó trong Book đã bị xóa trước đó.
    • SET_NULL: đặt giá trị null cho bản ghi đã bị xóa.
    • SET_DEFAULT: đặt giá trị mặc định cho bản ghi bị xóa.

many-to-many

Trong quan hệ này, nhiều bản ghi trong một bảng có thể tham chiếu tới nhiều bản ghi trong bảng khác. Ví dụ một cuốn sách có thể có nhiều đồng tác giả và mỗi tác giả có thể viết nhiều cuốn sách. Nó hình thành mối quan hệ many-to-many giữa BookContributor:

Trong models.py thêm dòng cuối sau vào model Book:

class Book(models.Model): """A published book.""" title = models.CharField(max_length=70, help_text="The title of the book.") publication_date = models.DateField(verbose_name="Date the book was published.") isbn = models.CharField(max_length=20, verbose_name="ISBN the number of the book.") publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) contributors = models.ManyToManyField('Contributor', through='BookContributor')
Code language: Python (python)

Trường contributors vừa thêm thiết lập mối quan hệ many-to-many giữa BookContributor sử dụng kiểu ManyToManyField:

  • models.ManyToManyField: kiểu trường này dùng để thiết lập mối quan hệ many-to-many.
  • through: là tùy chọn dùng với quan hệ many-to-many. Khi chúng ta có quan hệ many-to-many trên hai bảng, nếu ta muốn lưu thêm thông tin mở rộng về mối quan hệ này, chúng ta có thể thiết lập mối quan hệ này qua một bảng trung gian.

Ví dụ, chúng ta có hai bảng là BookContributor, và chúng ta cần lưu thêm thông tin về kiểu của một contributor của cuốn sách, như Author (tác giả), Co-author (đồng tác giả) hoặc Editor (người biên tập). Kiểu của contributor được lưu trong một bảng trung gian có tên BookContributor. Thêm model mới BookContributor vào trong reviews/models.py:

class BookContributor(models.Model): class ContributionRole(models.TextChoices): AUTHOR = "AUTHOR", "Author" CO_AUTHOR = "CO_AUTHOR", "Co-author" EDITOR = "EDITOR", "Editor" book = models.ForeignKey(Book, on_delete=models.CASCADE) contributor = models.ForeignKey(Contributor, on_delete=models.CASCADE) role = models.CharField( verbose_name="The role this contributor had in the book.", choices=ContributionRole.choices, max_length=20 )
Code language: Python (python)

Model trung gian BookContributor thiết lập các mối quan hệ bằng cách sử dụng các khóa ngoại tới cả model BookContributor, nó có những trường sau đây:

  • book: đây là khóa ngoại trỏ tới model Book.
  • contributor: đây là khóa ngoại trỏ tới Contributor.
  • role: lưu thông tin mở rộng về mối quan hệ giữa BookContributor.
  • class ContributionRole(models.TextChoices): dùng để định nghĩa các lựa chọn cho trường role bằng cách tạo một lớp nội thừa kế từ models.TextChoices.
  • choices: tham chiếu tới các lựa chọn được tạo từ models.TextChoices.

one-to-one

Trong mối quan hệ này, một bản ghi trong bảng tham chiếu tới chỉ một bản ghi trong bảng khác. Ví dụ, một người chỉ có một bằng lái xe, quan hệ giữa một người và số bằng lái của họ là quan hệ one-to-one.

Trường OneToOneField có thể dùng để thiết lập mối quan hệ one-to-one, như sau:

class DriverLicence(models.Model): person = models.OneToOneField(Person, on_delete=models.CASCADE) licence_number = models.CharField(max_length=50)
Code language: Python (python)

Thêm model reviews

Chúng ta đã thêm các model BookPublisher tới reviews/models.py. Model cuối cùng chúng ta sẽ thêm là review, nội dung của nó như sau:

from django.contrib import auth from django.utils import timezone class Review(models.Model): content = models.TextField(help_text="The Review text.") rating = models.IntegerField(help_text="The rating the reviewer has given.") date_created = models.DateTimeField(default=timezone.now, help_text="The date and time the review was created.") date_edited = models.DateTimeField(null=True, help_text="The date and time the review was last edited.") creator = models.ForeignKey(auth.get_user_model(), on_delete=models.CASCADE) book = models.ForeignKey(Book, on_delete=models.CASCADE, help_text="The Book that this review is for.")
Code language: Python (python)

Một điểm cần chú ý là chúng ta tham chiếu đến model User có sẵn từ ứng dụng mặc định django.contrib.auth thông qua việc gọi phương thức .auth.get_user_model().

Các phương thức của model

Trong Django, chúng ta có thể viết các phương thức bên trong một lớp, chúng được gọi là phương thức của model và có thể là phương thức tùy chỉnh hoặc phương thức đặc biệt. Một trong những phương thức đặc biệt là __str___() trả về chuỗi biểu diễn một model, đặc biệt hữu ích khi sử dụng Django Shell. Trong ví dụ sau, phương thức __str___() được thêm vào model Publisher, trả về chuỗi biểu diễn của một đối tượng Publisher là tên của nhà xuất bản:

class Publisher(models.Model): """A company that publishes books.""" name = models.CharField(max_length=50, help_text="The name of the Publisher.") website = models.URLField(help_text="The Publisher's website.") email = models.EmailField(help_text="The Publisher's email address.") def __str__(self): return self.name
Code language: Python (python)

Tương tự cho model ContributorBook:

class Book(models.Model): """A published book.""" title = models.CharField(max_length=70, help_text="The title of the book.") publication_date = models.DateField(verbose_name="Date the book was published.") isbn = models.CharField(max_length=20, verbose_name="ISBN number of the book.") publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) contributors = models.ManyToManyField('Contributor', through="BookContributor") def __str__(self): return self.title class Contributor(models.Model): """ A contributor to a Book, e.g. author, editor, co-author """ first_names = models.CharField(max_length=50, help_text="The contributor's first name or names.") last_names = models.CharField(max_length=50, help_text="The contributor's last name or names.") email = models.EmailField(help_text="The contact email for the contributor.") def __str__(self): return self.first_names
Code language: Python (python)

Migrate ứng dụng reviews

Chạy lệnh sau để tạo các migration:

python manage.py makemigrations reviews
Code language: Bash (bash)

Kết quả như sau:

reviews/migrations/0002_auto_20191007_0112.py - Create model Book - Create model Contributor - Create model Review - Create model BookContributor - Add field contributors to book - Add field publisher to book
Code language: Bash (bash)

Tiếp theo migrate tất cả các migrations đã tạo ở trên:

python manage.py migrate reviews
Code language: Bash (bash)

Bạn sẽ thấy kết quả như sau:

Operations to perform: Apply all migrations: reviews Running migrations: Applying reviews.0002_auto_20191007_0112... OK
Code language: Bash (bash)

Sau khi chạy lệnh này, chúng ta đã tạo thành công các bảng được định nghĩa trong ứng dụng reviews. Bạn có thể sử dụng DB Browser for SQLite để khám phá những bảng này.

CRUD thông qua Django ORM

Để minh họa các ví dụ, chúng ta sử dụng Django Shell. Mở Django Shell bằng lệnh:

python manage.py shell
Code language: Bash (bash)

Bài tập 2.02: Tạo một bản ghi trong cơ sở dữ liệu bookr

Trong bài tập này, bạn sẽ tạo một bản ghi mới trong cơ sở dữ liệu bằng cách tạo ra một đối tượng của model. Nói cách khác, bạn sẽ tạo một bản ghi trong cơ sở dữ liệu mà không cần sử dụng SQL:

1. Trước tiên, nạp lớp/model Publisher từ reviews.models:

>>> from reviews.models import Publisher
Code language: Python (python)

2. Tạo một đối tượng của Publisher bằng cách truyền vào tất cả các giá trị của tất cả các trường bắt buộc (name, website, email) của model:

>>> publisher = Publisher(name='Packt Publishing', website='https://www.packtpub.com', email='info@packtpub.com')
Code language: Python (python)

3. Tiếp theo, ghi đối tượng đó vào cơ sở dữ liệu bằng cách gọi phương thức .save() của nó:

>>> publisher.save()
Code language: Python (python)

Giờ bạn có thể thấy bản ghi vừa tạo trong cơ sở dữ liệu thông qua DB Browser:

4. Sử dụng các thuộc tính của đối tượng để thay đổi đối tượng và lưu lại sự thay đổi đó tới cơ sở dữ liệu:

>>> publisher.email 'info@packtpub.com' >>> publisher.email = 'customersupport@packtpub.com' >>> publisher.save()
Code language: Python (python)

Bài tập 2.03: Sử dụng phương thức create() để tạo một bản ghi

Ở đây, chúng ta sẽ tạo một bản ghi trong bảng Contributor sử dụng phương thức .create():

1. Trước tiên, nạp model Contributor như trước đây:

>>> from reviews.models import Contributor
Code language: Python (python)

2. Gọi phương thức .create() của Contributor để tạo một đối tượng và lưu nó vào cơ sở dữ liệu (chỉ cần một bước). Đảm bảo rằng bạn đã truyền vào toàn bộ các trường yêu cầu (first_name, last_name, và email):

>>> contributor = Contributor.objects.create(first_names="Rowel", last_names="Atienza", email="RowelAtienza@example.com")
Code language: Python (python)

Bài tập 2.04: Tạo bản ghi cho quan hệ many-to-one

Trong bài tập này, bạn sẽ tạo một bản ghi trong bảng Book chứa một khóa ngoại tới bảng Publisher. Như bạn đã biết, mối quan hệ giữa BookPublisher là many-to-one, nên bạn phải lấy đối tượng Publisher và sử dụng nó để tạo bản ghi trong Book:

1. Trước tiên, nạp lớp PublisherBook:

>>> from reviews.models import Book, Publisher
Code language: Python (python)

2. Lấy đối tượng publisher từ cơ sở dữ liệu bằng cách dùng lệnh sau. Phương thức .get() dùng để lấy một đối tượng (bản ghi) từ cơ sở dữ liệu:

>>> publisher = Publisher.objects.get(name='Packt Publishing')
Code language: Python (python)

3. Khi tạo một cuốn sách, chúng ta cần cung cấp đối tượng date làm publication_date như được định nghĩa trong model Book. Cho nên, ta cần nạp date từ datetime như sau:

>>> from datetime import date
Code language: Python (python)

4. Sử dụng phương thức .create() để tạo một bản ghi trong bảng Book. Đảm bảo rằng bạn đã truyền tất cả các trường cần thiết là title, publication_date, isbnpublisher:

>>> book = Book.objects.create(title="Advanced Deep Learning with Keras", publication_date=date(2018, 10, 31), isbn='9781788629416', publisher=publisher)
Code language: JavaScript (javascript)

Chú ý rằng vì publisher là khóa ngoại và không thể null (không thể chứa giá trị null) nên bắt buộc phải truyền đối tượng publisher nếu không sẽ gây lỗi.

Khóa ngoại publisher chuyển thành trường publisher_id trong bảng reviews_book và trỏ tới khóa chính (trường id) của bảng reviews_publisher.

Bài tập 2.05: Tạo bản ghi cho quan hệ many-to-many

Trong bài tập này, bạn sẽ tạo mối quan hệ many-to-many giữa BookContributor sử dụng BookContributor:

1. Bạn khởi động lại Django Shell để xóa các đối tượng publisherbook hiện có. Lấy lại chúng từ cơ sở dữ liệu bằng các lệnh sau:

>>> from reviews.models import Book >>> from reviews.models import Contributor >>> contributor = Contributor.objects.get(first_names='Rowel') >>> book = Book.objects.get(title='Advanced Deep Learning with Keras')
Code language: Python (python)

2. Cách thiết lập quan hệ many-to-many là lưu thông tin về quan hệ trong model trung gian hay còn gọi là model quan hệ; trong trường hợp này là BookContributor. Vì chúng ta đã lấy bookcontributor từ cơ sở dữ liệu, sử dụng những đối tượng này khi tạo bản ghi của BookContributor và lưu vào cơ sở dữ liệu. Khi thực hiện, đảm bảo rằng bạn truyền các trường yêu cầu có tên là book, contributorrole:

>>> from reviews.models import BookContributor >>> book_contributor = BookContributor(book=book, contributor=contributor, role='AUTHOR') >>> book_contributor.save()
Code language: Python (python)

Nó thiết lập quan hệ giữa cuốn sách Advanced Deep Lerning with Keras và cộng tác viên Rowel (Rowel là tác giả của cuốn sách này).

Bài tập 2.06: Thiết lập quan hệ many-to-many bằng phương thức add()

Trong bài tâp này, bạn sẽ thiết lập một quan hệ many-to-many sử dụng phương thức .add(). Tiếp tục từ ví dụ trước, cùng thêm một cộng tác viên cho cuốn sách. Lần này, cộng tác viên sẽ là một người biên tập cho cuốn sách:

1. Chạy các lệnh sau để nạp và lấy cuốn sách yêu cầu:

>>> from reviews.models import Book, Contributor >>> book = Book.objects.get(title="Advanced Deep Learning with Keras")
Code language: Python (python)

2. Sử dụng phương thức create() để tạo một cộng tác viên như sau:

>>> contributor = Contributor.objects.create(first_names='Packt', last_names='Example Editor', email='PacktEditor@example.com')
Code language: Python (python)

3. Thêm cộng tác viên mới tạo tới cuốn sách bằng phương thức add() như sau:

>>> book.contributors.add(contributor, through_defaults={'role': 'EDITOR'})
Code language: Python (python)

Tham số through_defaults dùng để cung cấp các tham số bổ sung cho mối quan hệ giữa BookContributor (cụ thể là role) dưới dạng một từ điển.

Sử dụng phương thức create() và set() cho quan hệ many-to-many

Giả sử cuốn sách Advanced Deep Learning with Keras có hai người biên tập. Sử dụng phương thức sau để thêm người biên tập nữa cho cuốn sách. Nếu người biên tập chưa có sẵn trong cơ sở dữ liệu, thì chúng ta có thể sử dụng phương thức create() để đồng thời tạo và thiết lập mối quan hệ với cuốn sách:

>>> book.contributors.create(first_names='Packtp', last_names='Editor Example', email='PacktEditor2@example.com', through_defaults={'role': 'EDITOR'})
Code language: Python (python)

Tương tự, chúng ta cũng có thể sử dụng phương thức set() để thêm một danh sách các công tác viên cho cuốn sách. Cùng tạo một nhà xuất bản, một tập hai cộng tác viên là đồng tác giả, và đối tượng book. Trước tiên, nạp model Publisher nếu nó chưa được nạp với dòng lệnh sau:

>>> from reviews.models import Publisher
Code language: Python (python)

Các câu lệnh sau sẽ giúp ta thực hiện công việc này:

>>> publisher = Publisher.objects.create(name='Pocket Books', website='https://pocketbookssampleurl.com', email='pocketbook@example.com') >>> contributor1 = Contributor.objects.create(first_names='Stephen', last_names='Stephen', email='StephenKing@example.com') >>> contributor2 = Contributor.objects.create(first_names='Peter', last_names='Straub', email='PeterStraub@example.com') >>> book = Book.objects.create(title='The Talisman', publication_date=date(2012, 9, 25), isbn='9781451697216', publisher=publisher)
Code language: Python (python)

Vì đây là quan hệ many-to-many, chúng ta có thể liệt kê các đối tượng chỉ một lần bằng phương thức set(). Chúng ta có thể sử dụng through_defaults để chỉ định vai trò của các cộng tác viên; trong trường hợp này, họ là các đồng tác giả:

>>> book.contributors.set([contributor1, contributor2], through_defaults={'role': 'CO_AUTHOR'})
Code language: Python (python)

Bài tập 2.07: Sử dụng phương thức get() để lấy một bản ghi

Trong bài này, bạn sẽ lấy một bản ghi (được biểu diễn như một đối tượng) từ cơ sở dữ liệu bằng phương thức get():

1. Lấy đối tượng Publisher có trường name mang giá trị Pocket Books:

>>> from reviews.models import Publisher >>> publisher = Publisher.objects.get(name='Pocket Books')
Code language: Python (python)

2. Hiển thị đối tượng publisher ra Shell:

>>> publisher <Publisher: Pocket Books>
Code language: Python (python)

Cái được hiển thị trong shell gọi là biểu diễn chuỗi của đối tượng. Nó là kết quả của phương thức đặc biệt __str__() mà ta đã định nghĩa trong model Publisher.

3. Khi đã lấy đối tượng, bạn truy cập được tới mọi thuộc tính của đối tượng. Vì nó là đối tượng Python, các thuộc tính này được truy cập qua dấu chấm “.” sau đó là tên thuộc tính. Do vậy, bạn có thể truy cập tên của nhà xuất bản với lệnh sau:

>>> publisher.name 'Pocket Books'
Code language: Python (python)

4. Tương tự, lấy địa chỉ website của nhà xuất bản:

>>> publisher.website 'https://pocketbookssampleurl.com'
Code language: Python (python)

Cũng như địa chỉ email của nhà xuất bản:

>>> publisher.email 'pocketbook@example.com'
Code language: Python (python)

Phương thức get() chỉ trả về một đối tượng

Cần chú ý rằng, phương thức get() chỉ có thể lấy và trả về một bản ghi. Nếu có nhiều bản ghi có cùng giá trị trường name, phương thức này trả về lỗi “returned more than one”.

Ta cũng nhận được lỗi “matching query does not exist” khi không có đối tượng nào được tìm thấy. Phương thức get() có thể tìm theo bất cứ trường nào. Trong trường hợp sau, chúng ta sử dụng trường website:

>>> publisher = Publisher.objects.get(website='https://pocketbookssampleurl.com')
Code language: Python (python)

Sau khi lấy được đối tượng, chúng ta vẫn có thể truy cập đầy đủ tới các trường khác, chẳng hạn trường name:

>>> publisher.name 'Pocket Books'
Code language: Python (python)

Một cách khác để lấy một đối tượng bằng cách sử dụng khóa chính – pk, như lệnh dưới đây:

>>> Publisher.objects.get(pk=2) <Publisher: Pocket Books>
Code language: Python (python)

Sử dụng pk cho khóa chính tổng quát hơn sử dụng tên trường cụ thể của khóa chính vì các trường khóa chính có thể có nhiều tên khác nhau. Trong trường hợp model Publisher, vì trường khóa chính có tên id, chúng ta cũng có thể sử dụng id, như sau:

>>> Publisher.objects.get(id=2) <Publisher: Pocket Books>
Code language: Python (python)

Bài tập 2.08: Sử dụng phương thức all() để lấy nhiều bản ghi

Chúng ta có thể sử dụng phương thức all() để lấy nhiều đối tượng (chứa thông tin về các bản ghi). Trong bài tập này, bạn sẽ sử dụng phương thức này để lấy tên của tất cả các cộng tác viên:

1. Thêm đoạn mã sau để lấy tất cả các đối tượng từ model Contributor:

>>> from reviews.models import Contributor >>> Contributor.objects.all() <QuerySet [<Contributor: Rowel>, <Contributor: Packt>, <Contributor: Packtp>, <Contributor: Stephen>, <Contributor: Peter>]>
Code language: Python (python)

Như ta thấy, bạn nhận được một QuerySet chứa tất cả các đối tượng.

2. Ta có thể lưu đối tượng QuerySet vào một biến và truy cập tới từng phần tử thông qua chỉ số của chúng:

>>> contributors = Contributor.objects.all() >>> contributors[0] <Contributor: Rowel>
Code language: Python (python)

Mỗi phần tử của contributors là một đối tượng Contributor mà bạn từ đó có thể truy cập tới các trường:

>>> contributors[0].first_name 'Rowel' >>> contributors[0].last_name 'Atienza'
Code language: Python (python)

Bài tập 2.09: Lọc các bản ghi bằng phương thức filter()

Trong bài tập này, bạn sẽ sử dụng phương thức filter() để lấy ra tập các đối tượng thỏa mãn điều kiện nào đó. Cụ thể, bạn sẽ lấy tên của các cộng tác viên có first_namePeter:

1. Trước tiên, tạo thêm hai công tác viên:

>>> from reviews.models import Contributor >>> Contributor.objects.create(first_names='Peter', last_names='Wharton', email='PeterWharton@example.com') >>> Contributor.objects.create(first_names='Peter', last_names='Tyrrell', email='PeterTyrrell@example.com')
Code language: Python (python)

2. Để lấy những bản ghi này (có first_namePeter) sử dụng dòng lệnh sau:

>>> Contributor.objects.filter(first_name='Peter') <QuerySet [<Contributor: Peter>, <Contributor: Peter>, <Contributor: Peter>]>
Code language: Python (python)

3. Phương thức filter() trả về một QuerySet ngay cả khi chỉ có một đối tượng thỏa mãn:

>>> Contributor.objects.filter(first_name='Rowel') <QuerySet [<Contributor: Rowel>]>
Code language: Python (python)

4. Nếu không có đối tượng nào thỏa mãn, filter() trả về một QuerySet trống:

>>> Contributor.objects.filter(first_name='Nobody') <QuerySet []>
Code language: Python (python)

Sử dụng các toán tử điều kiện với filter()

Django ORM cho phép kết hợp toán tử điều kiện với tên trường để tìm kiếm nâng cao hơn trong filter(). Ở đây ta giới thiệu các toán tử sau:

  • lt: nhỏ hơn
  • lte: nhỏ hơn hoặc bằng
  • gt: lớn hơn
  • gte: lớn hơn hoặc bằng

Nó kết hợp với tên trường qua cú pháp sau: tên_trường__tên_toán_tử ở đó tên trường và tên toán tử ngăn cách nhau bởi hai dấu gạch dưới "__".

Ví dụ sau lọc ra các cuốn sách có ngày xuất bản publication_date sau ngày 01-01-2014:

>>> from reviews.models import Book >>> book = Book.objects.filter(publication_date__gt=date(2014, 1, 1)) <QuerySet [<Book: Advanced Deep Learning with Keras>]> >>> book[0].publication_date datetime.date(2018, 10, 31)
Code language: Python (python)

Sử dụng toán tử contains

Toán tử contains sử dụng khi nội dung một trường có chứa một chuỗi con nào đó:

>>> book = Book.objects.filter(title__contains='Deep Learning')
Code language: Python (python)

Ở đây title__contains tìm các đối tượng có tiêu đề chứa chuỗi con 'Deep learning':

>>> book <QuerySet [<Book: Advanced Deep Learning with Keras>]> >>> book[0].title 'Advanced Deep Learning with Keras'
Code language: Python (python)

Tương tự có những toán tử khác là:

  • icontains: tìm kiếm không phân biệt chữ hoa, chữ thường.
  • startswith: tìm kiếm chuỗi bắt dầu bằng chuỗi con nào đó.

Lấy các bản ghi bằng điều kiện loại trừ

Khi cần lọc các đối tượng thỏa mãn điều kiện nào đó, ta dùng filter(). Ngược lại khi cần lọc các đối tượng không thỏa mãn điều kiện nào đó, ta dùng exclude(). Lệnh sau liệt kê tất cả các cộng tác viên:

>>> Contributor.objects.all() <QuerySet [<Contributor: Rowel>, <Contributor: Packt>, <Contributor: Packtp>, <Contributor: Stephen>, <Contributor: Peter>, <Contributor: Peter>, <Contributor: Peter>]>
Code language: Python (python)

Giờ từ danh sách này, chúng ta muốn loại trừ các cộng tác viên có first_namePeter:

>>> Contributor.objects.exclude(first_name='Peter') <QuerySet [<Contributor: Rowel>, <Contributor: Packt>, <Contributor: Packtp>, <Contributor: Stephen>]>
Code language: Python (python)

Sắp xếp các bản ghi bằng phương thức order_by()

Chúng ta có thể lấy một danh sách các đối tượng được sắp xếp theo một trường nhất định sử dụng phương thức order_by(). Ví dụ, ở đoạn mã sau, chúng ta sắp xếp các cuốn sách theo ngày xuất bản:

>>> books = Book.objects.order_by("publication_date") >>> books <QuerySet [<Book: The Talisman>, <Book: Advanced Deep Learning with Keras>]> >>> books[0].publication_date datetime.date(2012, 9, 25) >>> books[1].publication_date datetime.date(2018, 10, 31)
Code language: Python (python)

Để sắp xếp theo thứ tự ngược lại thêm dấu trừ "-" vào trước tên trường cần sắp xếp:

>>> books = Book.objects.order_by("-publication_date") >>> books <QuerySet [<Book: Advanced Deep Learning with Keras>,<Book: The Talisman>]> >>> books[0].publication_date datetime.date(2018, 10, 31) >>> books[1].publication_date datetime.date(2012, 9, 25)
Code language: Python (python)

Chúng ta cũng có thể sắp xếp trên một trường kiểu chuỗi hoặc kiểu số. Ví dụ lệnh sau sắp xếp theo khóa chính:

>>> books = Book.objects.order_by('id') <QuerySet [<Book: Advanced Deep Learning with Keras>,<Book: The Talisman>]> >>> books[0].id 1 >>> books[1].id 2
Code language: Python (python)

Sắp xếp theo thứ tự ngược lại của khóa chính:

>>> Book.objects.order_by('-id') <QuerySet [<Book: The Talisman>, <Book: Advanced Deep Learning with Keras>]> >>> books[0].id 2 >>> books[1].id 1
Code language: JavaScript (javascript)

Khi sắp xếp trên trường kiểu chuỗi, thứ tự ABC được áp dụng:

>>>Book.objects.order_by('title') <QuerySet [<Book: Advanced Deep Learning with Keras>, <Book: The Talisman>]> >>> books[0] <Book: Advanced Deep Learning with Keras> >>> books[1] <Book: The Talisman>
Code language: Python (python)

Tương tự có thể sắp xếp theo thứ tự ngược lại:

>>> Book.objects.order_by('-title') <QuerySet [<Book: The Talisman>, <Book: Advanced Deep Learning with Keras>]> >>> books[0] <Book: The Talisman> >>> books[1] <Book: Advanced Deep Learning with Keras>
Code language: JavaScript (javascript)

Một phương thức hữu ích khác là values(). Nó trả về một tập các từ điển thay vì đối tượng:

>>> publishers = Publisher.objects.all().values() >>> publishers <QuerySet [{'id': 1, 'name': 'Packt Publishing', 'website': 'https://www.packtpub.com', 'email': 'customersupport@packtpub.com'}, {'id': 2, 'name': 'Pocket Books', 'website': 'https://pocketbookssampleurl.com', 'email': 'pocketbook@example.com'}]> >>> publishers[0] {'id': 1, 'name': 'Packt Publishing', 'website': 'https://www.packtpub.com', 'email': 'customersupport@packtpub.com'} >>> publishers[1] {'id': 1, 'name': 'Packt Publishing', 'website': 'https://www.packtpub.com', 'email': 'customersupport@packtpub.com'}
Code language: JavaScript (javascript)

Truy vấn qua các quan hệ

Truy vấn sử dụng khóa ngoại

Khi chúng ta có các quan hệ giữa hai model/bảng, Django cung cấp cách để thực hiện truy vấn sử dụng mối quan hệ này. Lệnh sau lấy tất cả cuốn sách được xuất bản bởi Packt Publishing:

>>> Book.objects.filter(publisher__name='Packt Publishing') <QuerySet [<Book: Advanced Deep Learning with Keras>]>
Code language: Python (python)

Ta sử dụng cú pháp hai dấu gạch dưới "__" để thực hiện truy vấn qua khóa ngoại theo cú pháp sau:

tên_khóa_ngoại__tên_trường

trong đó tên_khóa_ngoại là tên của trường models.ForeignKey trong model Book, còn tên_trường là tên của một trường trong Publisher.

Truy vấn qua tên model

Giả sử ta muốn truy vấn nhà xuất bản đã xuất bản cuốn sách có tên Advanced Deep Learning with Keras. Để thực hiện chúng ta có thể chạy lệnh sau:

>>> Publisher.objects.get(book__title='Advanced Deep Learning with Keras') <Pulisher: Packt Publishing>
Code language: Python (python)

Ở đây book là tên model Book (viết thường) còn title là một trường của Book.

Truy vấn qua một đối tượng (bản ghi)

Chúng ta cũng có thể truy vấn thông qua thuộc tính khóa ngoại của đối tượng. Giả sử chúng ta muốn truy vấn tên nhà xuất bản cuốn sách The Talisman.

>>> book = Book.objects.get(title='The Talisman') >>> book.publisher <Publisher: Pocket Books>
Code language: Python (python)

Còn đây là cách ta lấy tất cả các cuốn sách được xuất bản bởi Pocket Books:

>>> publisher = Publisher.objects.get(name='Pocket Books') >>> publisher.book_set.all() <QuerySet [<Book: The Talisman>]>
Code language: Python (python)

Ta có thể nối nhiều truy vấn liên tiếp:

>>> Book.objects.filter(publisher__name='Pocket Books').filter(title='The Talisman') <QuerySet [<Book: The Talisman>]>
Code language: Python (python)

Bài tập 2.10: Truy vấn quan hệ many-to-many sử dụng tên model

Chúng ta biết rằng BookContributor có quan hệ many-to-many. Trong bài tập này, không tạo đối tượng, bạn sẽ thực hiện một truy vấn để lấy tất cả các cộng tác viên của cuốn sách The Talisman:

1. Trước tiên, nạp lớp Contributor:

>>> from reviews.models import Contributor
Code language: Python (python)

2. Sử dụng dòng lệnh sau để truy vấn tập các cộng tác viên của cuốn sách The Talisman:

>>> Contributor.objects.filter(book__title='The Talisman') <QuerySet [<Contributor: Stephen>, <Contributor: Peter>]>
Code language: Python (python)

Truy vấn này sử dụng model book (viết thường) và thực hiện tìm kiếm trên trường title của nó, sử dụng cú pháp "__".

Bài tập 2.11: Truy vấn quan hệ many-to-many sử dụng các đối tượng

Trong bài tập này, sử dụng đối tượng Book, ta tìm kiếm tất cả các cộng tác viên của cuốn sách The Talisman. Các bước sau sẽ giúp bạn làm việc này:

1. Nạp model Book:

>>> from reviews.models import Book
Code language: Python (python)

2. Lấy sách The Talisman (dưới dạng đối tượng):

>>> book = Book.objects.get(title='The Talisman')
Code language: Python (python)

3. Sau đó lấy tất cả cộng tác viên của cuốn sách này sử dụng thông qua book:

>>> book.contributors.all() <QuerySet [<Contributor: Stephen>, <Contributor: Peter>]>
Code language: Python (python)

Bài tập 2.12: Truy vấn quan hệ many-to-many bằng set()

Trong bài tập này, chúng ta sẽ sử dụng đối tượng contributor để lấy tất cả cuốn sách viết bởi cộng tác viên có tên Rowel:

1. Nạp model Contributor:

>>> from reviews.models import Contributor
Code language: Python (python)

2. Lấy đối tượng contributorfirst_nameRowel sử dụng phương thức get():

>>> contributor = Contributor.objects.get(first_names='Rowel')
Code language: Python (python)

3. Sử dụng đối tượng contributorbook_set.all() để lấy tất cả sách viết bởi cộng tác viên này:

>>> contributor.book_set.all() <QuerySet [<Book: Advanced Deep Learning with Keras>]>
Code language: CSS (css)

Bài tập 2.13: Sử dụng phương thức update()

Trong bài tập này, bạn sẽ sử dụng phương thức update() để cập nhật bản ghi hiện có:

1. Đổi first_name của cộng tác viên có last_nameTyrrell:

>>> from reviews.models import Contributor >>> contributor.objects.filter(last_names='Tyrrell').update(first_names='Mike')
Code language: Python (python)

Nó trả về giá trị cho biết số lượng bản ghi đã được cập nhật. Trong trường hợp này, chỉ có một bản ghi đã được cập nhật.

2. Lấy cộng tác viên vừa được chỉnh sửa bằng phương thức get() và xác nhận rằng first_name đã bị thay đổi thành Mike:

>>> Contributor.objects.get(last_names='Tyrrell').first_names 'Mike'
Code language: Python (python)

Bài tập 2.14: Sử dụng phương thức delete()

Một bản ghi đã có trong cơ sở dữ liệu có thể bị xóa bằng phương thức delete(). Trong bài này, bạn sẽ xóa bản ghi của bảng Contributorfirst_nameWharton:

Lấy đối tượng bằng phương thức get và sử dụng phương thức delete như sau:

>>> from reviews.models import Contributor >>> Contributor.objects.get(last_name='Wharton').delete() (1, {'reviews.BookContributor': 0, 'reviews.Contributor': 1})
Code language: Python (python)

Tạo các bản ghi mẫu

Mặc dù chúng ta đã biết cách tạo các bản ghi trong cơ sở dữ liệu. Trong các bài tiếp theo, chúng ta sẽ phải tạo rất nhiều bản ghi để làm việc với dự án. Vì lý do này, tôi có sẵn một file .csv chứa sẵn rất nhiều bản ghi. Theo các bước sau để nạp bản ghi này vào cơ sở dữ liệu.

1. Tạo cấu trúc thư mục như sau bên trong thư mục dự án:

bookr/reviews/management/commands/
Code language: Bash (bash)

2. Sao chép loadcsv.pyWebDevWithDjangoData.csv vào thư mục vừa tạo. Tải chúng về ở bên dưới

Khi đặt loadcsv.py trong management/commands nó làm việc như lệnh quản lý dự án tùy chỉnh.

3. Tạo mới lại cơ sở dữ liệu. Xóa tệp cơ sở dữ liệu hiện diện trong thư mục dự án:

rm bookr/db.sqlite3
Code language: Bash (bash)

4. Để tạo mới lại cơ sở dữ liệu, chạy lệnh quản lý migrate:

python manage.py migrate
Code language: Bash (bash)

Giờ bạn sẽ thấy lại file d.sqlite3 được tạo lại trong thư mục dự án bookr.

5. Chạy lệnh quản lý dự án tùy chỉnh loadcsv để nạp các bản ghi vào cơ sở dữ liệu:

python manage.py loadcsv --csv reviews/management/commands/WebDevWithDjangoData.csv
Code language: Bash (bash)

6. Sử dụng DB Browser for SQLite, xác nhận lại rằng tất cả các bảng tạo bởi dự án bookr đã được nạp sẵn các bản ghi.