django-signals vs触发器?

Ale*_*ird 14 sql django triggers django-signals

我读到了django信号(http://docs.djangoproject.com/en/dev/topics/signals/),但据我所知,信号永远不会转换为文字SQL触发器(http://en.wikipedia. org/wiki/Database_trigger).

如果我是正确的,信号和触发器是不同的,那么哪一个更好,以什么方式?什么是最佳做法?

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

这是一个具体的例子,如果你想要一个:

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')
Run Code Online (Sandbox Code Playgroud)

我希望一个人能够加入一个团队,当且仅当该人的位置在该团队的一组位置内时.我不知道如何使用正常的关系约束来做到这一点,所以据我所知,我被迫使用触发器或信号.我的直觉说我应该使用触发器,但我想知道最佳实践.

Dan*_*man 19

都不是.这项工作的最佳工具是模型验证 - 您可以在那里编写自定义验证规则,它将在管理员和您自己的应用程序中实施.

  • +1:这和模型中对“保存”的简单覆盖涵盖了我遇到的所有基础。 (2认同)
  • 我有两个目标:1)让网站做我想做的事(验证)2)当*我*犯错时抓住我。就#1 而言,这个建议是有道理的。就#2 而言,如果我不使用 ModelForm 与数据库交互会怎样?文档说“请注意,当您保存模型时,验证器不会自动运行”。这意味着我现在可能会意外丢失数据完整性,因为我在修改数据库之前没有通过调用 `Person.save()` 来调用验证器。但是有了触发器,就不可能错误地绕过触发器。我的推理有道理吗? (2认同)

Igo*_*kiy 9

Django信号很棒(验证也很棒,但有时你需要在保存之前改变一些东西......).如果你只是通过Django使用数据库,那么将所有逻辑保持在同一个地方真的是个好主意,imho.

这是一个例子,它是如何工作的:

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) 
Run Code Online (Sandbox Code Playgroud)


zar*_*ski 5

触发器相对于信号的主要优点:

  • 独立于应用程序:使迁移到新框架/语言更容易(因为触发器以及在某些情况下存储过程与数据库一起转储)

  • 安全性:根据具体情况,您可以限制某些表的更新权限,但仍然能够运行您的应用程序(想想关键历史记录或事务表,谁知道未来 10 年内可能会发现哪些漏洞)

  • 减少应用程序必须向 DBMS 发送的请求数量(在分布式架构的上下文中特别有用)。

以下是主要优点。主要缺点是您必须处理老式的 SQL 语法。