2010-08-21 30 views
10

Tôi đọc về tín hiệu django (http://docs.djangoproject.com/en/dev/topics/signals/), nhưng theo như tôi hiểu, các tín hiệu không bao giờ được chuyển đổi thành các kích hoạt SQL theo nghĩa đen (http://en.wikipedia.org/wiki/Database_trigger).django-signal vs triggers?

Nếu tôi đúng là các tín hiệu và trình kích hoạt khác nhau, thì cái nào tốt hơn và theo cách nào? Thực hành tốt nhất là gì?

....................

Dưới đây là một ví dụ cụ thể nếu bạn muốn một:

class Location(models.Model): 
    name = models.CharField(max_length=30) 

class Person(models.Model): 
    location = models.ForeignKey('Location') 

class Team(models.Model): 
    locations = models.ManyToManyField('Location') 

Tôi muốn có một người để được có thể tham gia một nhóm nếu và chỉ khi vị trí của người đó nằm trong bộ địa điểm của nhóm đó. Tôi không biết làm thế nào để làm điều đó với những ràng buộc quan hệ bình thường, cho đến chừng nào tôi biết mình bị buộc phải sử dụng các trigger hay tín hiệu. Ruột của tôi nói rằng tôi nên sử dụng gây nên nhưng tôi muốn biết thực hành tốt nhất.

Trả lời

14

Không. Công cụ tốt nhất cho công việc này là model validation - bạn có thể viết quy tắc xác thực tùy chỉnh ở đó và quy tắc này sẽ được thực thi trong quản trị viên và ứng dụng của riêng bạn.

+0

+1: Đó và ghi đè đơn giản cho 'save' trong mô hình bao gồm tất cả các căn cứ mà tôi từng gặp. –

+0

+1. Tín hiệu thường làm chậm quá trình kiểm tra của bạn nếu bạn đang tải đồ đạc kích hoạt tín hiệu. Đó là một nỗi đau để làm việc xung quanh bằng cách 'ngắt kết nối 'trước khi kiểm tra và' kết nối' ing sau đó. –

+1

Tôi có hai mục tiêu: 1) làm cho trang web thực hiện những gì tôi muốn (xác thực) 2) bắt tôi khi * Tôi * phạm sai lầm. Về mặt số 1, đề xuất này có ý nghĩa. Về mặt số 2, nếu tôi không sử dụng ModelForm để tương tác với DB thì sao? tài liệu nói "Lưu ý rằng trình xác thực sẽ không được chạy tự động khi bạn lưu mô hình". Điều đó có nghĩa là bây giờ tôi có thể vô tình mất toàn vẹn dữ liệu vì tôi đã không gọi trình xác nhận hợp lệ bằng cách gọi 'Person.save()' trước khi sửa đổi DB. Nhưng với trình kích hoạt, không thể kích hoạt nhầm lẫn được. Lý do của tôi có hợp lý không? –

1

Bạn có thể sử dụng trình kích hoạt để thực thi loại ràng buộc này, nhưng tôi sẽ không dựa vào điều đó. Điều này chỉ có thể được thực hiện như là một thực thi thứ cấp, trong khi chính là để được xác nhận mô hình, giống như Daniel đã nói.

Đối với DB trình kích hoạt và Django tín hiệu chúng khác nhau phổ biến hơn. Điều chung duy nhất mà họ chia sẻ là cả hai được gọi khi thay đổi thực thể. Nhưng các thực thể khác nhau rất nhiều.

Trình kích hoạt cơ sở dữ liệu giám sát thay đổi hàng, do đó chúng hoạt động trên dữ liệu bảng thô. Mã kích hoạt được chạy bởi DBMS.

Ngược lại với các kích hoạt tín hiệu theo dõi thay đổi đối tượng tên miền. Trong một trường hợp chung của Django mô hình bao gồm dữ liệu từ một số hàng bảng (xem xét kế thừa mô hình và các tập con đối tượng liên quan). Mã tín hiệu được điều hành bởi Django.

6

Tín hiệu Django thật tuyệt vời (quá trình xác thực cũng tuyệt vời, nhưng đôi khi bạn cần để thay đổi điều gì đó trước khi lưu…). Nếu bạn đang làm việc với cơ sở dữ liệu CHỈ thông qua Django, nó thực sự là ý tưởng tốt để giữ cho tất cả logic ở cùng một nơi, imho.

Dưới đây là một ví dụ, làm thế nào nó hoạt động:

class Example(models.Model): 
    ''' Example of Model (I hate foo-bars!) ''' 
    age = models.IntegerField() 
    can_buy_beer = models.BooleanField(default=False) 


def set_can_buy_beer(sender, instance, **kwargs): 
    ''' Trigger body ''' 
    if instance.age >= 21: 
     instance.can_buy_beer = True 
    else: 
     instance.can_buy_beer = False 

# ↓ Magic — now, field Example.can_buy_beer will be autocalculated on each save! 
pre_save.connect(set_can_buy_beer, sender=Example) 
Các vấn đề liên quan