2010-08-21 40 views
10

He leído sobre las señales de django (http://docs.djangoproject.com/en/dev/topics/signals/), pero por lo que yo entiendo, las señales nunca se convierten en activadores de SQL literales (http://en.wikipedia.org/wiki/Database_trigger).django-signals vs triggers?

Si tengo la certeza de que las señales y los factores desencadenantes son diferentes, ¿cuál es mejor y de qué manera? ¿Cuál es la mejor práctica?

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

Aquí está un ejemplo concreto si quieres uno:

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') 

quiero que una persona sea capaz de unirse a un equipo si y solo si la ubicación de esa persona está dentro del conjunto de ubicaciones de ese equipo. No sé cómo hacer eso con las restricciones relacionales normales, por lo que sé que estoy obligado a usar disparadores o señales. Mi instinto me dice que debería usar disparadores, pero quiero conocer las mejores prácticas.

Respuesta

14

Ninguno. La mejor herramienta para este trabajo es model validation - puede escribir su regla de validación personalizada allí y se aplicará en el administrador y sus propias aplicaciones.

+0

+1: Eso y un simple anulación de 'save' en el modelo cubre todas las bases que me he encontrado. –

+0

+1. Las señales generalmente reducen la velocidad de tus pruebas si estás cargando dispositivos que disparan señales. Es difícil trabajar desconectando antes las pruebas y luego conectando. –

+1

Tengo dos objetivos: 1) hacer que el sitio haga lo que quiero (validar) 2) atraparme cuando * I * cometer un error. En términos del n. ° 1, esta sugerencia tiene sentido. En términos del n. ° 2, ¿qué ocurre si no utilizo un ModelForm para interactuar con el DB? la documentación dice "Tenga en cuenta que los validadores no se ejecutarán automáticamente cuando guarde un modelo". Eso significa que ahora puedo perder accidentalmente la integridad de los datos ya que no invoqué un validador al llamar 'Person.save()' antes de modificar el DB. Pero con desencadenadores, es imposible eludir erróneamente el desencadenador. ¿Tiene sentido mi razonamiento? –

1

Puede utilizar desencadenadores para aplicar este tipo de restricciones, pero no confiaría en eso. Esto solo se puede hacer como una aplicación secundaria, mientras que el principal es la validación del modelo, tal como Daniel ya dijo.

cuanto a DB desencadena vs Django señales que son más diferente la común. Lo único común que comparten es que ambos se invocan al cambiar la entidad. Pero las entidades difieren mucho.

Disparadores supervisa los cambios en la fila de la base de datos, por lo tanto operan en datos tabulares sin formato. El código de activación lo ejecuta DBMS.

En contraste con los factores desencadenantes señales supervise los cambios del objeto de dominio. En un caso genérico, el modelo de Django consiste en datos de varias filas de tablas (considere la herencia del modelo y los subconjuntos de objetos relacionados). El código de señal lo ejecuta Django.

6

Las señales de Django son increíbles (la validación también es impresionante, pero a veces se necesita para cambiar algo antes de guardar ...). Si está trabajando con la base de datos SOLAMENTE a través de Django, es una buena idea mantener toda la lógica en el mismo lugar, en mi humilde opinión.

Aquí es un ejemplo, cómo funciona:

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) 
Cuestiones relacionadas