Domanda

Sto avendo problemi a avvolgermi la testa. In questo momento ho alcuni modelli che sembrano un po 'così:

 def Review(models.Model)
    ...fields...
    overall_score = models.FloatField(blank=True)

def Score(models.Model)
    review = models.ForeignKey(Review)
    question = models.TextField()
    grade = models.IntegerField()

Una recensione ha diversi "punteggi", il punteggio complessivo è la media dei punteggi. Quando viene salvata una recensione o un punteggio, devo ricalcolare la media complessivo_score. In questo momento sto usando un metodo di salvataggio ignorato. Ci sarebbero dei vantaggi nell'usare il dispatcher di segnali di Django?

È stato utile?

Soluzione

I segnali di salvataggio / eliminazione sono generalmente favorevoli in situazioni in cui è necessario apportare modifiche che non sono completamente specifiche del modello in questione, oppure potrebbero essere applicate a modelli che hanno qualcosa in comune o potrebbero essere configurati per l'uso tra i modelli .

Un'attività comune nei metodi save ignorati è la generazione automatizzata di lumache da alcuni campi di testo in un modello. Questo è un esempio di qualcosa che, se fosse necessario implementarlo per un numero di modelli, trarrebbe beneficio dall'uso di un segnale pre_save , in cui il gestore del segnale potrebbe prendere il nome del campo slug e il nome di il campo da cui generare la lumaca. Una volta che hai installato qualcosa del genere, tutte le funzionalità avanzate che metterai in atto si applicheranno anche a tutti i modelli, ad es. guardando la lumaca che stai per aggiungere per il tipo di modello in questione, per garantire l'unicità.

Le applicazioni riutilizzabili spesso traggono vantaggio dall'uso dei segnali: se la funzionalità che forniscono può essere applicata a qualsiasi modello, generalmente (a meno che non sia inevitabile) non vorranno che gli utenti debbano modificare direttamente i loro modelli per trarne vantaggio .

Con django-mptt , ad esempio, ho usato pre_save per gestire un insieme di campi che descrivono una struttura ad albero per il modello che sta per essere creato o aggiornato e il segnale pre_delete per rimuovere i dettagli della struttura ad albero per l'oggetto da eliminare e il relativo l'intero sottoalbero di oggetti prima di esso e vengono eliminati. A causa dell'uso dei segnali, gli utenti non devono aggiungere o modificare i metodi save o delete sui propri modelli per fare eseguire questa gestione per loro, devono solo lasciare django-mptt sa quali modelli vogliono che gestiscano.

Altri suggerimenti

Hai chiesto:

Ci sarebbero dei vantaggi nell'usare il dispatcher di segnali di Django?

L'ho trovato nei documenti di django:

  

I metodi del modello sovrascritti non vengono chiamati per operazioni in blocco

     

Nota che il metodo delete () per un oggetto non è necessariamente chiamato   quando si eliminano oggetti in blocco utilizzando un QuerySet o come risultato di a   eliminazione a cascata. Per garantire l'esecuzione della logica di eliminazione personalizzata, l'utente   può usare i segnali pre_eliminazione e / o post_eliminazione.

     

Sfortunatamente, non esiste una soluzione alternativa durante la creazione o l'aggiornamento   oggetti in blocco, poiché nessuno di save (), pre_save e post_save lo sono   chiamato.

Da: Sostituzione dei metodi del modello predefinito

Se utilizzerai i segnali, sarai in grado di aggiornare il punteggio della recensione ogni volta che viene salvato il modello di punteggio correlato. Ma se non ho bisogno di tale funzionalità non vedo alcun motivo per metterlo in evidenza, è roba piuttosto legata al modello.

È una specie di denormalizzazione. Guarda questa bella soluzione . Definizione del campo di composizione sul posto.

Piccola aggiunta dai documenti Django sull'eliminazione in blocco (metodo .delete () su oggetti QuerySet ):

  

Tieni presente che, quando possibile, questo sarà eseguito esclusivamente in   SQL, e così saranno i metodi delete () delle singole istanze di oggetti   non necessariamente essere chiamato durante il processo. Se hai fornito a   metodo delete () personalizzato su una classe di modello e si desidera assicurarsi che lo sia   chiamato, dovrai & # 8220; manualmente & # 8221; elimina le istanze di quel modello   (ad es. iterando su un QuerySet e chiamando delete () su ciascuno   oggetto singolarmente) anziché utilizzare il metodo bulk (() di a   QuerySet.

https://docs.djangoproject.com/ it / 1.11 / temi / db / query / # Eliminazione di oggetti-

E aggiornamento collettivo (metodo .update () su oggetti QuerySet ):

  

Infine, renditi conto che update () fa un aggiornamento a livello SQL e,   quindi, non chiama alcun metodo save () sui tuoi modelli, né lo fa   emette i segnali pre_save o post_save (che sono una conseguenza di   chiamando Model.save ()). Se si desidera aggiornare un gruppo di record per a   modello che ha un metodo save () personalizzato, passaci sopra e chiama save ()

https://docs.djangoproject.com/en/ 2.1 / ref / modelli / querysets / # update

I segnali sono utili quando è necessario eseguire un processo a lungo termine e non si desidera bloccare l'utente in attesa del completamento del salvataggio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top