2010-08-21 17 views
10

Ho letto dei segnali di django (http://docs.djangoproject.com/en/dev/topics/signals/), ma per quanto ho capito, i segnali non vengono mai convertiti in trigger SQL letterali (http://en.wikipedia.org/wiki/Database_trigger).segnali django e trigger?

Se sono corretto che segnali e trigger siano diversi, quale è il migliore e in che modo? Qual è la migliore pratica?

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

Ecco un esempio concreto se volete 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') 

voglio una persona di essere in grado di unirsi a una squadra se e solo se la posizione di quella persona rientra nella serie di posizioni di quella squadra. Non so come farlo con i normali vincoli relazionali, quindi per quanto ne so sono costretto a usare trigger o segnali. Il mio istinto dice che dovrei usare i grilletti, ma voglio conoscere le migliori pratiche.

risposta

14

Nessuno dei due. Lo strumento migliore per questo lavoro è model validation - puoi scrivere qui la tua regola di convalida personalizzata e verrà applicata nell'amministratore e nelle tue app.

+0

+1: Che e una semplice sostituzione a 'save' nel modello copre tutte le basi che abbia mai incontrato. –

+0

+1. I segnali di solito rallentano i test se si caricano proiettori che attivano i segnali. È un problema aggirare il fatto di "disconnettere" prima dei test e "connettersi" in seguito. –

+1

Ho due obiettivi: 1) fare in modo che il sito faccia quello che voglio (convalidare) 2) prendermi quando * I * commettere un errore. In termini di # 1, questo suggerimento ha senso. In termini di # 2, cosa succede se non utilizzo un ModelForm per interagire con il DB? la documentazione dice "Nota che i validatori non verranno eseguiti automaticamente quando salvi un modello". Ciò significa che ora posso perdere accidentalmente l'integrità dei dati poiché non ho richiamato un validatore chiamando 'Person.save()' prima di modificare il DB. Ma con i trigger, è impossibile che il trigger venga erroneamente aggirato. Il mio ragionamento ha senso? –

1

È possibile utilizzare i trigger per applicare questo tipo di vincoli, ma non ci farei affidamento. Questo può essere fatto solo come applicazione secondaria, mentre quello primario deve essere la validazione del modello, proprio come Daniel ha già detto.

Per quanto riguarda DB innesca vs Django segnali sono più diversi del comune. L'unica cosa comune che condividono è che entrambi sono invocati al cambio di entità. Ma le entità differiscono molto.

Trigger monitora le modifiche alle righe del database, quindi operano su dati tabulari non elaborati. Il codice di attivazione è eseguito da DBMS.

Al contrario di trigger segnali modifiche all'oggetto di dominio del monitor. In un caso generico il modello di Django consiste di dati provenienti da diverse righe di tabella (considerare l'ereditarietà del modello e i relativi sottoinsiemi di oggetti). Il codice del segnale è gestito da Django.

6

I segnali di Django sono fantastici (anche la validazione è straordinaria, ma a volte è necessario modificare prima di salvare ...). Se lavori con il database SOLO attraverso Django, è davvero una buona idea mantenere tutta la logica nello stesso posto, imho.

Ecco un esempio, come funziona:

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) 
Problemi correlati