Đây là kho lưu trữ hướng dẫn mà bạn có thể sử dụng để định cấu hình và chạy các Trình kích hoạt Postgres khác nhau bên trong ứng dụng Django bằng cách sử dụng django-pgtrigger
Hướng dẫn này là một phần của bài nói chuyện do Wes Kendall đưa ra tại Buổi gặp mặt SF Django vào ngày 23 tháng 7 năm 2020
nội dung
Hướng dẫn giả sử bạn đã cài đặt Docker trên máy tính của mình
Chạy lệnh sau để thiết lập toàn bộ dự án
git clone //github.com/wesleykendall/django-pgtrigger-tutorial.git && \ cd django-pgtrigger-tutorial && \ docker-compose build
Đợi vài giây để quá trình xây dựng bắt đầu và sau đó chạy phần này để hoàn tất thiết lập
docker-compose run --rm app python manage.py migrate
Các mô hình và trình kích hoạt liên quan trong hướng dẫn này đều nằm trong hướng dẫn/mô hình. py trong repo Github chính. Các mô hình có một số trình kích hoạt được xác định, nhiều trình kích hoạt trong số đó chúng ta sẽ thực hiện trong hướng dẫn này
Mặc dù không bắt buộc nhưng sẽ rất hữu ích nếu bạn có hiểu biết cơ bản về class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 5 trước khi xem qua phần hướng dẫn này. Kiểm tra các tài liệu ở đây
Lưu ý Mọi ví dụ trong hướng dẫn sử dụng class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 6 đều có thể được bạn thực thi cục bộ, giả sử rằng bạn đã làm theo hướng dẫn thiết lập ở trên
Bảo vệ xóa mô hình
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 7 là một định nghĩa kích hoạt đưa ra một ngoại lệ, tôi. e. “bảo vệ” một hoạt động khỏi xảy ra. Trình kích hoạt có thể được định cấu hình cho bất kỳ điều kiện và sự kiện nào cần được bảo vệ
Ví dụ: mô hình class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 8 đăng ký trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 7 để bảo vệ chống xóa
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ]
Chạy mã này cục bộ với mã sau đây để cố xóa mô hình. Nó sẽ thất bại lớn
________số 8
Lỗi sẽ trông giống như
Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute return self.cursor.execute(sql, params) psycopg2.errors.RaiseException: pgtrigger: Cannot delete rows from tutorial_cannotdelete table CONTEXT: PL/pgSQL function pgtrigger_protect_c1608bb7cb9f8647() line 5 at RAISE
Thay vì cố gắng bảo vệ việc xóa mô hình trong lớp ứng dụng, một phương pháp có thể dễ dàng bị phá vỡ hoặc bỏ qua, trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 7 có thể bảo vệ đáng tin cậy trước các hoạt động mà bạn không muốn xảy ra
Các mô hình chỉ nối thêm
Trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 7 hữu ích cho nhiều thứ hơn là chỉ bảo vệ việc xóa. Tùy thuộc vào sự kết hợp của các hoạt động và điều kiện, người ta có thể thể hiện nhiều loại bảo vệ trên các mô hình và trường
Ví dụ: trình kích hoạt này tạo mô hình “chỉ nối thêm”
docker-compose run --rm app python manage.py migrate 2
Chạy mã này cho thấy cách chúng ta có thể tạo mô hình nhưng không cập nhật hoặc xóa nó (i. e. một mô hình "chỉ nối thêm")
docker-compose run --rm app python manage.py migrate 3
Vì chúng tôi đang bắt lỗi trong ví dụ này, bạn sẽ thấy đầu ra giống như thế này
docker-compose run --rm app python manage.py migrate 4
Các trường chỉ đọc
Trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 7 hoạt động ở cấp độ bảng, vì vậy người ta có thể tự hỏi liệu nó có thể được sử dụng để bảo vệ các hoạt động ở cấp độ cột hay không. Đây là nơi các điều kiện phát huy tác dụng
Điều kiện trên trình kích hoạt cấp hàng là mệnh đề docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 3 có thể hoạt động trên các hàng docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 4 và docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 5 là một phần của hoạt động cơ sở dữ liệu đang diễn ra. Mặc dù class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 5 cho phép một người viết SQL thô cho các điều kiện, các đối tượng docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 7 và docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 8 cho phép bạn xây dựng các mệnh đề trên các hàng docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 4 và docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 5 tương tự như cách hoạt động của các đối tượng Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute return self.cursor.execute(sql, params) psycopg2.errors.RaiseException: pgtrigger: Cannot delete rows from tutorial_cannotdelete table CONTEXT: PL/pgSQL function pgtrigger_protect_c1608bb7cb9f8647() line 5 at RAISE 1 và Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute return self.cursor.execute(sql, params) psycopg2.errors.RaiseException: pgtrigger: Cannot delete rows from tutorial_cannotdelete table CONTEXT: PL/pgSQL function pgtrigger_protect_c1608bb7cb9f8647() line 5 at RAISE 2 của Django
Trong ví dụ này, chúng tôi đã đặt trường “created_at” ở chế độ chỉ đọc bằng cách chỉ bảo vệ các bản cập nhật khi trường này thay đổi
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 6
Chạy mã này cho thấy cách chúng tôi không được phép cập nhật trường “created_at” sau khi mô hình được tạo
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 7
Vì chúng tôi đang bắt lỗi trong ví dụ này, bạn sẽ thấy đầu ra giống như thế này
Lỗi được đưa ra từ đoạn mã trên vì chúng tôi đã định cấu hình trình kích hoạt bảo vệ này để chỉ kích hoạt bất cứ khi nào Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute return self.cursor.execute(sql, params) psycopg2.errors.RaiseException: pgtrigger: Cannot delete rows from tutorial_cannotdelete table CONTEXT: PL/pgSQL function pgtrigger_protect_c1608bb7cb9f8647() line 5 at RAISE 3 của hàng docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 4 (_______95) khác với (Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute return self.cursor.execute(sql, params) psycopg2.errors.RaiseException: pgtrigger: Cannot delete rows from tutorial_cannotdelete table CONTEXT: PL/pgSQL function pgtrigger_protect_c1608bb7cb9f8647() line 5 at RAISE 6) Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute return self.cursor.execute(sql, params) psycopg2.errors.RaiseException: pgtrigger: Cannot delete rows from tutorial_cannotdelete table CONTEXT: PL/pgSQL function pgtrigger_protect_c1608bb7cb9f8647() line 5 at RAISE 3 trong hàng docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 5 của bản cập nhật. Khi điều kiện này không xảy ra, trình kích hoạt bảo vệ không kích hoạt và chúng tôi được phép tiếp tục thao tác
Lưu ý Nếu bạn muốn tạo nhiều trường chỉ đọc, hãy mở rộng điều kiện của bạn để hỗ trợ trường đó. Ví dụ: điều kiện này sẽ làm cho cả hai trường chỉ đọc là Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute return self.cursor.execute(sql, params) psycopg2.errors.RaiseException: pgtrigger: Cannot delete rows from tutorial_cannotdelete table CONTEXT: PL/pgSQL function pgtrigger_protect_c1608bb7cb9f8647() line 5 at RAISE 3 và docker-compose run --rm app python manage.py migrate 20
docker-compose run --rm app python manage.py migrate 0
Mô hình xóa mềm
Một mô hình bị xóa “mềm” bất cứ khi nào một trường được cập nhật để cho biết rằng đối tượng đã bị xóa. Ví dụ: thông thường, người ta sẽ đặt cờ docker-compose run --rm app python manage.py migrate 21 thành docker-compose run --rm app python manage.py migrate 22 để cho biết mô hình bị xóa mà không thực sự xóa mô hình đó khỏi cơ sở dữ liệu
Trình kích hoạt, cụ thể là trình kích hoạt docker-compose run --rm app python manage.py migrate 23 chạy trước một thao tác, có thể tự động bỏ qua thao tác đang được thực thi và áp dụng một thao tác khác. Trình kích hoạt docker-compose run --rm app python manage.py migrate 24 hoạt động theo cách này, thiết lập một trường trên một mô hình và lưu nó bất cứ khi nào việc xóa xảy ra trên mô hình
Đây là một ví dụ về cách định cấu hình trình kích hoạt docker-compose run --rm app python manage.py migrate 24 trên một mô hình
docker-compose run --rm app python manage.py migrate 1
Chạy mã này cho thấy cách chúng ta có thể xóa mô hình bằng lệnh gọi Django ORM tiêu chuẩn mà không thực sự bị xóa
docker-compose run --rm app python manage.py migrate 2
Sau đây sẽ in
Như đã đề cập trong các nhận xét của ví dụ, Django vẫn hoạt động theo cách tương tự, nhưng cơ sở dữ liệu đặt cờ docker-compose run --rm app python manage.py migrate 21 thành docker-compose run --rm app python manage.py migrate 22 dưới mui xe
Điều quan trọng cần lưu ý là Django vẫn sẽ cố gắng xếp tầng các mô hình xóa tham chiếu các mô hình đã xóa mềm. Người ta cũng có tùy chọn để làm cho các mô hình này có thể xóa mềm và người ta cũng có thể xóa hoàn toàn những mô hình này bằng docker-compose run --rm app python manage.py migrate 28 hoặc bỏ qua việc xóa hoàn toàn bằng docker-compose run --rm app python manage.py migrate 29 trong định nghĩa khóa ngoại của chúng. Tùy thuộc vào kỹ sư để quyết định cách xóa mô hình xếp tầng sẽ xảy ra trên các mô hình xóa mềm trong ứng dụng của họ
Phiên bản một mô hình
Ví dụ xóa mềm trước đó cho thấy một ví dụ về trình kích hoạt docker-compose run --rm app python manage.py migrate 23, đây là trình kích hoạt sửa đổi các hàng trước khi thao tác dự định diễn ra. Chúng ta sẽ sử dụng lớp cơ sở docker-compose run --rm app python manage.py migrate 31 ở đây để viết trình kích hoạt sẽ tăng trường số nguyên trước khi áp dụng bản cập nhật
Trong ví dụ này, chúng ta sẽ viết một số SQL thô sẽ được nhúng trực tiếp vào hàm kích hoạt kích hoạt. Khi viết SQL thô cho lớp docker-compose run --rm app python manage.py migrate 31, người ta chỉ cần viết SQL thực thi bên trong hàm kích hoạt và không cần gì khác
Dưới đây là một ví dụ về mô hình có trường “phiên bản” được cập nhật bất cứ khi nào mô hình được cập nhật. Chúng tôi cũng đảm bảo rằng trường này là trường chỉ đọc để không ai cố cập nhật phiên bản của mô hình
docker-compose run --rm app python manage.py migrate 3
Với mô hình đã được phiên bản của chúng tôi, đoạn mã sau cho biết cách trường phiên bản được cập nhật tự động
docker-compose run --rm app python manage.py migrate 4
Ví dụ trên sẽ xuất ra điều này
docker-compose run --rm app python manage.py migrate 5
Lưu ý Trong trình kích hoạt ví dụ của chúng tôi, chúng tôi đang tăng hàng docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 5 và trả lại. Không cần thực hiện bất kỳ thao tác cơ sở dữ liệu nào. Postgres sẽ lấy hàng docker-compose run --rm app python manage.py shell_plus --quiet-load -c " # This object cannot be deleted cannot_delete = CannotDelete.objects.create() cannot_delete.delete() "; 5 đã sửa đổi này và sử dụng nó khi thực hiện thao tác docker-compose run --rm app python manage.py migrate 35 cuối cùng
Lưu ý Giá trị trả về của trình kích hoạt docker-compose run --rm app python manage.py migrate 36 là rất quan trọng vì nó cho Postgres biết hàng nào sẽ được sử dụng trong thao tác cơ sở dữ liệu. Nếu docker-compose run --rm app python manage.py migrate 37 được trả về, Postgres sẽ chặn thao tác được thực hiện. Đây là cách hoạt động của docker-compose run --rm app python manage.py migrate 24
Tạo giao diện “chính thức”
Bạn đã bao giờ muốn buộc các kỹ sư sử dụng chính xác một giao diện để thực hiện một thao tác cơ sở dữ liệu cụ thể chưa?
Trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 7 được sử dụng kết hợp với trình quản lý/trang trí ngữ cảnh docker-compose run --rm app python manage.py migrate 42 có thể được sử dụng để thực hiện điều này
Ví dụ: hãy tưởng tượng chúng tôi có một mô hình docker-compose run --rm app python manage.py migrate 43 và chúng tôi muốn đảm bảo rằng giao diện docker-compose run --rm app python manage.py migrate 44 là phương pháp duy nhất có thể được sử dụng để tạo mô hình ví dụ của chúng tôi
docker-compose run --rm app python manage.py migrate 6
Hãy thử tạo mô hình này bằng phương pháp docker-compose run --rm app python manage.py migrate 45 tiêu chuẩn. Nó sẽ dẫn đến lỗi, nhưng chúng ta có thể tạo đối tượng bằng giao diện docker-compose run --rm app python manage.py migrate 44 chính thức của mình
docker-compose run --rm app python manage.py migrate 7
Bạn sẽ thấy kết quả tương tự như sau (ID của đối tượng có thể khác trên máy tính của bạn)
docker-compose run --rm app python manage.py migrate 8
Trong ví dụ này, chúng tôi đã sử dụng docker-compose run --rm app python manage.py migrate 42 để tự động bỏ qua trình kích hoạt bảo vệ chèn của chúng tôi. docker-compose run --rm app python manage.py migrate 42 sẽ bỏ qua việc thực thi trình kích hoạt đó cho một luồng thực thi duy nhất, do đó cho phép chúng tôi xác định giao diện “chính thức” cho hoạt động được bảo vệ
Lưu ý Ví dụ này có nghĩa là quản trị viên Django và bất kỳ công cụ nào gọi mặc định là docker-compose run --rm app python manage.py migrate 49 sẽ không hoạt động. Mặc dù đây có thể là hành vi mong muốn, hãy nhớ rằng trình kích hoạt bảo vệ sẽ bảo vệ hoạt động từ mọi nơi (trừ khi nó bị bỏ qua một cách cụ thể)
Hạn chế các trường chuyển đổi
Thông thường, trường trạng thái trên mô hình có các trạng thái cụ thể và chuyển tiếp giữa các trạng thái đó. Trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 60 cho phép một người đảm bảo chuyển tiếp hợp lệ (i. e. thực thi một máy trạng thái hữu hạn) của một trường
Hãy xem xét mô hình sau có các chuyển đổi trạng thái có thể xảy ra sau đây
- “chưa công bố” thành “đã công bố”
- “chưa xuất bản” thành “không hoạt động”
- “đã xuất bản” thành “không hoạt động”
Chúng tôi có thể liệt kê tất cả các chuyển đổi hợp lệ này trong trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 60 như vậy và nó sẽ đưa ra một ngoại lệ bất cứ khi nào có chuyển đổi không hợp lệ
docker-compose run --rm app python manage.py migrate 9
Đoạn mã sau cho biết cách chúng tôi có thể thực hiện các chuyển đổi hợp lệ và cách chuyển đổi không hợp lệ sẽ dẫn đến lỗi như thế nào
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 0
Bạn sẽ thấy đầu ra sau
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 1
Lưu ý Tất cả các trình kích hoạt trong class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 5 có thể áp dụng các điều kiện cho chúng. Ví dụ: chúng tôi cũng có thể xác định trình kích hoạt class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 60 chỉ thực thi chuyển đổi trong các điều kiện nhất định
Theo dõi lịch sử mô hình và thay đổi
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 5 có thể được sử dụng để chụp nhanh tất cả các thay đổi mô hình, chụp nhanh các thay đổi bất cứ khi nào một điều kiện cụ thể xảy ra và thậm chí đính kèm ngữ cảnh từ ứng dụng của bạn (e. g. người dùng được xác thực) đến sự kiện được kích hoạt
Theo dõi và kiểm tra lịch sử là một vấn đề sẽ khác đối với nhu cầu của mọi tổ chức. Do phạm vi của vấn đề này, chúng tôi đã tạo toàn bộ thư viện theo dõi lịch sử có tên là django-pghistory nhằm giải quyết các nhu cầu chung để thực hiện theo dõi lịch sử. Nó được triển khai bằng cách sử dụng class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 5 và chúng tôi đưa ra một ví dụ về nó ở đây
Ví dụ sau định cấu hình một mô hình để các thay đổi sau được theo dõi
- Tất cả các thay đổi mô hình. Bất cứ khi nào xảy ra thao tác chèn hoặc cập nhật, một sự kiện “snapshot” sẽ được tạo để chụp nhanh mọi trường của mô hình theo mặc định. Đây là một cách cơ bản về cách người ta có thể theo dõi tất cả lịch sử cho một mô hình
- Sáng tạo mô hình. Khi mô hình được tạo, một sự kiện "tạo" đặc biệt sẽ được kích hoạt để chụp nhanh các trường của mô hình tại thời điểm tạo
- Khi một trường khớp với một điều kiện. Chúng tôi kích hoạt sự kiện “low_int” bất cứ khi nào “int_field” dưới 0 cho bất kỳ bản cập nhật mô hình nào
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 2
Trình kích hoạt ảnh chụp nhanh từ class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 66 sẽ tạo các bảng sự kiện chứa tất cả các sự kiện. Chạy mã này để tạo sự kiện và truy cập chúng. Chúng tôi cũng sẽ đính kèm một số ngữ cảnh cho các sự kiện
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 3
Bạn sẽ thấy kết quả trông như thế này
class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 4
Trong phần "ảnh chụp nhanh" của đầu ra, chúng tôi đã hiển thị tất cả ảnh chụp nhanh của mình theo thứ tự. Hai ảnh chụp nhanh cuối cùng có ngữ cảnh được liên kết với chúng mà chúng tôi đã đính kèm bằng cách sử dụng class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 67
Phần “khác biệt” cho thấy cách sử dụng class CannotDelete(models.Model): """This model cannot be deleted. The ``pgtrigger.Protect`` trigger protects the deletion operation from happening """ class Meta: triggers = [ pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete) ] 68 để tổng hợp các sự kiện cho mô hình đích và hiển thị các sự kiện khác nhau. Những khác biệt này hiển thị "trước" và "sau" của các trường đã được thay đổi trong các sự kiện đã lọc
Hai bản in cuối cùng hiển thị số lượng sự kiện cụ thể mà chúng tôi đã định cấu hình để theo dõi
Ví dụ này chỉ chạm vào bề mặt của những gì được cung cấp bởi django-pghistory. Hãy nhớ đọc tài liệu để tìm hiểu thêm về cách định cấu hình cho trường hợp sử dụng của bạn