Django                
            F () espressioni
        
        
            
    Ricerca…
introduzione
Un'espressione F () è un modo per Django di utilizzare un oggetto Python per fare riferimento al valore del campo del modello o della colonna annotata nel database senza dover inserire il valore nella memoria di Python. Ciò consente agli sviluppatori di evitare determinate condizioni di gara e di filtrare i risultati in base ai valori del campo del modello.
Sintassi
- da django.db.models import F
Evitare le condizioni di gara
Vedi questa domanda Q & A se non sai quali sono le condizioni di gara.
Il seguente codice può essere soggetto a condizioni di gara:
article = Article.objects.get(pk=69)
article.views_count += 1
article.save()
 Se views_count è uguale a 1337 , ciò comporterà una query di questo tipo: 
UPDATE app_article SET views_count = 1338 WHERE id=69
 Se due client accedono contemporaneamente a questo articolo, ciò che potrebbe accadere è che la seconda richiesta HTTP esegua Article.objects.get(pk=69) prima che il primo esegua article.save() . Pertanto, entrambe le richieste avranno views_count = 1337 , incrementarlo e salvare views_count = 1338 nel database, mentre in realtà dovrebbe essere 1339 . 
 Per risolvere questo problema, usa un'espressione F() : 
article = Article.objects.get(pk=69)
article.views_count = F('views_count') + 1
article.save()
Questo, d'altra parte, si tradurrà in tale query:
UPDATE app_article SET views_count = views_count + 1 WHERE id=69
Aggiornamento di queryset in blocco
 Supponiamo di voler rimuovere 2 upvotes da tutti gli articoli dell'autore con id 51 . 
 Farlo solo con Python eseguirà N query ( N è il numero di articoli nel queryset): 
for article in Article.objects.filter(author_id=51):
    article.upvotes -= 2
    article.save()
    # Note that there is a race condition here but this is not the focus
    # of this example.
 Cosa succede se invece di trascinare tutti gli articoli in Python, passandoci sopra, diminuendo gli upvotes e salvando ogni aggiornato nel database, c'era un altro modo? 
 Usando un'espressione F() , puoi farlo in una query: 
Article.objects.filter(author_id=51).update(upvotes=F('upvotes') - 2)
Quale può essere tradotto nella seguente query SQL:
UPDATE app_article SET upvotes = upvotes - 2 WHERE author_id = 51
Perché è meglio?
- Invece di fare il lavoro in Python, passiamo il carico nel database che è messo a punto per fare queste domande.
- Riduce efficacemente il numero di query del database necessarie per ottenere il risultato desiderato.
Esegui operazioni aritmetiche tra i campi
 F() espressioni F() possono essere utilizzate per eseguire operazioni aritmetiche ( + , - , * ecc.) Tra i campi del modello, al fine di definire una ricerca / connessione algebrica tra di esse. 
- Lascia che il modello sia: - class MyModel(models.Model): int_1 = models.IntegerField() int_2 = models.IntegerField()
- Ora lascia supporre che vogliamo recuperare tutti gli oggetti di - MyModeltabella che di- int_1e- int_2campi soddisfano questa equazione:- int_1 + int_2 >= 5. Utilizzando- annotate()e- filter()otteniamo:- result = MyModel.objects.annotate( diff=F(int_1) + F(int_2) ).filter(diff__gte=5)- resultora contiene tutti gli oggetti di cui sopra.
 Sebbene l'esempio utilizzi i campi Integer , questo metodo funzionerà su ogni campo in cui è possibile applicare un'operazione aritmetica.